diff options
371 files changed, 8071 insertions, 10898 deletions
diff --git a/HOWTO/INSTALL-RASPBERRYPI3.md b/HOWTO/INSTALL-RASPBERRYPI3.md new file mode 100644 index 0000000000..536d095cb4 --- /dev/null +++ b/HOWTO/INSTALL-RASPBERRYPI3.md @@ -0,0 +1,323 @@ +# Cross Compiling Erlang/OTP - Raspberry Pi 3 + + +## Introduction + +This document describes how to build a toolchain and cross compile Erlang/OTP +to Raspberry Pi 3 on macOS High Sierra. It is recommended to consult +[Building and Installing Erlang/OTP](https://github.com/erlang/otp/blob/master/HOWTO/INSTALL.md) and [Cross Compiling Erlang/OTP](https://github.com/erlang/otp/blob/master/HOWTO/INSTALL-CROSS.md) before attempting to follow the instructions in this guide. + +The whole process takes several hours and depending on the package versions different problems may arise that require additional +fixes not described in this document. In other words, it is not fun to build a toolchain. I assume that you have a Mac and would +like to develop Erlang/OTP applications based on the latest OTP release (or master) that not yet released as a binary for +Raspberry Pi 3. + +The first and most time consuming step is building the toolchain from scratch. Once your cross compiler is ready you cross compile +all library dependencies and create the sysroot file system. In the last step you cross compile Erlang/OTP using the new +toolchain and sysroot. + +#### Tested Configuration + +macOS High Sierra 10.13.2<br> +Raspberry Pi Model B Rev 1.2<br> +Crosstools-NG 1.23.0_1 + +> Note: /proc/device/tree/model contains model information of your +> Raspberry Pi. + + +#### Install Crosstool NG + + (1) + + $ brew install crosstool-ng + $ brew install grep --default-names # needed by crosstools-ng scripts + $ brew install md5sha1sum # needed by crosstools-ng populate script + + +#### Create case-sensitive disk images + + (2) + +Create two case-sensitive disk images using Disk Utility: + +`File -> New Image -> Blank Image...` + +Format: `Mac OS Extended (Case-sensitive, Journaled)` + +``` +/Volumes/xtools-build-env 15 GB +/Volumes/xtools 500 MB +``` + +The first image holds all source and object files while building the toolchain. The second image houses the compiled +toolchain. + +## Building the Toolchain + + +#### Configure crosstool-ng + + (4) + + $ ct-ng armv8-rpi3-linux-gnueabihf + $ ct-ng menuconfig + +#### Modify *path* section + +* Local tarballs directory: `/Volumes/xtools-build-env/src` +* Working directory: `/Volumes/xtools-build-env/.build` +* Prefix directory: `/Volumes/xtools/${CT_TARGET}` + +#### Modify *Extracting* section + +* Check option: _Stop after extracting tarballs_. + +> Note: The build shall stop after the tarballs have been extracted to give us time to fix source code problems. + +#### Enable STOP / RESTART + +Edit /Volumes/xtools-build-env/.config + `CT_DEBUG_CT_SAVE_STEPS=y` + +Should the build break at a particular build step, you can fix the problem and continue the build from where it broke. + +Short summary of the most common `ct-ng` commands: + +* Listing all build steps + +``` + $ ct-ng list-steps + + Available build steps, in order: + - companion_tools_for_build + - companion_libs_for_build + - binutils_for_build + - companion_tools_for_host + - companion_libs_for_host + - binutils_for_host + - cc_core_pass_1 + - kernel_headers + - libc_start_files + - cc_core_pass_2 + - libc + - cc_for_build + - cc_for_host + - libc_post_cc + - companion_libs_for_target + - binutils_for_target + - debug + - test_suite + - finish +``` + +* Re-run step +``` + $ ct-ng step +``` + +* Restart from step +``` + $ ct-ng step+ +``` + +* Run until step +``` + $ ct-ng +step +``` + +#### Fix file permissions on crosstool-NG.sh + + (5) + + $ chmod 744 /usr/local/Cellar/crosstool-ng/1.23.0_1/lib/crosstool-ng-1.23.0/scripts/crosstool-NG.sh + +#### Run build command + +Build process stops just after the tarballs have been extracted. + + (6) + + $ ct-ng build + + Retrieving needed toolchain components' tarballs + [EXTRA] Retrieving 'make-4.2.1' + [EXTRA] Retrieving 'm4-1.4.18' + [EXTRA] Retrieving 'linux-4.10.8' + [EXTRA] Retrieving 'gmp-6.1.2' + [EXTRA] Retrieving 'mpfr-3.1.5' + [EXTRA] Retrieving 'isl-0.16.1' + [EXTRA] Retrieving 'mpc-1.0.3' + [EXTRA] Retrieving 'expat-2.2.0' + [EXTRA] Retrieving 'ncurses-6.0' + [EXTRA] Retrieving 'libiconv-1.15' + [EXTRA] Retrieving 'gettext-0.19.8.1' + [EXTRA] Retrieving 'binutils-2.28' + [EXTRA] Retrieving 'gcc-6.3.0' + [EXTRA] Retrieving 'glibc-2.25' + [EXTRA] Retrieving 'gdb-7.12.1' + +#### Fix source files + + (7) + +Add macro to /Volumes/xtools-build-env/.build/src/gdb-7.12.1/gdb/doublest.c: +```C +#define min(a,b) \ + ({ typeof (a) _a = (a); \ + typeof (b) _b = (b); \ + _a < _b ? _a : _b; }) +``` + + (8) Update ulimit + + $ ulimit -n 1024 + +#### Modify *extract* section + + (8) + + $ ct-ng menuconfig + + Uncheck option: _Stop after extracting tarballs_ + +#### Re-run build command + +Restarts build process from where it previously stopped. + + (9) + + $ ct-ng build + +#### Fix gettext + +Build will fail at step `companion_tools_for_build` but it can be fixed by running autoreconf: + + (10) + + $ cd .build/src/gettext-0.19.8.1/ + $ ./autoreconf + $ ct-ng companion_tools_for_build+ + +#### Test the toolchain + + (11) + + $ cat > test.c + $ int main() { printf("Hello, world!\n"); return 0; } + $ /Volumes/xtools/arm-unknown-linux-gnueabi-gcc -o test test.c + + (12) OPTIONAL + + “Render the toolchain read-only” from crosstool-NG’s “Paths and misc options” configuration page. + + +## Cross compiling dependencies + + (13) + + $ export PATH=/Volumes/xtools/armv8-rpi3-linux-gnueabihf/bin:$PATH + +#### Cross compiling zlib + + (14) + + $ wget http://zlib.net/zlib-1.2.11.tar.gz + $ tar xf zlib-1.2.11.tar.gz + $ cd zlib-1.2.11 + $ CHOST=armv8-rpi3-linux-gnueabihf ./configure --prefix=/Users/<username>/git/raspberrypi/arm + $ make + $ make install + +#### Cross compiling openssl + + (15) + + $ wget http://openssl.org/source/openssl-1.1.0g.tar.gz + $ tar xf openssl-1.1.0g.tar.gz + $ cd openssl-1.1.0g + $ ./Configure linux-generic32 --prefix=/Users/<username>/git/raspberrypi/arm --openssldir=/Users/<username>/git/raspberrypi/arm/openssl --cross-compile-prefix=armv8-rpi3-linux-gnueabihf + $ make + $ make install + +#### Cross compiling ncurses + + (16) + + $ wget http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.9.tar.gz + + + (17) + +Apply patch: + +```patch +--- a/ncurses/base/MKlib_gen.sh ++++ b/ncurses/base/MKlib_gen.sh +@@ -474,11 +474,22 @@ sed -n -f $ED1 \ + -e 's/gen_$//' \ + -e 's/ / /g' >>$TMP + ++cat >$ED1 <<EOF ++s/ / /g ++s/^ // ++s/ $// ++s/P_NCURSES_BOOL/NCURSES_BOOL/g ++EOF ++ ++# A patch discussed here: ++# https://gcc.gnu.org/ml/gcc-patches/2014-06/msg02185.html ++# introduces spurious #line markers. Work around that by ignoring the system's ++# attempt to define "bool" and using our own symbol here. ++sed -e 's/bool/P_NCURSES_BOOL/g' $TMP > $ED2 ++cat $ED2 >$TMP ++ + $preprocessor $TMP 2>/dev/null \ +-| sed \ +- -e 's/ / /g' \ +- -e 's/^ //' \ +- -e 's/_Bool/NCURSES_BOOL/g' \ ++| sed -f $ED1 \ + | $AWK -f $AW2 \ + | sed -f $ED3 \ + | sed \ +``` + + (18) + + $ ./configure --build=x86_64-apple-darwin17.3.0 --host=armv8-rpi3-linux-gnueabihf --without-ada --without-cxx --without-cxx-binding --without-manpages --without-progs --without-tests --prefix=/usr --libdir=/lib --with-build-cc="gcc -D_GNU_SOURCE" --with-shared + $ make + $ make DESTDIR=/Users/<username>/git/raspberrypi/arm install + + (19) + +Compile ncurses test program: + + $ cd test + $ armv8-rpi3-linux-gnueabihf-gcc -o nctest ncurses.c -I${RPI_SYSROOT}/usr/include -L${RPI_SYSROOT}/lib -lncursesw + + +## Populating sysroot + + (19) + + Edit /Volumes/xtools/armv8-rpi3-linux-gnueabihf/bin/armv8-rpi3-linux-gnueabihf-populate: + + sed="gsed" + + (20) + + $ armv8-rpi3-linux-gnueabihf-populate -s /Users/<username>/git/raspberrypi/arm -d /Users/<username>/git/raspberrypi/sysroot + $ export RPI_SYSROOT=/Users/<username>/git/raspberrypi/sysroot + + +## Cross compiling Erlang/OTP + + (21) + + $ LC_CTYPE=C && LANG=C && ./otp_build autoconf + $ ./otp_build configure --disable-dynamic-ssl-lib --xcomp-conf=./xcomp/erl-xcomp-armv8-rpi3-linux-gnueabihf.conf + $ ./otp_build boot -a + $ ./otp_build release -a /Users/<username>/git/raspberrypi/erlang + $ tar czf erlang.tgz ./erlang + diff --git a/bootstrap/bin/no_dot_erlang.boot b/bootstrap/bin/no_dot_erlang.boot Binary files differindex 60f70c0f97..127072b3ed 100644 --- a/bootstrap/bin/no_dot_erlang.boot +++ b/bootstrap/bin/no_dot_erlang.boot diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot Binary files differindex 60f70c0f97..127072b3ed 100644 --- a/bootstrap/bin/start.boot +++ b/bootstrap/bin/start.boot diff --git a/bootstrap/bin/start_clean.boot b/bootstrap/bin/start_clean.boot Binary files differindex 60f70c0f97..127072b3ed 100644 --- a/bootstrap/bin/start_clean.boot +++ b/bootstrap/bin/start_clean.boot diff --git a/bootstrap/lib/compiler/ebin/beam_dead.beam b/bootstrap/lib/compiler/ebin/beam_dead.beam Binary files differindex 8934cb5d11..534eb65372 100644 --- a/bootstrap/lib/compiler/ebin/beam_dead.beam +++ b/bootstrap/lib/compiler/ebin/beam_dead.beam diff --git a/bootstrap/lib/compiler/ebin/beam_disasm.beam b/bootstrap/lib/compiler/ebin/beam_disasm.beam Binary files differindex 5e3585ada7..2d9bc49992 100644 --- a/bootstrap/lib/compiler/ebin/beam_disasm.beam +++ b/bootstrap/lib/compiler/ebin/beam_disasm.beam diff --git a/bootstrap/lib/compiler/ebin/beam_jump.beam b/bootstrap/lib/compiler/ebin/beam_jump.beam Binary files differindex e13be6fb24..6af8a015c0 100644 --- a/bootstrap/lib/compiler/ebin/beam_jump.beam +++ b/bootstrap/lib/compiler/ebin/beam_jump.beam diff --git a/bootstrap/lib/compiler/ebin/beam_peep.beam b/bootstrap/lib/compiler/ebin/beam_peep.beam Binary files differindex 1bf1e5a79f..5f33584fe4 100644 --- a/bootstrap/lib/compiler/ebin/beam_peep.beam +++ b/bootstrap/lib/compiler/ebin/beam_peep.beam diff --git a/bootstrap/lib/compiler/ebin/beam_trim.beam b/bootstrap/lib/compiler/ebin/beam_trim.beam Binary files differindex 75fcff822e..32cc6efe88 100644 --- a/bootstrap/lib/compiler/ebin/beam_trim.beam +++ b/bootstrap/lib/compiler/ebin/beam_trim.beam diff --git a/bootstrap/lib/compiler/ebin/beam_type.beam b/bootstrap/lib/compiler/ebin/beam_type.beam Binary files differindex f21ede5043..266c04acfd 100644 --- a/bootstrap/lib/compiler/ebin/beam_type.beam +++ b/bootstrap/lib/compiler/ebin/beam_type.beam diff --git a/bootstrap/lib/compiler/ebin/beam_utils.beam b/bootstrap/lib/compiler/ebin/beam_utils.beam Binary files differindex 0eeb313856..5648719621 100644 --- a/bootstrap/lib/compiler/ebin/beam_utils.beam +++ b/bootstrap/lib/compiler/ebin/beam_utils.beam diff --git a/bootstrap/lib/compiler/ebin/beam_validator.beam b/bootstrap/lib/compiler/ebin/beam_validator.beam Binary files differindex db49f6f0fa..2bcec9ca3c 100644 --- a/bootstrap/lib/compiler/ebin/beam_validator.beam +++ b/bootstrap/lib/compiler/ebin/beam_validator.beam diff --git a/bootstrap/lib/compiler/ebin/cerl.beam b/bootstrap/lib/compiler/ebin/cerl.beam Binary files differindex 97e0c72b15..4f8ae7ca43 100644 --- a/bootstrap/lib/compiler/ebin/cerl.beam +++ b/bootstrap/lib/compiler/ebin/cerl.beam diff --git a/bootstrap/lib/compiler/ebin/cerl_inline.beam b/bootstrap/lib/compiler/ebin/cerl_inline.beam Binary files differindex 6b365ce68f..f0d6063f19 100644 --- a/bootstrap/lib/compiler/ebin/cerl_inline.beam +++ b/bootstrap/lib/compiler/ebin/cerl_inline.beam diff --git a/bootstrap/lib/compiler/ebin/compile.beam b/bootstrap/lib/compiler/ebin/compile.beam Binary files differindex 5772dd173b..d1a9058417 100644 --- a/bootstrap/lib/compiler/ebin/compile.beam +++ b/bootstrap/lib/compiler/ebin/compile.beam diff --git a/bootstrap/lib/compiler/ebin/compiler.appup b/bootstrap/lib/compiler/ebin/compiler.appup index a8847fc407..350a3924e7 100644 --- a/bootstrap/lib/compiler/ebin/compiler.appup +++ b/bootstrap/lib/compiler/ebin/compiler.appup @@ -16,7 +16,7 @@ %% limitations under the License. %% %% %CopyrightEnd% -{"7.1.4", +{"7.1.5", [{<<".*">>,[{restart_application, compiler}]}], [{<<".*">>,[{restart_application, compiler}]}] }. diff --git a/bootstrap/lib/compiler/ebin/core_lint.beam b/bootstrap/lib/compiler/ebin/core_lint.beam Binary files differindex e24a473a4c..567e381ee8 100644 --- a/bootstrap/lib/compiler/ebin/core_lint.beam +++ b/bootstrap/lib/compiler/ebin/core_lint.beam diff --git a/bootstrap/lib/compiler/ebin/erl_bifs.beam b/bootstrap/lib/compiler/ebin/erl_bifs.beam Binary files differindex be3dc425f4..37bd743796 100644 --- a/bootstrap/lib/compiler/ebin/erl_bifs.beam +++ b/bootstrap/lib/compiler/ebin/erl_bifs.beam diff --git a/bootstrap/lib/compiler/ebin/rec_env.beam b/bootstrap/lib/compiler/ebin/rec_env.beam Binary files differindex bd0b9c004c..b0ef249e15 100644 --- a/bootstrap/lib/compiler/ebin/rec_env.beam +++ b/bootstrap/lib/compiler/ebin/rec_env.beam diff --git a/bootstrap/lib/compiler/ebin/sys_core_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam Binary files differindex 3b6f6637f0..073bb041d4 100644 --- a/bootstrap/lib/compiler/ebin/sys_core_fold.beam +++ b/bootstrap/lib/compiler/ebin/sys_core_fold.beam diff --git a/bootstrap/lib/compiler/ebin/sys_core_inline.beam b/bootstrap/lib/compiler/ebin/sys_core_inline.beam Binary files differindex b4cdba519a..ebe35883b5 100644 --- a/bootstrap/lib/compiler/ebin/sys_core_inline.beam +++ b/bootstrap/lib/compiler/ebin/sys_core_inline.beam diff --git a/bootstrap/lib/compiler/ebin/v3_codegen.beam b/bootstrap/lib/compiler/ebin/v3_codegen.beam Binary files differindex 5aeca65888..c537f1e550 100644 --- a/bootstrap/lib/compiler/ebin/v3_codegen.beam +++ b/bootstrap/lib/compiler/ebin/v3_codegen.beam diff --git a/bootstrap/lib/kernel/ebin/application_controller.beam b/bootstrap/lib/kernel/ebin/application_controller.beam Binary files differindex e57be279d5..4cc77ec55c 100644 --- a/bootstrap/lib/kernel/ebin/application_controller.beam +++ b/bootstrap/lib/kernel/ebin/application_controller.beam diff --git a/bootstrap/lib/kernel/ebin/disk_log.beam b/bootstrap/lib/kernel/ebin/disk_log.beam Binary files differindex 19880724ba..4f0eae4984 100644 --- a/bootstrap/lib/kernel/ebin/disk_log.beam +++ b/bootstrap/lib/kernel/ebin/disk_log.beam diff --git a/bootstrap/lib/kernel/ebin/dist_util.beam b/bootstrap/lib/kernel/ebin/dist_util.beam Binary files differindex e9f49343ba..3956e595f8 100644 --- a/bootstrap/lib/kernel/ebin/dist_util.beam +++ b/bootstrap/lib/kernel/ebin/dist_util.beam diff --git a/bootstrap/lib/kernel/ebin/erl_ddll.beam b/bootstrap/lib/kernel/ebin/erl_ddll.beam Binary files differindex baec5883a9..de9b1cb638 100644 --- a/bootstrap/lib/kernel/ebin/erl_ddll.beam +++ b/bootstrap/lib/kernel/ebin/erl_ddll.beam diff --git a/bootstrap/lib/kernel/ebin/error_logger.beam b/bootstrap/lib/kernel/ebin/error_logger.beam Binary files differindex bb250d71f3..8dd3c07f71 100644 --- a/bootstrap/lib/kernel/ebin/error_logger.beam +++ b/bootstrap/lib/kernel/ebin/error_logger.beam diff --git a/bootstrap/lib/kernel/ebin/file_io_server.beam b/bootstrap/lib/kernel/ebin/file_io_server.beam Binary files differindex e889d294b8..d9ca62a82b 100644 --- a/bootstrap/lib/kernel/ebin/file_io_server.beam +++ b/bootstrap/lib/kernel/ebin/file_io_server.beam diff --git a/bootstrap/lib/kernel/ebin/inet.beam b/bootstrap/lib/kernel/ebin/inet.beam Binary files differindex fd855be69b..7df45ea492 100644 --- a/bootstrap/lib/kernel/ebin/inet.beam +++ b/bootstrap/lib/kernel/ebin/inet.beam diff --git a/bootstrap/lib/kernel/ebin/inet_db.beam b/bootstrap/lib/kernel/ebin/inet_db.beam Binary files differindex 315d1126aa..513a7dc03d 100644 --- a/bootstrap/lib/kernel/ebin/inet_db.beam +++ b/bootstrap/lib/kernel/ebin/inet_db.beam diff --git a/bootstrap/lib/kernel/ebin/inet_dns.beam b/bootstrap/lib/kernel/ebin/inet_dns.beam Binary files differindex 7b04a63303..f483acd96c 100644 --- a/bootstrap/lib/kernel/ebin/inet_dns.beam +++ b/bootstrap/lib/kernel/ebin/inet_dns.beam diff --git a/bootstrap/lib/kernel/ebin/inet_parse.beam b/bootstrap/lib/kernel/ebin/inet_parse.beam Binary files differindex 561e53dcbd..175649cd81 100644 --- a/bootstrap/lib/kernel/ebin/inet_parse.beam +++ b/bootstrap/lib/kernel/ebin/inet_parse.beam diff --git a/bootstrap/lib/kernel/ebin/kernel.app b/bootstrap/lib/kernel/ebin/kernel.app index 0e1cf7cbb7..340ed8653f 100644 --- a/bootstrap/lib/kernel/ebin/kernel.app +++ b/bootstrap/lib/kernel/ebin/kernel.app @@ -140,9 +140,8 @@ inet_db, pg2]}, {applications, []}, - {env, [{logger_level, info}, - {logger_sasl_compatible, false}, - {logger_progress_reports, stop} + {env, [{logger_level, notice}, + {logger_sasl_compatible, false} ]}, {mod, {kernel, []}}, {runtime_dependencies, ["erts-10.0", "stdlib-3.5", "sasl-3.0"]} diff --git a/bootstrap/lib/kernel/ebin/logger.beam b/bootstrap/lib/kernel/ebin/logger.beam Binary files differindex a2e87793ff..e6d8f5b2c6 100644 --- a/bootstrap/lib/kernel/ebin/logger.beam +++ b/bootstrap/lib/kernel/ebin/logger.beam diff --git a/bootstrap/lib/kernel/ebin/logger_backend.beam b/bootstrap/lib/kernel/ebin/logger_backend.beam Binary files differindex ccc03d104c..be448bd75c 100644 --- a/bootstrap/lib/kernel/ebin/logger_backend.beam +++ b/bootstrap/lib/kernel/ebin/logger_backend.beam diff --git a/bootstrap/lib/kernel/ebin/logger_config.beam b/bootstrap/lib/kernel/ebin/logger_config.beam Binary files differindex 1033fc7c3d..52f7847561 100644 --- a/bootstrap/lib/kernel/ebin/logger_config.beam +++ b/bootstrap/lib/kernel/ebin/logger_config.beam diff --git a/bootstrap/lib/kernel/ebin/logger_disk_log_h.beam b/bootstrap/lib/kernel/ebin/logger_disk_log_h.beam Binary files differindex fc601ddaa6..f7571f180b 100644 --- a/bootstrap/lib/kernel/ebin/logger_disk_log_h.beam +++ b/bootstrap/lib/kernel/ebin/logger_disk_log_h.beam diff --git a/bootstrap/lib/kernel/ebin/logger_formatter.beam b/bootstrap/lib/kernel/ebin/logger_formatter.beam Binary files differindex 6216a8095e..7f7d77ab28 100644 --- a/bootstrap/lib/kernel/ebin/logger_formatter.beam +++ b/bootstrap/lib/kernel/ebin/logger_formatter.beam diff --git a/bootstrap/lib/kernel/ebin/logger_h_common.beam b/bootstrap/lib/kernel/ebin/logger_h_common.beam Binary files differindex b1fb2c1191..61bd03d0e3 100644 --- a/bootstrap/lib/kernel/ebin/logger_h_common.beam +++ b/bootstrap/lib/kernel/ebin/logger_h_common.beam diff --git a/bootstrap/lib/kernel/ebin/logger_server.beam b/bootstrap/lib/kernel/ebin/logger_server.beam Binary files differindex 381c9292b4..72a14acce3 100644 --- a/bootstrap/lib/kernel/ebin/logger_server.beam +++ b/bootstrap/lib/kernel/ebin/logger_server.beam diff --git a/bootstrap/lib/kernel/ebin/logger_simple_h.beam b/bootstrap/lib/kernel/ebin/logger_simple_h.beam Binary files differindex 64db774f26..890de624b9 100644 --- a/bootstrap/lib/kernel/ebin/logger_simple_h.beam +++ b/bootstrap/lib/kernel/ebin/logger_simple_h.beam diff --git a/bootstrap/lib/kernel/ebin/logger_std_h.beam b/bootstrap/lib/kernel/ebin/logger_std_h.beam Binary files differindex e883c81366..2af36d638f 100644 --- a/bootstrap/lib/kernel/ebin/logger_std_h.beam +++ b/bootstrap/lib/kernel/ebin/logger_std_h.beam diff --git a/bootstrap/lib/kernel/ebin/ram_file.beam b/bootstrap/lib/kernel/ebin/ram_file.beam Binary files differindex 658240ef1e..c2f265ede4 100644 --- a/bootstrap/lib/kernel/ebin/ram_file.beam +++ b/bootstrap/lib/kernel/ebin/ram_file.beam diff --git a/bootstrap/lib/stdlib/ebin/dets_utils.beam b/bootstrap/lib/stdlib/ebin/dets_utils.beam Binary files differindex 6f00fd917b..2b56a46eb1 100644 --- a/bootstrap/lib/stdlib/ebin/dets_utils.beam +++ b/bootstrap/lib/stdlib/ebin/dets_utils.beam diff --git a/bootstrap/lib/stdlib/ebin/dets_v9.beam b/bootstrap/lib/stdlib/ebin/dets_v9.beam Binary files differindex 088a58617c..2fda3ba53f 100644 --- a/bootstrap/lib/stdlib/ebin/dets_v9.beam +++ b/bootstrap/lib/stdlib/ebin/dets_v9.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_anno.beam b/bootstrap/lib/stdlib/ebin/erl_anno.beam Binary files differindex 710a82f1fa..7a0a4c08d8 100644 --- a/bootstrap/lib/stdlib/ebin/erl_anno.beam +++ b/bootstrap/lib/stdlib/ebin/erl_anno.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_eval.beam b/bootstrap/lib/stdlib/ebin/erl_eval.beam Binary files differindex a6dc4e0d68..eea70718c8 100644 --- a/bootstrap/lib/stdlib/ebin/erl_eval.beam +++ b/bootstrap/lib/stdlib/ebin/erl_eval.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam Binary files differindex a4bfe3d411..9a3daef51e 100644 --- a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam +++ b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_internal.beam b/bootstrap/lib/stdlib/ebin/erl_internal.beam Binary files differindex c635408fde..c571d9f6f3 100644 --- a/bootstrap/lib/stdlib/ebin/erl_internal.beam +++ b/bootstrap/lib/stdlib/ebin/erl_internal.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam Binary files differindex fd2b331f69..3fa4a49c24 100644 --- a/bootstrap/lib/stdlib/ebin/erl_lint.beam +++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_scan.beam b/bootstrap/lib/stdlib/ebin/erl_scan.beam Binary files differindex 0f516803e3..a7a2910e1b 100644 --- a/bootstrap/lib/stdlib/ebin/erl_scan.beam +++ b/bootstrap/lib/stdlib/ebin/erl_scan.beam diff --git a/bootstrap/lib/stdlib/ebin/filename.beam b/bootstrap/lib/stdlib/ebin/filename.beam Binary files differindex 42e8e24580..85d568a8e1 100644 --- a/bootstrap/lib/stdlib/ebin/filename.beam +++ b/bootstrap/lib/stdlib/ebin/filename.beam diff --git a/bootstrap/lib/stdlib/ebin/gen_event.beam b/bootstrap/lib/stdlib/ebin/gen_event.beam Binary files differindex bb1d4f69ba..ef8d0cd929 100644 --- a/bootstrap/lib/stdlib/ebin/gen_event.beam +++ b/bootstrap/lib/stdlib/ebin/gen_event.beam diff --git a/bootstrap/lib/stdlib/ebin/gen_fsm.beam b/bootstrap/lib/stdlib/ebin/gen_fsm.beam Binary files differindex 769f82a528..3a4df3499c 100644 --- a/bootstrap/lib/stdlib/ebin/gen_fsm.beam +++ b/bootstrap/lib/stdlib/ebin/gen_fsm.beam diff --git a/bootstrap/lib/stdlib/ebin/gen_server.beam b/bootstrap/lib/stdlib/ebin/gen_server.beam Binary files differindex 68e6390cbe..1752276cc8 100644 --- a/bootstrap/lib/stdlib/ebin/gen_server.beam +++ b/bootstrap/lib/stdlib/ebin/gen_server.beam diff --git a/bootstrap/lib/stdlib/ebin/gen_statem.beam b/bootstrap/lib/stdlib/ebin/gen_statem.beam Binary files differindex f47d71163d..ebdb70b93c 100644 --- a/bootstrap/lib/stdlib/ebin/gen_statem.beam +++ b/bootstrap/lib/stdlib/ebin/gen_statem.beam diff --git a/bootstrap/lib/stdlib/ebin/io.beam b/bootstrap/lib/stdlib/ebin/io.beam Binary files differindex e1841e184c..197d9b7f9c 100644 --- a/bootstrap/lib/stdlib/ebin/io.beam +++ b/bootstrap/lib/stdlib/ebin/io.beam diff --git a/bootstrap/lib/stdlib/ebin/ms_transform.beam b/bootstrap/lib/stdlib/ebin/ms_transform.beam Binary files differindex 03b4b75bb6..e465ca8d5d 100644 --- a/bootstrap/lib/stdlib/ebin/ms_transform.beam +++ b/bootstrap/lib/stdlib/ebin/ms_transform.beam diff --git a/bootstrap/lib/stdlib/ebin/otp_internal.beam b/bootstrap/lib/stdlib/ebin/otp_internal.beam Binary files differindex 00fef1da84..ab99005d7a 100644 --- a/bootstrap/lib/stdlib/ebin/otp_internal.beam +++ b/bootstrap/lib/stdlib/ebin/otp_internal.beam diff --git a/bootstrap/lib/stdlib/ebin/proc_lib.beam b/bootstrap/lib/stdlib/ebin/proc_lib.beam Binary files differindex b8602a6490..ce36bcf6fc 100644 --- a/bootstrap/lib/stdlib/ebin/proc_lib.beam +++ b/bootstrap/lib/stdlib/ebin/proc_lib.beam diff --git a/bootstrap/lib/stdlib/ebin/qlc.beam b/bootstrap/lib/stdlib/ebin/qlc.beam Binary files differindex 5d4375adca..c1cd50f143 100644 --- a/bootstrap/lib/stdlib/ebin/qlc.beam +++ b/bootstrap/lib/stdlib/ebin/qlc.beam diff --git a/bootstrap/lib/stdlib/ebin/shell.beam b/bootstrap/lib/stdlib/ebin/shell.beam Binary files differindex 36a9c27c35..65ffc775ad 100644 --- a/bootstrap/lib/stdlib/ebin/shell.beam +++ b/bootstrap/lib/stdlib/ebin/shell.beam diff --git a/bootstrap/lib/stdlib/ebin/string.beam b/bootstrap/lib/stdlib/ebin/string.beam Binary files differindex 678fead549..57142f539a 100644 --- a/bootstrap/lib/stdlib/ebin/string.beam +++ b/bootstrap/lib/stdlib/ebin/string.beam diff --git a/bootstrap/lib/stdlib/ebin/supervisor.beam b/bootstrap/lib/stdlib/ebin/supervisor.beam Binary files differindex 1cb1178884..939f385c93 100644 --- a/bootstrap/lib/stdlib/ebin/supervisor.beam +++ b/bootstrap/lib/stdlib/ebin/supervisor.beam diff --git a/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam b/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam Binary files differindex cb61f6e6f9..6cfaa984df 100644 --- a/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam +++ b/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam diff --git a/bootstrap/lib/stdlib/ebin/unicode.beam b/bootstrap/lib/stdlib/ebin/unicode.beam Binary files differindex b3b0a4637a..bdd4374aef 100644 --- a/bootstrap/lib/stdlib/ebin/unicode.beam +++ b/bootstrap/lib/stdlib/ebin/unicode.beam diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index 74654a295d..4cf0066999 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -631,14 +631,16 @@ of process heaps is destroyed by the crash dump generation.</p> <p>Option <c>+d</c> instructs the emulator to produce only a core dump and no crash dump if an internal error is detected.</p> - <p>Calling <seealso marker="erlang:halt/1"> + <p>Calling <seealso marker="erlang#halt/1"> <c>erlang:halt/1</c></seealso> with a string argument still produces a crash dump. On Unix systems, sending an emulator process a <c>SIGUSR1</c> signal also forces a crash dump.</p> </item> <tag><marker id="+e"/><c><![CDATA[+e Number]]></c></tag> <item> - <p>Sets the maximum number of ETS tables.</p> + <p>Sets the maximum number of ETS tables. This limit is + <seealso marker="stdlib:ets#max_ets_tables">partially obsolete</seealso>. + </p> </item> <tag><c><![CDATA[+ec]]></c></tag> <item> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index cff56b9cb8..1b973cd60e 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -36,8 +36,8 @@ in this module. Some of the BIFs are viewed more or less as part of the Erlang programming language and are <em>auto-imported</em>. Thus, it is not necessary to specify the - module name. For example, the calls <c>atom_to_list(Erlang)</c> - and <c>erlang:atom_to_list(Erlang)</c> are identical.</p> + module name. For example, the calls <c>atom_to_list(erlang)</c> + and <c>erlang:atom_to_list(erlang)</c> are identical.</p> <p>Auto-imported BIFs are listed without module prefix. BIFs listed with module prefix are not auto-imported.</p> @@ -4832,11 +4832,11 @@ RealSystem = system + MissedSystem</code> </item> <tag><c>error_logger</c></tag> <item> - <p>When set to <c>true</c>, the runtime system sends a - message to the current <seealso marker="kernel:error_logger"> - <c>error_logger</c></seealso> + <p>When set to <c>true</c>, the runtime system logs an + error event via <seealso marker="kernel:logger"> + <c>logger</c></seealso>, containing details about the process when the maximum - heap size is reached. One <c>error_logger</c> report is sent + heap size is reached. One log event is sent each time the limit is reached.</p> <p>If <c>error_logger</c> is not defined in the map, the system default is used. The default system default is <c>true</c>. @@ -4850,7 +4850,7 @@ RealSystem = system + MissedSystem</code> amount of memory that is used during the garbage collection. When contemplating using this option, it is recommended to first run it in production with <c>kill</c> set to <c>false</c> and inspect - the <c>error_logger</c> reports to see what the normal peak sizes + the log events to see what the normal peak sizes of the processes in the system is and then tune the value accordingly. </p> @@ -7382,7 +7382,7 @@ ok <note><p>If a scheduler fails to bind, this is often silently ignored, as it is not always possible to verify valid logical processor identifiers. If an error is reported, - it is reported to <c>error_logger</c>. To verify that the + an error event is logged. To verify that the schedulers have bound as requested, call <seealso marker="#system_info_scheduler_bindings"> <c>erlang:system_info(scheduler_bindings)</c></seealso>.</p> @@ -8166,16 +8166,18 @@ ok <c>erl(1)</c>. </p> </item> + <tag><marker id="system_info_ets_count"/> + <c>ets_count</c></tag> + <item> + <p>Returns the number of ETS tables currently existing at the + local node.</p> + </item> <tag><marker id="system_info_ets_limit"/> <c>ets_limit</c></tag> <item> - <p>Returns the maximum number of ETS tables allowed. This - limit can be increased at startup by passing - command-line flag - <seealso marker="erts:erl#+e"><c>+e</c></seealso> to - <c>erl(1)</c> or by setting environment variable - <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang - runtime system.</p> + <p>Returns the limit for number of ETS tables. This limit is + <seealso marker="stdlib:ets#max_ets_tables">partially obsolete</seealso> + and number of tables are only limited by available memory.</p> </item> <tag><marker id="system_info_port_count"/><c>port_count</c></tag> <item> diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index d741e29958..f7f86084a9 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -31,220 +31,12 @@ </header> <p>This document describes the changes made to the ERTS application.</p> -<section><title>Erts 10.0</title> +<section><title>Erts 9.3.2</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> <p> - The type specifications for <c>file:posix/0</c> and - <c>inet:posix/0</c> have been updated according to which - errors file and socket operations should be able to - return.</p> - <p> - Own Id: OTP-14019 Aux Id: ERL-550 </p> - </item> - <item> - <p> - Fix error printout from run_erl and a bug that could - cause unintended fds to be leaked into the started - program.</p> - <p> - Own Id: OTP-14537 Aux Id: PR1529 </p> - </item> - <item> - <p> File operations used to accept <seealso - marker="kernel:file#type-name_all">filenames</seealso> - containing null characters (integer value zero). This - caused the name to be truncated and in some cases - arguments to primitive operations to be mixed up. - Filenames containing null characters inside the filename - are now <em>rejected</em> and will cause primitive file - operations to fail. </p> <p> Also environment variable - operations used to accept <seealso - marker="kernel:os#type-env_var_name">names</seealso> and - <seealso - marker="kernel:os#type-env_var_value">values</seealso> of - environment variables containing null characters (integer - value zero). This caused operations to silently produce - erroneous results. Environment variable names and values - containing null characters inside the name or value are - now <em>rejected</em> and will cause environment variable - operations to fail. </p> <p>Primitive environment - variable operations also used to accept the <c>$=</c> - character in environment variable names causing various - problems. <c>$=</c> characters in environment variable - names are now also <em>rejected</em>. </p> <p>Also - <seealso - marker="kernel:os#cmd/1"><c>os:cmd/1</c></seealso> now - reject null characters inside its <seealso - marker="kernel:os#type-os_command">command</seealso>. - </p> <p><seealso - marker="erts:erlang#open_port/2"><c>erlang:open_port/2</c></seealso> - will also reject null characters inside the port name - from now on.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14543 Aux Id: ERL-370 </p> - </item> - <item> - <p> - Fix bugs related to the bookkeeping of microstate - accounting states.</p> - <p> - Own Id: OTP-14652</p> - </item> - <item> - <p><c>os:putenv</c> and <c>os:getenv</c> no longer access - the process environment directly and instead work on a - thread-safe emulation. The only observable difference is - that it's <em>not</em> kept in sync with libc - <c>getenv(3)</c> / <c>putenv(3)</c>, so those who relied - on that behavior in drivers or NIFs will need to add - manual synchronization.</p> <p>On Windows this means that - you can no longer resolve DLL dependencies by modifying - the <c>PATH</c> just before loading the driver/NIF. To - make this less of a problem, the emulator now adds the - target DLL's folder to the DLL search path.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14666</p> - </item> - <item> - <p>Corrected <c>erlang:is_builtin(erlang, M, F)</c> to - return <c>true</c> for <c>apply/2</c> and - <c>yield/0</c>.</p> - <p> - Own Id: OTP-14713 Aux Id: ERL-500 </p> - </item> - <item> - <p>Fixed a bug where the PATH environment variable wasn't - updated correctly on a release downgrade, effectively - keeping the PATH of the new release.</p> - <p> - Own Id: OTP-14719</p> - </item> - <item> - <p>A receive optimization that avoids scanning the entire - message queue when receiving a message containing a - freshly created reference could in rare circumstances - (involving recursive calls to the functions that does the - receive) cause the receive to hang. This has been - corrected.</p> - <p> - Own Id: OTP-14782 Aux Id: ERL-511 </p> - </item> - <item> - <p> - Fix building of Erlang/OTP on platforms which have small - data area with short addressing. For example the - PowerPC/RTEMS platform.</p> - <p> - Own Id: OTP-14909 Aux Id: PR-1692 </p> - </item> - <item> - <p>Fixed a crash when <c>enif_make_binary</c> is called - with a binary produced by <c>enif_inspect_binary</c> in a - different environment.</p> - <p> - Own Id: OTP-14931</p> - </item> - <item> - <p>Fixed a crash when <c>enif_make_binary</c> is called - more than once with a binary that had previously been - added to an <c>enif_ioq</c>.</p> - <p> - Own Id: OTP-14932</p> - </item> - <item> - <p> - The erl_child_setup program now ignores SIGTERM signals.</p> - <p> - Own Id: OTP-14943 Aux Id: ERL-576 </p> - </item> - <item> - <p> - Force 64-bit alignment on pre-allocators on architectures - which needs it.</p> - <p> - Own Id: OTP-14977</p> - </item> - <item> - <p> - Fixed a bug where dirty scheduler picked up non-dirty - work.</p> - <p> - Own Id: OTP-14978</p> - </item> - <item> - <p> - Calls to <c>gen_tcp:send/2</c> on closed sockets now - returns <c>{error, closed}</c> instead of - <c>{error,enotconn}</c>.</p> - <p> - Own Id: OTP-15001</p> - </item> - <item> - <p> - <c>erlang:monotonic_time/1</c> failed with <c>badarg</c> - when passing the <c>perf_counter</c> time unit as - argument.</p> - <p> - Own Id: OTP-15008</p> - </item> - <item> - <p> - Fix bug where rapid <c>init:restart()</c> calls would - sometimes crash because a code load request leaked in - between the restarts.</p> - <p> - Own Id: OTP-15013</p> - </item> - <item> - <p> - Improve <c>float_to_list(F, [{decimals,D}])</c> to closer - conform with <c>io_lib:format("~.*f", [D,F])</c>.</p> - <p> - There are however, still cases when <c>float_to_list</c> - does not produce the exact same result as - <c>io_lib:format</c>, especially for large values - <c>F</c> and/or many decimals <c>D</c>.</p> - <p> - Own Id: OTP-15015 Aux Id: OTP-14890 </p> - </item> - <item> - <p>Fixed a deadlock that would occur on certain - allocators when a reallocation failed with <c>+ramv</c> - enabled.</p> - <p> - Own Id: OTP-15024</p> - </item> - <item> - <p> - Fix bug that made it impossible to use an erl_tracer as - the seq_trace trace receiver.</p> - <p> - Own Id: OTP-15029</p> - </item> - <item> - <p> - Fix bug where a large (> 1 GB) emulator generated error - logger message would cause the emulator to crash.</p> - <p> - Own Id: OTP-15032</p> - </item> - <item> - <p>The emulator will no longer crash when reading the - file information of an ordinary file that has an NTFS - reparse point, such as files stored in a OneDrive-mapped - folder.</p> - <p> - Own Id: OTP-15062 Aux Id: ERL-615 </p> - </item> - <item> - <p> Fixed bug in <c>enif_binary_to_term</c> which could cause memory corruption for immediate terms (atoms, small integers, pids, ports, empty lists).</p> @@ -259,650 +51,6 @@ <p> Own Id: OTP-15085</p> </item> - <item> - <p> - On OSs with per thread CPU time support, change - <c>cpu_timestamp</c> in <seealso - marker="erlang#trace/3">erlang:trace/3</seealso> to use - it instead of per process CPU time. This makes this - option useable on such OSs when running multiple - schedulers.</p> - <p> - Own Id: OTP-15090</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>It is now possible to open device files and FIFOs with - <c>file:open/2</c>.</p> - <p> - Own Id: OTP-11462</p> - </item> - <item> - <p> - The <c>erlang:system_flag(scheduler_wall_time,Bool)</c> - call is now reference counted and will be turned off if - the (last) process that started the performance - statistics dies. Thus it is no longer possible to start - the statistics with <c>rpc:call(Node, erlang, - system_flag, [scheduler_wall_time, true])</c> since it - will be turned off directly afterwards when the rpc - process dies.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-11694</p> - </item> - <item> - <p>A new logging API is added to Erlang/OTP, see the - <seealso - marker="kernel:logger"><c>logger(3)</c></seealso> manual - page, and section <seealso - marker="kernel:logger_chapter">Logging</seealso> in the - Kernel User's Guide.</p> - <p>Calls to <c>error_logger</c> are automatically - redirected to the new API, and legacy error logger event - handlers can still be used. It is, however, recommended - to use the Logger API directly when writing new code.</p> - <p>Notice the following potential incompatibilities:</p> - <list> <item><p>Kernel configuration parameters - <c>error_logger</c> still works, but is overruled if the - default handler's output destination is configured with - Kernel configuration parameter <c>logger</c>.</p> <p>In - general, parameters for configuring error logger are - overwritten by new parameters for configuring - Logger.</p></item> <item><p>The concept of SASL error - logging is deprecated, meaning that by default the SASL - application does not affect which log events are - logged.</p> <p>By default, supervisor reports and crash - reports are logged by the default Logger handler started - by Kernel, and end up at the same destination (terminal - or file) as other standard log event from Erlang/OTP.</p> - <p>Progress reports are not logged by default, but can be - enabled with the Kernel configuration parameter - <c>logger_progress_reports</c>.</p> <p>To obtain - backwards compatibility with the SASL error logging - functionality from earlier releases, set Kernel - configuration parameter <c>logger_sasl_compatible</c> to - <c>true</c>. This prevents the default Logger handler - from logging any supervisor-, crash-, or progress - reports. Instead, SASL adds a separate Logger handler - during application start, which takes care of these log - events. The SASL configuration parameters - <c>sasl_error_logger</c> and <c>sasl_errlog_type</c> - specify the destination (terminal or file) and severity - level to log for these events.</p></item></list> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13295</p> - </item> - <item> - <p> - <c>gen_sctp:connect_init/4</c> or rather connect in - <c>inet_drv.c</c> for SCTP has been fixed to not check - the write file descriptor for writeability after a - connect, since for SCTP (SOCK_SEQPACKET) that property - does not seem to be any kind of indicator for when a - connect has finished. This fixes connects that the OS - returned as "in progress" that was misinterpreted by - <c>gen_sctp:connect_init</c> as failed.</p> - <p> - Own Id: OTP-13760 Aux Id: PR-1592 </p> - </item> - <item> - <p>The file driver has been rewritten as a NIF, - decreasing the latency of file operations. Two notable - incompatibilities are:</p> <list> <item><p>The - <c>use_threads</c> option for <c>file:sendfile/5</c> no - longer has any effect; we either use non-blocking - <c>sendfile(2)</c> or fall back to <c>file:read</c> + - <c>gen_tcp:send</c>. </p></item> <item><p>The - file-specific DTrace probes have been removed. The same - effect can be achieved with normal tracing together with - the <c>nif__entry</c>/<c>nif__return</c> probes to track - scheduling.</p></item> </list> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14256</p> - </item> - <item> - <p>The I/O polling functionality of erts has been - re-written to better make use of the OSs polling - mechanisms. This change means that erts will now always - prefer to use a kernel-polling mechanism if possible. - Also all of the I/O polling has been moved to dedicated - threads instead of being placed in the scheduler - loops.</p> <p>As a result of this, the <c>erl</c> options - <c>+K</c> and <c>+secio</c> have been removed. It is - still possible to disable kernel-poll, but it has to be - done at compile time through the configure option - <c>--disable-kernel-poll</c>.</p> <p>The new <c>erl</c> - options <seealso marker="erl#+IOt"><c>+IOt</c></seealso> - and <seealso marker="erl#+IOp"><c>+IOp</c></seealso> can - be used to change how many IO poll threads and poll sets - that erts should use. See their respective documentation - for more details.</p> - <p> - Own Id: OTP-14346</p> - </item> - <item> - <p>Truly asynchronous auto-connect. Earlier, when - <c>erlang:send</c> was done toward an unconnected node, - the function would not return until the connection setup - had completed (or failed). Now the function returns - directly after the signal has been enqueued and the - connection setup started.</p> - <p>The same applies to all distributed operations that - may trigger auto-connect, i.e. <c>'!'</c>, <c>send</c>, - <c>link</c>, <c>monitor</c>, <c>monitor_node</c>, - <c>exit/2</c> and <c>group_leader</c>.</p> - <p>The interface for all these functions are unchanged as - they do not return connection failures. The only - exception is <c>erlang:monitor</c> where a <em>possible - incompatibility</em> is introduced: An attempt to monitor - a process on a primitive node (such as erl_interface or - jinterface), where remote process monitoring is not - implemented, will no longer fail with <c>badarg</c> - exception. Instead a monitor will be created, but it will - only supervise the connection to the node.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14370</p> - </item> - <item> - <p>Changed the default behaviour of <c>.erlang</c> - loading: <c>.erlang</c> is no longer loaded from the - current directory. <c>c:erlangrc(PathList)</c> can be - used to search and load an <c>.erlang</c> file from user - specified directories.</p> <p><c>escript</c>, - <c>erlc</c>, <c>dialyzer</c> and <c>typer</c> no longer - load an <c>.erlang</c> at all.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14439</p> - </item> - <item> - <p> - New functionality for implementation of alternative - carriers for the Erlang distribution has been introduced. - This mainly consists of support for usage of distribution - controller processes (previously only ports could be used - as distribution controllers). For more information see - <seealso marker="erts:alt_dist#distribution_module">ERTS - User's Guide ➜ How to implement an Alternative Carrier - for the Erlang Distribution ➜ Distribution - Module</seealso>.</p> - <p> - Own Id: OTP-14459</p> - </item> - <item> - <p> - Add support for the lcc compiler and in extension the - Elbrus 2000 platform.</p> - <p> - Own Id: OTP-14492</p> - </item> - <item> - <p>Support for "tuple calls" have been removed from the - run-time system. Tuple calls was an undocumented and - unsupported feature which allowed the module argument for - an apply operation to be a tuple: <c>Var = dict:new(), - Var:size()</c>. This "feature" frequently caused - confusion, especially when such call failed. The - stacktrace would point out functions that don't exist in - the source code.</p> - <p>For legacy code that need to use parameterized modules - or tuple calls for some other reason, there is a new - compiler option called <c>tuple_calls</c>. When this - option is given, the compiler will generate extra code - that emulates the old behavior for calls where the module - is a variable.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14497</p> - </item> - <item> - <p>Creation of small maps with literal keys has been - optimized to be faster and potentially use less memory. - The keys are combined into a literal key tuple which is - put into the literal pool. The key tuple can be shared - between many instances of maps having the same keys.</p> - <p> - Own Id: OTP-14502</p> - </item> - <item> - <p> - When an exception is thrown, include the arguments of the - call in the stacktrace for BIFs <c>band</c>, <c>bor</c>, - <c>bsl</c>, <c>bsr</c>, <c>bxor</c>, <c>div</c>, - <c>rem</c> and the operators <c>+</c>, <c>-</c>, <c>*</c> - and <c>/</c>.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14508</p> - </item> - <item> - <p> - The non-smp emulators have been removed. This means that - the configure options <c>--disable-threads</c> and - <c>--enable-plain-emulator</c> have been removed and - configure will now refuse to build Erlang/OTP on - platforms without thread support.</p> - <p> - In order to achieve a similar setup as the non-smp - emulator, it is possible to start Erlang/OTP with the - <c>+S 1</c> option.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14518</p> - </item> - <item> - <p>Modules that use floating point constants compiled - with R15 or earlier will need to be re-compiled before - they can be loaded.</p> - <p> - Own Id: OTP-14575</p> - </item> - <item> - <p> - Implementation of true asynchronous signaling between - processes in order to improve scalability. Signals - affected include exit, monitor, demonitor, monitor - triggered, link, unlink, and group leader.</p> - <p> - Own Id: OTP-14589</p> - </item> - <item> - <p> - Added a PGO (profile guided optimization) pass to the - build step of erts. This can be disabled by passing - --disable-pgo to configure.</p> - <p> - Own Id: OTP-14604</p> - </item> - <item> - <p> - Improved the performance of <c>binary:split</c> and - <c>binary:match</c>.</p> - <p> - Own Id: OTP-14610 Aux Id: PR-1480 </p> - </item> - <item> - <p> - It is not longer possible to disable dirty schedulers - when building erlang.</p> - <p> - Own Id: OTP-14613</p> - </item> - <item> - <p>Loaded BEAM code in a 64-bit system requires less - memory because of better packing of operands for - instructions.</p> - <p>These memory savings were achieved by major - improvements to the <c>beam_makeops</c> scripts used when - building the run time system and BEAM compiler. There is - also new for documentation for <c>beam_makeops</c> that - describes how new BEAM instructions and loader - transformations can be implemented. The documentation is - found in here in a source directory or git repository: - erts/emulator/internal_doc/beam_makeops.md. An online - version can be found here: - https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/beam_makeops.md</p> - <p> - Own Id: OTP-14626</p> - </item> - <item> - <p><c>file:read_file</c> has been changed to read the - content of files that report a size of 0 even when data - can be read from them. An example of such a file is - <c>/proc/cpuinfo</c> on Linux.</p> - <p> - Own Id: OTP-14637 Aux Id: ERL-327 PR-1524 </p> - </item> - <item> - <p> - It is no longer possible to disable the <c>temp_alloc</c> - allocator. Disabling it caused serious performance - degradations and was never what was wanted.</p> - <p> - Own Id: OTP-14651</p> - </item> - <item> - <p>The reduction cost of sending messages is now - constant. It will no longer scale according to the length - of the receiving process' message queue.</p> - <p> - Own Id: OTP-14667</p> - </item> - <item> - <p> - Improved loading of modules with <c>-on_load</c> - directive, to no longer block all schedulers when the - load operation is completed.</p> - <p> - Own Id: OTP-14680</p> - </item> - <item> - <p> - On platforms with real-time signals available, SIGRTMIN+1 - is now used as the internal scheduler suspend signal - instead of SIGUSR2.</p> - <p> - Own Id: OTP-14682</p> - </item> - <item> - <p>When the value returned from a '<c>catch</c>' - expression is ignored, no stacktrace will be built if an - exception is caught. That will save time and produce less - garbage. There are also some minor optimizations of - '<c>try</c>/<c>catch</c>' both in the compiler and - run-time system.</p> - <p> - Own Id: OTP-14683</p> - </item> - <item> - <p>The guarantees and non-guarantees of - <c>erlang:get_stacktrace/0</c> are now documented.</p> - <p> - Own Id: OTP-14687</p> - </item> - <item> - <p>There is a new syntax in '<c>try/catch</c>' for - retrieving the stacktrace without calling - '<c>erlang:get_stacktrace/0</c>'. See the reference - manual for a description of the new syntax. The - '<c>erlang:get_stacktrace/0</c>' BIF is now - deprecated.</p> - <p> - Own Id: OTP-14692</p> - </item> - <item> - <p> - New 'used' option for <c>binary_to_term/2</c> that will - also return number of bytes actually read from the - binary. This enables easy access to any extra data in the - binary located directly after the returned term.</p> - <p> - Own Id: OTP-14780</p> - </item> - <item> - <p> - Added more statistics for - <c>erlang:system_info({allocator,A})</c> in the - <c>mbcs_pool</c> section.</p> - <p> - Own Id: OTP-14795 Aux Id: ERL-88 </p> - </item> - <item> - <p>Added <c>enif_ioq_peek_head</c> to retrieve Erlang - terms from NIF IO queues without having to resort to - copying.</p> - <p> - Own Id: OTP-14797</p> - </item> - <item> - <p>There is a new option '<c>makedep_side_effect</c>' for - the compiler and <c>-MMD</c> for '<c>erlc</c>' that - generates dependencies and continues to compile as - normal.</p> - <p> - Own Id: OTP-14830</p> - </item> - <item> - <p>Added <c>ets:whereis/1</c> for retrieving the table - identifier of a named table.</p> - <p> - Own Id: OTP-14884</p> - </item> - <item> - <p><c>seq_trace</c> labels may now be any erlang - term.</p> - <p> - Own Id: OTP-14899</p> - </item> - <item> - <p> - Optimized the common case of <c>monitor</c> followed by - <c>send</c> to the same local process. The monitor signal - is now delayed in order to be piggybacked with the sent - message and thereby only get one lock operation on the - message queue of the receiver. A delayed monitor signal - is flushed if no <c>send</c> has been done at the latest - when the process is scheduled out.</p> - <p> - Own Id: OTP-14901</p> - </item> - <item> - <p> - Make hipe compiled code work on x86_64 (amd64) with OS - security feature PIE, where executable code can be loaded - into a random location. Old behavior, if hipe was - enabled, was to disable PIE build options for the VM.</p> - <p> - Own Id: OTP-14903</p> - </item> - <item> - <p>The number of driver async threads will now default to - 1 as the standard drivers do not use them anymore. Users - that changed this value to tweak the file driver should - replace <c>+A</c> with <c>+SDio</c> since it now uses - dirty IO schedulers instead of async threads.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14928</p> - </item> - <item> - <p> - Optimize <c>==</c> and <c>/=</c> for binaries with - different sizes to be constant in time instead of - proportional to the size of their common prefix.</p> - <p> - Own Id: OTP-14934 Aux Id: PR-1708 </p> - </item> - <item> - <p> - Refactorings making some internal process flags available - for other usage.</p> - <p> - Own Id: OTP-14948</p> - </item> - <item> - <p> - Removed need for HiPE to allocate native executable - memory in low 2GB address space on x86_64. Command line - option <c>+MXscs</c> is thereby obsolete and ignored.</p> - <p> - Own Id: OTP-14951</p> - </item> - <item> - <p>Added <c>enif_make_map_from_arrays</c> for creating a - populated map, analogous to - <c>enif_make_list_from_array</c>.</p> - <p> - Own Id: OTP-14954</p> - </item> - <item> - <p>Added configuration switches for busy-wait and wake up - thresholds for dirty schedulers, and changing these - settings for normal schedulers will no longer affect - dirty schedulers. </p> <p>Refer to the documentation for - details. The new switches are <seealso - marker="erl#+sbwtdcpu">+sbwtdcpu</seealso>, <seealso - marker="erl#+sbwtdio">+sbwtdio</seealso>, <seealso - marker="erl#+swtdcpu">+swtdcpu</seealso>, and <seealso - marker="erl#+swtdio">+swtdio</seealso>.</p> <p>The - default busy wait threshold for dirty scheduler threads - has also been lowered to <c>short</c>.</p> - <p> - Own Id: OTP-14959</p> - </item> - <item> - <p> - The list of "taints" now also includes dynamic loaded - drivers in addition to NIF libraries. Statically linked - drivers and NIF libraries that are part of erts are not - included. The "taints" are returned by - <c>system_info(taints)</c> and printed in the header of - <c>erl_crash.dump</c> files.</p> - <p> - Own Id: OTP-14960</p> - </item> - <item> - <p>Added <c>instrument:allocations</c> and - <c>instrument:carriers</c> for retrieving information - about memory utilization and fragmentation.</p> - <p>The old <c>instrument</c> interface has been removed, - as have the related options <c>+Mim</c> and - <c>+Mis</c>.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14961</p> - </item> - <item> - <p>The process suspend functionality used by the <seealso - marker="erlang:suspend_process/2">erlang:suspend_process/2</seealso> - BIF has been reimplemented using the newly introduced - true asynchronous signaling between processes. This - mainly to reduce memory usage in the process control - block of all processes, but also in order to simplify the - implementation.</p> <warning> <p>You can easily create - deadlocks if processes suspends each other (directly or - in circles). In ERTS versions prior to ERTS version 10.0, - the runtime system prevented such deadlocks, but this - prevention has now been removed due to performance - reasons.</p> </warning> <p>Other ERTS internal - functionality that used the previous process suspend - functionality have also been reimplemented to use - asynchronous signaling instead.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14964 Aux Id: OTP-14589 </p> - </item> - <item> - <p>Added the <c>nifs</c> option to - <c>?MODULE:module_info/1</c> for listing a module's - installed NIF functions.</p> - <p> - Own Id: OTP-14965</p> - </item> - <item> - <p> - New implementation of <c>erlang:process_info/[1,2]</c>.</p> - <p> - In the general case when inspecting another process, the - new implementation sends an asynchronous process-info - request signal to the other process and waits for the - result instead of locking the other process and reading - the result directly. In some special cases where no - conflicts occur, signal order wont be violated, and the - amount of data requested is guaranteed to be small, the - inspected process may be inspected directly.</p> - <p> - Appropriate amount of reductions are now also bumped when - inspecting a process.</p> - <p> - Own Id: OTP-14966</p> - </item> - <item> - <p> - Removed process start time from crash dump in order to - save memory in process control block.</p> - <p> - Own Id: OTP-14975 Aux Id: PR-1597 </p> - </item> - <item> - <p> - Optimize <c>erlang:put/2</c> when updating existing key - with a new immediate value (atom, small integer, pid, - port).</p> - <p> - Own Id: OTP-14976</p> - </item> - <item> - <p> - <c>erlang:process_info/1</c> has been changed to no - longer include <c>messages</c> by default. Instead - <c>erlang:process_info/2</c> should be used.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14986 Aux Id: PR-1745 </p> - </item> - <item> - <p> - New NIF functions: <c>enif_mutex_name</c>, - <c>enif_cond_name</c>, <c>enif_rwlock_name</c>, - <c>enif_thread_name</c>, <c>enif_vfprintf</c>, - <c>enif_vsnprintf</c>.</p> - <p> - Own Id: OTP-14994</p> - </item> - <item> - <p>When <c>erlang:system_flag(backtrace_depth, 0)</c> has - been called, all exceptions will now contain the entry - for <em>one</em> function (despite the zero). It used to - be that a hand-made stack backtrace passed to - <c>erlang:raise/3</c> would be be truncated to an empty - list.</p> - <p> - Own Id: OTP-15026</p> - </item> - <item> - <p> - Fixed bug for named <c>ets</c> tables which could cause - unexpected results from matchspec iteration functions - (<c>ets:select*</c> and <c>ets:match*</c>) if the table - was deleted and recreated with the same name during the - iteration. The iteration could incorrectly continue - through the recreated table. The expected correct - behavior is now for the iteration call to fail with a - <c>badarg</c> exception if the table is deleted before - the iteration has completed.</p> - <p> - Own Id: OTP-15031</p> - </item> - <item> - <p>Two new guards BIFs operating on maps have been added: - <c>map_get/2</c> and <c>is_map_key/2</c>. They do the - same as <c>maps:get/2</c> and <c>maps:is_key/2</c>, - respectively, except that they are allowed to be used in - guards.</p> - <p> - Own Id: OTP-15037 Aux Id: PR-1784, PR-1802 </p> - </item> - <item> - <p> - Release run-queue lock while cleaning up terminated dirty - process.</p> - <p> - Own Id: OTP-15081</p> - </item> - <item> - <p>The callback module passed as <c>-epmd_module</c> to - erl has been expanded to be able to do name and port - resolving.</p> <p>Documentation has also been added in - the <seealso - marker="kernel:erl_epmd"><c>erl_epmd</c></seealso> - reference manual and ERTS User's Guide <seealso - marker="erts:alt_disco">How to Implement an Alternative - Service Discovery for Erlang Distribution</seealso>.</p> - <p> - Own Id: OTP-15086 Aux Id: PR-1694 </p> - </item> </list> </section> diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 221cf84622..054692819e 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -517,7 +517,9 @@ release_docs_spec: # Generated source code. Put in $(TARGET) directory # +ifneq ($(strip $(CREATE_DIRS)),) _create_dirs := $(shell mkdir -p $(CREATE_DIRS)) +endif # has to be run after _create_dirs diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index d99d2ea57b..575d6ca867 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -2821,20 +2821,20 @@ erts_allocator_options(void *proc) Eterm as[4]; Eterm ts[4]; - as[l] = am_atom_put("e", 1); + as[l] = ERTS_MAKE_AM("e"); ts[l++] = am_true; switch (a) { case ERTS_ALC_A_SYSTEM: - as[l] = am_atom_put("m", 1); - ts[l++] = am_atom_put("libc", 4); + as[l] = ERTS_MAKE_AM("m"); + ts[l++] = ERTS_MAKE_AM("libc"); if(sas.trim_threshold >= 0) { - as[l] = am_atom_put("tt", 2); + as[l] = ERTS_MAKE_AM("tt"); ts[l++] = erts_bld_uint(hpp, szp, (Uint) sas.trim_threshold); } if(sas.top_pad >= 0) { - as[l] = am_atom_put("tp", 2); + as[l] = ERTS_MAKE_AM("tp"); ts[l++] = erts_bld_uint(hpp, szp, (Uint) sas.top_pad); } break; @@ -2848,7 +2848,7 @@ erts_allocator_options(void *proc) } else { - Eterm atom = am_atom_put("e", 1); + Eterm atom = ERTS_MAKE_AM("e"); Eterm term = am_false; tmp = erts_bld_2tup_list(hpp, szp, 1, &atom, &term); } @@ -2859,12 +2859,12 @@ erts_allocator_options(void *proc) #if HAVE_ERTS_MSEG if (use_mseg) { - atoms[length] = am_atom_put("mseg_alloc", 10); + atoms[length] = ERTS_MAKE_AM("mseg_alloc"); terms[length++] = erts_mseg_info_options(0, NULL, NULL, hpp, szp); } #endif - atoms[length] = am_atom_put("alloc_util", 10); + atoms[length] = ERTS_MAKE_AM("alloc_util"); terms[length++] = erts_alcu_au_info_options(NULL, NULL, hpp, szp); #if HAVE_ERTS_MMAP @@ -2874,17 +2874,15 @@ erts_allocator_options(void *proc) #endif { Eterm o[1], v[1]; - o[0] = am_atom_put("t", 1); + o[0] = ERTS_MAKE_AM("t"); v[0] = erts_mtrace_enabled ? am_true : am_false; - atoms[length] = am_atom_put("instr", 5); + atoms[length] = ERTS_MAKE_AM("instr"); terms[length++] = erts_bld_2tup_list(hpp, szp, 1, o, v); } - atoms[length] = am_atom_put("lock_physical_memory", 20); - terms[length++] = (lock_all_physical_memory - ? am_atom_put("all", 3) - : am_atom_put("no", 2)); + atoms[length] = ERTS_MAKE_AM("lock_physical_memory"); + terms[length++] = (lock_all_physical_memory ? am_all : am_no); settings = erts_bld_2tup_list(hpp, szp, length, atoms, terms); @@ -2899,10 +2897,10 @@ erts_allocator_options(void *proc) #if HAVE_ERTS_MSEG if (use_mseg) - terms[length++] = am_atom_put("mseg_alloc", 10); + terms[length++] = ERTS_MAKE_AM("mseg_alloc"); #endif #if ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC - terms[length++] = am_atom_put("sys_aligned_alloc", 17); + terms[length++] = ERTS_MAKE_AM("sys_aligned_alloc"); #endif #if defined(ARCH_64) && defined(ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION) terms[length++] = ERTS_MAKE_AM("literal_mmap"); @@ -2911,7 +2909,7 @@ erts_allocator_options(void *proc) #if defined(__GLIBC__) { - Eterm AM_glibc = am_atom_put("glibc", 5); + Eterm AM_glibc = ERTS_MAKE_AM("glibc"); Eterm version; version = erts_bld_cons(hpp, diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index 9db600dce0..5409b89bab 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -118,9 +118,6 @@ type PORT DRIVER SYSTEM port type ATOM LONG_LIVED ATOM atom_entry type MODULE LONG_LIVED CODE module_entry type REG_PROC STANDARD PROCESSES reg_proc -type LINK_LH STANDARD PROCESSES link_lh -type SUSPEND_MON STANDARD PROCESSES suspend_monitor -type PEND_SUSPEND SHORT_LIVED PROCESSES pending_suspend type PROC_LIST SHORT_LIVED PROCESSES proc_list type SAVED_ESTACK SHORT_LIVED PROCESSES saved_estack type FUN_ENTRY LONG_LIVED CODE fun_entry @@ -133,7 +130,6 @@ type TMP_HEAP TEMPORARY PROCESSES tmp_heap type MSG_REF FIXED_SIZE PROCESSES msg_ref type MSG EHEAP PROCESSES message type MSGQ_CHNG SHORT_LIVED PROCESSES messages_queue_change -type MSG_ROOTS TEMPORARY PROCESSES msg_roots type ROOTSET TEMPORARY PROCESSES root_set type LOADER_TMP TEMPORARY CODE loader_tmp type PREPARED_CODE SHORT_LIVED CODE prepared_code @@ -178,7 +174,6 @@ type BPD STANDARD SYSTEM bpd type LINEBUF STANDARD SYSTEM line_buf type IOQ STANDARD SYSTEM io_queue type BITS_BUF STANDARD SYSTEM bits_buf -type TMP_DIST_BUF TEMPORARY SYSTEM tmp_dist_buf type ASYNC_DATA LONG_LIVED SYSTEM internal_async_data type ESTACK TEMPORARY SYSTEM estack type DB_TABLE ETS ETS db_tab @@ -191,7 +186,6 @@ type DB_MC_STK TEMPORARY ETS db_mc_stack type DB_MS_RUN_HEAP SHORT_LIVED ETS db_match_spec_run_heap type DB_MS_CMPL_HEAP TEMPORARY ETS db_match_spec_cmpl_heap type DB_SEG ETS ETS db_segment -type DB_SEG_TAB ETS ETS db_segment_tab type DB_STK ETS ETS db_stack type DB_TRANS_TAB ETS ETS db_trans_tab type DB_SEL_LIST ETS ETS db_select_list @@ -200,7 +194,6 @@ type DB_DMC_ERR_INFO ETS ETS db_dmc_error_info type DB_TERM ETS ETS db_term type DB_PROC_CLEANUP SHORT_LIVED ETS db_proc_cleanup_state type ETS_ALL_REQ SHORT_LIVED ETS ets_all_request -type INSTR_INFO LONG_LIVED SYSTEM instr_info type LOGGER_DSBUF TEMPORARY SYSTEM logger_dsbuf type TMP_DSBUF TEMPORARY SYSTEM tmp_dsbuf type INFO_DSBUF SYSTEM SYSTEM info_dsbuf @@ -215,7 +208,6 @@ type PT_HNDL_LIST SHORT_LIVED SYSTEM port_task_handle_list type MISC_OP_LIST SHORT_LIVED SYSTEM misc_op_list type PORT_NAMES SHORT_LIVED SYSTEM port_names type PORT_DATA_LOCK DRIVER SYSTEM port_data_lock -type NODES_MON STANDARD PROCESSES nodes_monitor type PTAB_LIST_DEL SHORT_LIVED PROCESSES ptab_list_deleted_el type PTAB_LIST_CNKI SHORT_LIVED PROCESSES ptab_list_chunk_info type PTAB_LIST_PIDS SHORT_LIVED PROCESSES ptab_list_pids @@ -238,10 +230,8 @@ type CPUDATA LONG_LIVED SYSTEM cpu_data type TMP_CPU_IDS SHORT_LIVED SYSTEM tmp_cpu_ids type EXT_TERM_DATA SHORT_LIVED PROCESSES external_term_data type CPU_GRPS_MAP LONG_LIVED SYSTEM cpu_groups_map -type AUX_WORK_TMO LONG_LIVED SYSTEM aux_work_timeouts type MISC_AUX_WORK_Q LONG_LIVED SYSTEM misc_aux_work_q type CODE_IX_LOCK_Q SHORT_LIVED SYSTEM code_ix_lock_q -type PROC_INTERVAL LONG_LIVED SYSTEM process_interval type BUSY_CALLER_TAB SHORT_LIVED SYSTEM busy_caller_table type BUSY_CALLER SHORT_LIVED SYSTEM busy_caller type PROC_SYS_TSK SHORT_LIVED PROCESSES proc_sys_task @@ -250,8 +240,6 @@ type NEW_TIME_OFFSET SHORT_LIVED SYSTEM new_time_offset type IOB_REQ SHORT_LIVED SYSTEM io_bytes_request type TRACER_NIF LONG_LIVED SYSTEM tracer_nif type TRACE_MSG_QUEUE SHORT_LIVED SYSTEM trace_message_queue -type SCHED_ASYNC_JOB SHORT_LIVED SYSTEM async_calls -type DIRTY_START STANDARD PROCESSES dirty_start type DIRTY_SL SHORT_LIVED SYSTEM dirty_short_lived type MREF_NSCHED_ENT FIXED_SIZE SYSTEM nsched_magic_ref_entry type MREF_ENT STANDARD SYSTEM magic_ref_entry @@ -259,7 +247,6 @@ type MREF_TAB_BKTS STANDARD SYSTEM magic_ref_table_buckets type MREF_TAB LONG_LIVED SYSTEM magic_ref_table type MINDIRECTION FIXED_SIZE SYSTEM magic_indirection type BINARY_FIND SHORT_LIVED PROCESSES binary_find -type OPEN_PORT_ENV TEMPORARY SYSTEM open_port_env type CRASH_DUMP STANDARD SYSTEM crash_dump type DIST_TRANSCODE SHORT_LIVED SYSTEM dist_transcode_context @@ -273,10 +260,8 @@ type THR_Q_LL LONG_LIVED SYSTEM long_lived_thr_queue type ASYNC SHORT_LIVED SYSTEM async type ZLIB STANDARD SYSTEM zlib -type PORT_LOCK STANDARD SYSTEM port_lock type DRIVER_LOCK STANDARD SYSTEM driver_lock type XPORTS_LIST SHORT_LIVED SYSTEM extra_port_list -type PROC_LCK_WTR LONG_LIVED SYSTEM proc_lock_waiter type RUNQ_BLNS LONG_LIVED SYSTEM run_queue_balancing type THR_PRGR_IDATA LONG_LIVED SYSTEM thr_prgr_internal_data type THR_PRGR_DATA LONG_LIVED SYSTEM thr_prgr_data @@ -317,12 +302,6 @@ type HIPE_EXEC EXEC CODE hipe_code +endif -+if heap_frag_elim_test - -type SSB SHORT_LIVED PROCESSES ssb - -+endif - +if lcnt type LCNT_CARRIER STANDARD SYSTEM lcnt_lock_info_carrier @@ -342,7 +321,6 @@ type PURGE_DATA SHORT_LIVED CODE purge_data type DB_HEIR_DATA STANDARD ETS db_heir_data type DB_MS_PSDO_PROC LONG_LIVED ETS db_match_pseudo_proc type SCHDLR_DATA LONG_LIVED SYSTEM scheduler_data -type LL_TEMP_TERM LONG_LIVED SYSTEM ll_temp_term type NIF_TRAP_EXPORT STANDARD PROCESSES nif_trap_export_entry type NIF_EXP_TRACE FIXED_SIZE PROCESSES nif_export_trace @@ -366,21 +344,17 @@ type DRV_TAB LONG_LIVED SYSTEM drv_tab type DRV_EV_STATE LONG_LIVED SYSTEM driver_event_state type DRV_SEL_D_STATE FIXED_SIZE SYSTEM driver_select_data_state type NIF_SEL_D_STATE FIXED_SIZE SYSTEM enif_select_data_state -type FD_LIST SHORT_LIVED SYSTEM fd_list type POLLSET LONG_LIVED SYSTEM pollset type POLLSET_UPDREQ SHORT_LIVED SYSTEM pollset_update_req type POLL_FDS LONG_LIVED SYSTEM poll_fds -type POLL_RES_EVS LONG_LIVED SYSTEM poll_result_events type FD_STATUS LONG_LIVED SYSTEM fd_status type SELECT_FDS LONG_LIVED SYSTEM select_fds +if unix type SYS_READ_BUF TEMPORARY SYSTEM sys_read_buf -type FD_TAB LONG_LIVED SYSTEM fd_tab type FD_ENTRY_BUF STANDARD SYSTEM fd_entry_buf type CS_PROG_PATH LONG_LIVED SYSTEM cs_prog_path -type PRT_REP_EXIT STANDARD SYSTEM port_report_exit type SYS_BLOCKING STANDARD SYSTEM sys_blocking type SYS_WRITE_BUF TEMPORARY SYSTEM sys_write_buf @@ -392,7 +366,6 @@ type SYS_WRITE_BUF TEMPORARY SYSTEM sys_write_buf type DRV_DATA_BUF SYSTEM SYSTEM drv_data_buf type PRELOADED LONG_LIVED SYSTEM preloaded type WAITER_OBJ LONG_LIVED SYSTEM waiter_object -type CON_VPRINTF_BUF TEMPORARY SYSTEM con_vprintf_buf +endif diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h index ff4d10b206..cbae8ce98a 100644 --- a/erts/emulator/beam/erl_alloc_util.h +++ b/erts/emulator/beam/erl_alloc_util.h @@ -414,6 +414,10 @@ struct AOFF_RBTree_t_ { AOFF_RBTree_t *right; Uint32 flags; Uint32 max_sz; /* of all blocks in this sub-tree */ + union { + AOFF_RBTree_t* next; /* for best fit */ + Sint64 birth_time; /* for age first fit */ + } u; }; void aoff_add_pooled_mbc(Allctr_t*, Carrier_t*); diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.c b/erts/emulator/beam/erl_ao_firstfit_alloc.c index 0c5545401a..ebbe4af53d 100644 --- a/erts/emulator/beam/erl_ao_firstfit_alloc.c +++ b/erts/emulator/beam/erl_ao_firstfit_alloc.c @@ -100,22 +100,14 @@ #define AOFF_BLK_SZ(B) MBC_FBLK_SZ(&(B)->hdr) -/* BF block nodes keeps list of all with equal size - */ -typedef struct { - AOFF_RBTree_t t; - AOFF_RBTree_t *next; -}AOFF_RBTreeList_t; - -#define LIST_NEXT(N) (((AOFF_RBTreeList_t*) (N))->next) -#define LIST_PREV(N) (((AOFF_RBTreeList_t*) (N))->t.parent) +#define LIST_NEXT(N) (((AOFF_RBTree_t*)(N))->u.next) +#define LIST_PREV(N) (((AOFF_RBTree_t*)(N))->parent) typedef struct AOFF_Carrier_t_ AOFF_Carrier_t; struct AOFF_Carrier_t_ { Carrier_t crr; AOFF_RBTree_t rbt_node; /* My node in the carrier tree */ - Sint64 birth_time; AOFF_RBTree_t* root; /* Root of my block tree */ }; #define RBT_NODE_TO_MBC(PTR) ErtsContainerStruct((PTR), AOFF_Carrier_t, rbt_node) @@ -199,9 +191,7 @@ static ERTS_INLINE SWord cmp_blocks(enum AOFFSortOrder order, { ASSERT(lhs != rhs); if (order == FF_AGEFF) { - AOFF_Carrier_t* lc = RBT_NODE_TO_MBC(lhs); - AOFF_Carrier_t* rc = RBT_NODE_TO_MBC(rhs); - Sint64 diff = lc->birth_time - rc->birth_time; + Sint64 diff = lhs->u.birth_time - rhs->u.birth_time; #ifdef ARCH_64 if (diff) return diff; @@ -296,8 +286,10 @@ erts_aoffalc_start(AOFFAllctr_t *alc, allctr->mbc_header_size = sizeof(AOFF_Carrier_t); allctr->min_mbc_size = MIN_MBC_SZ; allctr->min_mbc_first_free_size = MIN_MBC_FIRST_FREE_SZ; - allctr->min_block_size = (aoffinit->blk_order == FF_BF ? - sizeof(AOFF_RBTreeList_t):sizeof(AOFF_RBTree_t)); + allctr->min_block_size = (aoffinit->blk_order == FF_BF + ? (offsetof(AOFF_RBTree_t, u.next) + + ErtsSizeofMember(AOFF_RBTree_t, u.next)) + : offsetof(AOFF_RBTree_t, u)); allctr->vsn_str = ERTS_ALC_AOFF_ALLOC_VSN_STR; @@ -939,8 +931,11 @@ static void aoff_creating_mbc(Allctr_t *allctr, Carrier_t *carrier) HARD_CHECK_TREE(NULL, alc->crr_order, *root, 0); crr->rbt_node.hdr.bhdr = 0; - if (alc->crr_order == FF_AGEFF || IS_DEBUG) - crr->birth_time = get_birth_time(); + if (alc->crr_order == FF_AGEFF || IS_DEBUG) { + Sint64 bt = get_birth_time(); + crr->rbt_node.u.birth_time = bt; + crr->crr.cpool.pooled.u.birth_time = bt; + } rbt_insert(alc->crr_order, root, &crr->rbt_node); /* aoff_link_free_block will add free block later */ @@ -978,6 +973,7 @@ static void aoff_add_mbc(Allctr_t *allctr, Carrier_t *carrier) void aoff_add_pooled_mbc(Allctr_t *allctr, Carrier_t *crr) { + AOFFAllctr_t *alc = (AOFFAllctr_t *) allctr; AOFF_RBTree_t **root = &allctr->cpool.pooled_tree; ASSERT(allctr == crr->cpool.orig_allctr); @@ -985,7 +981,7 @@ void aoff_add_pooled_mbc(Allctr_t *allctr, Carrier_t *crr) /* Link carrier in address order tree */ - rbt_insert(FF_AOFF, root, &crr->cpool.pooled); + rbt_insert(alc->crr_order, root, &crr->cpool.pooled); HARD_CHECK_TREE(NULL, 0, *root, 0); } diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.h b/erts/emulator/beam/erl_ao_firstfit_alloc.h index 9cf4fc81a8..dad864801f 100644 --- a/erts/emulator/beam/erl_ao_firstfit_alloc.h +++ b/erts/emulator/beam/erl_ao_firstfit_alloc.h @@ -29,10 +29,10 @@ typedef struct AOFFAllctr_t_ AOFFAllctr_t; enum AOFFSortOrder { - FF_AGEFF = 0, + FF_AGEFF = 0, /* carrier trees only */ FF_AOFF = 1, - FF_AOBF = 2, - FF_BF = 3 + FF_AOBF = 2, /* block trees only */ + FF_BF = 3 /* block trees only */ }; typedef struct { diff --git a/erts/emulator/beam/erl_bif_chksum.c b/erts/emulator/beam/erl_bif_chksum.c index 9095bcd380..cf92687595 100644 --- a/erts/emulator/beam/erl_bif_chksum.c +++ b/erts/emulator/beam/erl_bif_chksum.c @@ -44,7 +44,7 @@ void erts_init_bif_chksum(void) { /* Non visual BIF to trap to. */ erts_init_trap_export(&chksum_md5_2_exp, - am_erlang, am_atom_put("md5_trap",8), 2, + am_erlang, ERTS_MAKE_AM("md5_trap"), 2, &md5_2); } diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 8b2b1a58c7..5789fa8e71 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -3129,6 +3129,9 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) else if (ERTS_IS_ATOM_STR("ets_limit",BIF_ARG_1)) { BIF_RET(make_small(erts_db_get_max_tabs())); } + else if (ERTS_IS_ATOM_STR("ets_count",BIF_ARG_1)) { + BIF_RET(make_small(erts_ets_table_count())); + } else if (ERTS_IS_ATOM_STR("atom_limit",BIF_ARG_1)) { BIF_RET(make_small(erts_get_atom_limit())); } diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 3a29f8cf56..82e31f4cab 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -322,10 +322,10 @@ erts_db_make_tid(Process *c_p, DbTableCommon *tb) /* ** The meta hash table of all NAMED ets tables */ -# define META_NAME_TAB_LOCK_CNT 16 +# define META_NAME_TAB_LOCK_CNT 256 union { erts_rwmtx_t lck; - byte _cache_line_alignment[64]; + byte align[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(erts_rwmtx_t))]; }meta_name_tab_rwlocks[META_NAME_TAB_LOCK_CNT]; static struct meta_name_tab_entry { union { @@ -450,7 +450,7 @@ save_sched_table(Process *c_p, DbTable *tb) DbTable *first; ASSERT(esdp); - esdp->ets_tables.count++; + erts_atomic_inc_nob(&esdp->ets_tables.count); erts_refc_inc(&tb->common.refc, 1); first = esdp->ets_tables.clist; @@ -474,8 +474,8 @@ remove_sched_table(ErtsSchedulerData *esdp, DbTable *tb) ASSERT(erts_get_ref_numbers_thr_id(ERTS_MAGIC_BIN_REFN(tb->common.btid)) == (Uint32) esdp->no); - ASSERT(esdp->ets_tables.count > 0); - esdp->ets_tables.count--; + ASSERT(erts_atomic_read_nob(&esdp->ets_tables.count) > 0); + erts_atomic_dec_nob(&esdp->ets_tables.count); eaydp = ERTS_SCHED_AUX_YIELD_DATA(esdp, ets_all); if (eaydp->ongoing) { @@ -1776,9 +1776,11 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) ret = make_tid(BIF_P, tb); save_sched_table(BIF_P, tb); + save_owned_table(BIF_P, tb); if (is_named && !insert_named_tab(BIF_ARG_1, tb, 0)) { tid_clear(BIF_P, tb); + delete_owned_table(BIF_P, tb); db_lock(tb,LCK_WRITE); free_heir_data(tb); @@ -1789,7 +1791,6 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) } BIF_P->flags |= F_USING_DB; /* So we can remove tb if p dies */ - save_owned_table(BIF_P, tb); #ifdef HARDDEBUG erts_fprintf(stderr, @@ -1968,8 +1969,6 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1) save_owned_table(BIF_P, tb); } - tid_clear(BIF_P, tb); - if (is_table_named(tb)) remove_named_tab(tb, 0); @@ -1978,6 +1977,7 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1) tb->common.heir = am_none; reds -= free_fixations_locked(BIF_P, tb); + tid_clear(BIF_P, tb); db_unlock(tb, LCK_WRITE); reds = free_table_continue(BIF_P, tb, reds); @@ -2445,7 +2445,7 @@ ets_all_reply(ErtsSchedulerData *esdp, ErtsEtsAllReq **reqpp, ASSERT(!*tablepp); /* Max heap size needed... */ - sz = esdp->ets_tables.count; + sz = erts_atomic_read_nob(&esdp->ets_tables.count); sz *= ERTS_MAGIC_REF_THING_SIZE + 2; sz += 3 + ERTS_REF_THING_SIZE; hfragp = new_message_buffer(sz); @@ -2529,7 +2529,8 @@ erts_handle_yielded_ets_all_request(ErtsSchedulerData *esdp, if (!eaydp->queue) return 0; /* All work completed! */ - if (yc < ERTS_ETS_ALL_TB_YCNT_START && yc > esdp->ets_tables.count) + if (yc < ERTS_ETS_ALL_TB_YCNT_START && + yc > erts_atomic_read_nob(&esdp->ets_tables.count)) return 1; /* Yield! */ eaydp->ongoing = ongoing = eaydp->queue; @@ -2608,7 +2609,6 @@ BIF_RETTYPE ets_internal_request_all_0(BIF_ALIST_0) BIF_RET(ref); } - /* ** db_slot(Db, Slot) -> [Items]. */ @@ -3490,7 +3490,11 @@ void init_db(ErtsDbSpinCount db_spin_count) db_max_tabs, ((Uint)1)<<SMALL_BITS); } - meta_name_tab_mask = (((Uint) 1)<<(bits-1)) - 1; /* At least half the size of main tab */ + /* + * We don't have ony hard limit for number of tables anymore, . + * but we use 'db_max_tabs' to determine size of name hash table. + */ + meta_name_tab_mask = (((Uint) 1)<<bits) - 1; size = sizeof(struct meta_name_tab_entry)*(meta_name_tab_mask+1); meta_name_tab = erts_db_alloc_nt(ERTS_ALC_T_DB_TABLES, size); ERTS_ETS_MISC_MEM_ADD(size); @@ -3505,27 +3509,27 @@ void init_db(ErtsDbSpinCount db_spin_count) /* Non visual BIF to trap to. */ erts_init_trap_export(&ets_select_delete_continue_exp, - am_ets, am_atom_put("delete_trap",11), 1, + am_ets, ERTS_MAKE_AM("select_delete_trap"), 1, &ets_select_delete_trap_1); /* Non visual BIF to trap to. */ erts_init_trap_export(&ets_select_count_continue_exp, - am_ets, am_atom_put("count_trap",11), 1, + am_ets, ERTS_MAKE_AM("count_trap"), 1, &ets_select_count_1); /* Non visual BIF to trap to. */ erts_init_trap_export(&ets_select_replace_continue_exp, - am_ets, am_atom_put("replace_trap",11), 1, + am_ets, ERTS_MAKE_AM("replace_trap"), 1, &ets_select_replace_1); /* Non visual BIF to trap to. */ erts_init_trap_export(&ets_select_continue_exp, - am_ets, am_atom_put("select_trap",11), 1, + am_ets, ERTS_MAKE_AM("select_trap"), 1, &ets_select_trap_1); /* Non visual BIF to trap to. */ erts_init_trap_export(&ets_delete_continue_exp, - am_ets, am_atom_put("delete_trap",11), 1, + am_ets, ERTS_MAKE_AM("delete_trap"), 1, &ets_delete_trap); } @@ -3538,7 +3542,7 @@ erts_ets_sched_spec_data_init(ErtsSchedulerData *esdp) eaydp->tab = NULL; eaydp->queue = NULL; esdp->ets_tables.clist = NULL; - esdp->ets_tables.count = 0; + erts_atomic_init_nob(&esdp->ets_tables.count, 0); } @@ -3750,7 +3754,6 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks) && give_away_to_heir(c_p, tb)) { break; } - tid_clear(c_p, tb); /* Clear all access bits. */ tb->common.status &= ~(DB_PROTECTED | DB_PUBLIC | DB_PRIVATE); tb->common.status |= DB_DELETE; @@ -3760,6 +3763,7 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks) free_heir_data(tb); reds -= free_fixations_locked(c_p, tb); + tid_clear(c_p, tb); db_unlock(tb, LCK_WRITE); state->op = FREE_OWNED_TABLE; break; @@ -3907,7 +3911,7 @@ static void free_fixations_op(DbFixation* fix, void* vctx) struct free_fixations_ctx* ctx = (struct free_fixations_ctx*) vctx; erts_aint_t diff; - ASSERT(!btid2tab(fix->tabs.btid)); + ASSERT(btid2tab(fix->tabs.btid) == ctx->tb); ASSERT(fix->counter > 0); ASSERT(ctx->tb->common.status & DB_DELETE); @@ -4154,7 +4158,7 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) else if (What == am_data) { print_table(ERTS_PRINT_STDOUT, NULL, 1, tb); ret = am_true; - } else if (What == am_atom_put("fixed",5)) { + } else if (ERTS_IS_ATOM_STR("fixed",What)) { if (IS_FIXED(tb)) ret = am_true; else @@ -4206,7 +4210,7 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) ret = am_false; } erts_mtx_unlock(&tb->common.fixlock); - } else if (What == am_atom_put("stats",5)) { + } else if (ERTS_IS_ATOM_STR("stats",What)) { if (IS_HASH_TABLE(tb->common.status)) { FloatDef f; DbHashStats stats; @@ -4346,6 +4350,18 @@ erts_db_get_max_tabs() return db_max_tabs; } +Uint erts_ets_table_count(void) +{ + Uint tb_count = 0; + Uint six; + + for (six = 0; six < erts_no_schedulers; six++) { + ErtsSchedulerData *esdp = &erts_aligned_scheduler_data[six].esd; + tb_count += erts_atomic_read_nob(&esdp->ets_tables.count); + } + return tb_count; +} + /* * For testing of meta tables only. * diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h index db86c81914..db1dec015c 100644 --- a/erts/emulator/beam/erl_db.h +++ b/erts/emulator/beam/erl_db.h @@ -45,7 +45,7 @@ typedef struct { } ErtsEtsAllYieldData; typedef struct { - Uint count; + erts_atomic_t count; DbTable *clist; } ErtsEtsTables; @@ -69,6 +69,7 @@ typedef struct { /*TT*/ Uint erts_get_ets_misc_mem_size(void); +Uint erts_ets_table_count(void); typedef struct { DbTableCommon common; @@ -93,7 +94,7 @@ union db_table { /*TT*/ }; -#define DB_DEF_MAX_TABS 2053 /* Superseeded by environment variable +#define DB_DEF_MAX_TABS 8192 /* Superseeded by environment variable "ERL_MAX_ETS_TABLES" */ #define ERL_MAX_ETS_TABLES_ENV "ERL_MAX_ETS_TABLES" diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 37d261d0df..f1d47326b4 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -2770,9 +2770,7 @@ Eterm db_format_dmc_err_info(Process *p, DMCErrInfo *ei) sys_strcpy(buff,tmp->error_string); sl = sys_strlen(buff); shp = HAlloc(p, sl * 2 + 5); - sev = (tmp->severity == dmcWarning) ? - am_atom_put("warning",7) : - am_error; + sev = (tmp->severity == dmcWarning) ? am_warning : am_error; tlist = buf_to_intlist(&shp, buff, sl, NIL); tpl = TUPLE2(shp, sev, tlist); shp += 3; @@ -5180,7 +5178,7 @@ BIF_RETTYPE match_spec_test_3(BIF_ALIST_3) { Eterm res; #ifdef DMC_DEBUG - if (BIF_ARG_3 == am_atom_put("dis",3)) { + if (BIF_ARG_3 == ERTS_MAKE_AM("dis")) { test_disassemble_next = 1; BIF_RET(am_true); } else @@ -5291,7 +5289,7 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace) erts_free(ERTS_ALC_T_DB_TMP, arr); } erts_bin_free(mps); - ret = TUPLE4(hp, am_atom_put("ok",2), res, flg, lint_res); + ret = TUPLE4(hp, am_ok, res, flg, lint_res); } return ret; } diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index 4a3671df0c..3953a4c2e9 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -1567,8 +1567,9 @@ fail: erts_port_dec_refc(pp); if (ptp) { - abort_signal_task(pp, ERTS_PROC2PORT_SIG_ABORT, - ptp->type, &ptp->u.alive.td, 0); + if (ptp->type == ERTS_PORT_TASK_PROC_SIG) + abort_signal_task(pp, ERTS_PROC2PORT_SIG_ABORT, + ptp->type, &ptp->u.alive.td, 0); port_task_free(ptp); } diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c index e9b41ad298..d6d22677e7 100644 --- a/erts/emulator/beam/erl_proc_sig_queue.c +++ b/erts/emulator/beam/erl_proc_sig_queue.c @@ -423,13 +423,13 @@ sig_enqueue_trace(Process *c_p, ErtsMessage **sigp, int op, } static void -sig_enqueue_trace_cleanup(ErtsMessage *first, ErtsSignal *sig, ErtsMessage *last) +sig_enqueue_trace_cleanup(ErtsMessage *first, ErtsSignal *sig) { ErtsMessage *tmp; /* The usual case; no tracing signals... */ - if (sig == (ErtsSignal *) first && sig == (ErtsSignal *) last) { - sig->common.next = NULL; + if (sig == (ErtsSignal *) first) { + ASSERT(sig->common.next == NULL); return; } @@ -445,6 +445,8 @@ sig_enqueue_trace_cleanup(ErtsMessage *first, ErtsSignal *sig, ErtsMessage *last case ERTS_SIG_Q_OP_TRACE_CHANGE_STATE: destroy_trace_info((ErtsSigTraceInfo *) tmp_free); break; + case ERTS_SIG_Q_OP_MONITOR: + break; /* ignore flushed pending signal */ default: ERTS_INTERNAL_ERROR("Unexpected signal op"); break; @@ -667,7 +669,7 @@ proc_queue_signal(Process *c_p, Eterm pid, ErtsSignal *sig, int op) first_last_done: sig->common.specific.next = NULL; - /* may add signals before and/or after sig */ + /* may add signals before sig */ sig_enqueue_trace(c_p, sigp, op, rp, &last_next); last->next = NULL; @@ -688,22 +690,18 @@ first_last_done: erts_proc_unlock(rp, ERTS_PROC_LOCK_MSGQ); if (res == 0) { + sig_enqueue_trace_cleanup(first, sig); if (pend_sig) { + erts_proc_sig_send_monitor_down((ErtsMonitor*)pend_sig, am_noproc); if (sig == pend_sig) { /* We did a switch, callers signal is now pending (still ok) */ ASSERT(esdp->pending_signal.sig); res = 1; } - else { - ASSERT(first == (ErtsMessage*)pend_sig); - first = first->next; - } - erts_proc_sig_send_monitor_down((ErtsMonitor*)pend_sig, am_noproc); } - sig_enqueue_trace_cleanup(first, sig, last); } - - erts_proc_notify_new_sig(rp, state, 0); + else + erts_proc_notify_new_sig(rp, state, 0); if (!is_normal_sched) erts_proc_dec_refc(rp); @@ -2725,6 +2723,9 @@ handle_process_info(Process *c_p, ErtsSigRecvTracing *tracing, Uint reds = 0; Process *rp; + ASSERT(!!is_alive == !(erts_atomic32_read_nob(&c_p->state) + & ERTS_PSFLG_EXITING)); + if (pisig->msgq_len_offset != ERTS_PROC_SIG_PI_MSGQ_LEN_IGNORE) { /* * Request requires message queue data to be updated @@ -3009,10 +3010,8 @@ erts_proc_sig_handle_incoming(Process *c_p, erts_aint32_t *statep, ERTS_HDBG_CHECK_SIGNAL_PRIV_QUEUE(c_p, 0); ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN == erts_proc_lc_my_proc_locks(c_p)); - if (local_only) - state = -1; /* can never be a valid state... */ - else { - state = erts_atomic32_read_nob(&c_p->state); + state = erts_atomic32_read_nob(&c_p->state); + if (!local_only) { if (ERTS_PSFLG_SIG_IN_Q & state) { erts_proc_lock(c_p, ERTS_PROC_LOCK_MSGQ); erts_proc_sig_fetch(c_p); @@ -3025,13 +3024,15 @@ erts_proc_sig_handle_incoming(Process *c_p, erts_aint32_t *statep, yield = 0; if (!c_p->sig_qs.cont) { - if (state == -1) - *statep = erts_atomic32_read_nob(&c_p->state); - else - *statep = state; + *statep = state; return !0; } + if (state & ERTS_PSFLG_EXITING) { + *statep = state; + return 0; + } + next_nm_sig = &c_p->sig_qs.nmsigs.next; setup_tracing_state(c_p, &tracing); diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 1478b71195..8253ec4f40 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -9186,6 +9186,7 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) internal_sched_out_proc: ERTS_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p); + ASSERT(p->scheduler_data || ERTS_SCHEDULER_IS_DIRTY(esdp)); ASSERT(actual_reds >= 0); if (reds < ERTS_PROC_MIN_CONTEXT_SWITCH_REDS_COST) @@ -9618,6 +9619,8 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) state = erts_atomic32_read_nob(&p->state); if (is_normal_sched) { + ASSERT(!p->scheduler_data); + p->scheduler_data = esdp; if ((!!(state & ERTS_PSFLGS_DIRTY_WORK)) & (!(state & ERTS_PSFLG_ACTIVE_SYS))) { /* Migrate to dirty scheduler... */ @@ -9625,8 +9628,6 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) erts_proc_unlock(p, ERTS_PROC_LOCK_STATUS); goto sched_out_proc; } - ASSERT(!p->scheduler_data); - p->scheduler_data = esdp; } else { if (!(state & ERTS_PSFLGS_DIRTY_WORK)) { diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c index 8673e029e6..d225916ac5 100644 --- a/erts/emulator/beam/erl_unicode.c +++ b/erts/emulator/beam/erl_unicode.c @@ -79,23 +79,23 @@ void erts_init_unicode(void) max_loop_limit = CONTEXT_REDS * LOOP_FACTOR; /* Non visual BIFs to trap to. */ erts_init_trap_export(&characters_to_utf8_trap_exp, - am_erlang, am_atom_put("characters_to_utf8_trap",23), 3, + am_erlang, ERTS_MAKE_AM("characters_to_utf8_trap"), 3, &characters_to_utf8_trap); erts_init_trap_export(&characters_to_list_trap_1_exp, - am_erlang, am_atom_put("characters_to_list_trap_1",25), 3, + am_erlang, ERTS_MAKE_AM("characters_to_list_trap_1"), 3, &characters_to_list_trap_1); erts_init_trap_export(&characters_to_list_trap_2_exp, - am_erlang, am_atom_put("characters_to_list_trap_2",25), 3, + am_erlang, ERTS_MAKE_AM("characters_to_list_trap_2"), 3, &characters_to_list_trap_2); erts_init_trap_export(&characters_to_list_trap_3_exp, - am_erlang, am_atom_put("characters_to_list_trap_3",25), 3, + am_erlang, ERTS_MAKE_AM("characters_to_list_trap_3"), 3, &characters_to_list_trap_3); erts_init_trap_export(&characters_to_list_trap_4_exp, - am_erlang, am_atom_put("characters_to_list_trap_4",25), 1, + am_erlang, ERTS_MAKE_AM("characters_to_list_trap_4"), 1, &characters_to_list_trap_4); c_to_b_int_trap_exportp = erts_export_put(am_unicode,am_characters_to_binary_int,2); diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index d74052d8b2..78d9d5e613 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -1946,7 +1946,7 @@ do_allocate_logger_message(Eterm gleader, ErtsMonotonicTime *ts, Eterm *pid, else sz += MAP4_SZ /* metadata map w gl w pid*/; - *ts = ERTS_MONOTONIC_TO_USEC(erts_get_monotonic_time(NULL)) + ERTS_MONOTONIC_OFFSET_USEC; + *ts = ERTS_MONOTONIC_TO_USEC(erts_get_monotonic_time(NULL) + erts_get_time_offset()); erts_bld_sint64(NULL, &sz, *ts); *bp = new_message_buffer(sz); @@ -1972,8 +1972,7 @@ static void do_send_logger_message(Eterm gl, Eterm tag, Eterm format, Eterm args break; } - md = MAP2(hp, am_emulator, am_true, - am_atom_put("tag", 3), el_tag); + md = MAP2(hp, am_emulator, am_true, ERTS_MAKE_AM("tag"), el_tag); hp += MAP2_SZ; if (is_nil(gl) && is_non_value(pid)) { @@ -1994,14 +1993,14 @@ static void do_send_logger_message(Eterm gl, Eterm tag, Eterm format, Eterm args /* no gl */ md = MAP3(hp, am_error_logger, md, - am_atom_put("gl", 2), gl, + ERTS_MAKE_AM("gl"), gl, am_time, time); hp += MAP3_SZ; pid = NIL; } else { md = MAP4(hp, am_error_logger, md, - am_atom_put("gl", 2), gl, + ERTS_MAKE_AM("gl"), gl, am_pid, pid, am_time, time); hp += MAP4_SZ; diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c index 5dadd8a5a6..145503bea7 100644 --- a/erts/emulator/sys/common/erl_mmap.c +++ b/erts/emulator/sys/common/erl_mmap.c @@ -2514,8 +2514,8 @@ Eterm erts_mmap_debug_info(Process* p) sizeof(values)/sizeof(*values), tags, values); - sa_list = TUPLE2(hp, am_atom_put("sa_free_segs",12), sa_list); hp+=3; - sua_list = TUPLE2(hp, am_atom_put("sua_free_segs",13), sua_list); hp+=3; + sa_list = TUPLE2(hp, ERTS_MAKE_AM("sa_free_segs"), sa_list); hp+=3; + sua_list = TUPLE2(hp, ERTS_MAKE_AM("sua_free_segs"), sua_list); hp+=3; list = CONS(hp, sua_list, list); hp+=2; list = CONS(hp, sa_list, list); hp+=2; diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl index fdf4aab24d..7309908337 100644 --- a/erts/emulator/test/system_info_SUITE.erl +++ b/erts/emulator/test/system_info_SUITE.erl @@ -37,6 +37,7 @@ -export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1, wordsize/1, memory/1, ets_limit/1, atom_limit/1, + ets_count/1, atom_count/1]). suite() -> @@ -45,6 +46,7 @@ suite() -> all() -> [process_count, system_version, misc_smoke_tests, + ets_count, heap_size, wordsize, memory, ets_limit, atom_limit, atom_count]. %%% @@ -478,6 +480,21 @@ get_node_name(Config) -> ++ "-" ++ integer_to_list(erlang:unique_integer([positive]))). +ets_count(Config) when is_list(Config) -> + [ets_count_do([Type | Named]) + || Type <- [set, bag, duplicate_bag, ordered_set], + Named <- [[named_table], []] + ], + ok. + +ets_count_do(Opts) -> + Before = erlang:system_info(ets_count), + T = ets:new(?MODULE, Opts), + After = erlang:system_info(ets_count), + After = Before + 1, + ets:delete(T), + Before = erlang:system_info(ets_count). + %% Verify system_info(ets_limit) reflects max ETS table settings. ets_limit(Config0) when is_list(Config0) -> diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c index d739d21f12..c84e63ad7c 100644 --- a/erts/etc/common/escript.c +++ b/erts/etc/common/escript.c @@ -139,15 +139,6 @@ get_env(char *key) } static void -free_env_val(char *value) -{ -#ifdef __WIN32__ - if (value) - efree(value); -#endif -} - -static void set_env(char *key, char *value) { #ifdef __WIN32__ @@ -422,7 +413,6 @@ main(int argc, char** argv) int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; - char* env; char* basename; char* def_emu_lookup_path; char scriptname[PMAX]; @@ -504,7 +494,7 @@ main(int argc, char** argv) } /* Determine path to emulator */ - emulator = env = get_env("ESCRIPT_EMULATOR"); + emulator = get_env("ESCRIPT_EMULATOR"); if (emulator == NULL) { emulator = get_default_emulator(def_emu_lookup_path); @@ -518,7 +508,6 @@ main(int argc, char** argv) */ PUSH(emulator); - free_env_val(env); PUSH("+B"); PUSH2("-boot", "no_dot_erlang"); diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in index 39e378193a..5b89621733 100644 --- a/erts/etc/unix/etp-commands.in +++ b/erts/etc/unix/etp-commands.in @@ -1346,7 +1346,6 @@ define etp-sigq-int else if $etp_sig_save_last && *$etp_sig_save_last == $etp_sig printf " %% <== SAVED_LAST" - else end end if $etp_sig_next diff --git a/erts/lib_src/Makefile.in b/erts/lib_src/Makefile.in index 48660f7c71..dfaf664a18 100644 --- a/erts/lib_src/Makefile.in +++ b/erts/lib_src/Makefile.in @@ -334,7 +334,7 @@ ETHREAD_LIB= endif -ifneq ($(CREATE_DIRS),) +ifneq ($(strip $(CREATE_DIRS)),) _create_dirs := $(shell mkdir -p $(CREATE_DIRS)) endif diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam Binary files differindex 52f4c686a9..99f11495a5 100644 --- a/erts/preloaded/ebin/erlang.beam +++ b/erts/preloaded/ebin/erlang.beam diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 3a42e841e2..f4f31b1e4b 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -3778,8 +3778,8 @@ blocks_size([], Acc) -> Acc. get_fix_proc([{ProcType, A1, U1}| Rest], {A0, U0}) when ProcType == proc; - ProcType == monitor_sh; - ProcType == nlink_sh; + ProcType == monitor; + ProcType == link; ProcType == msg_ref; ProcType == ll_ptimer; ProcType == hl_ptimer; @@ -3903,7 +3903,6 @@ aa_mem_data(#memory{processes = Proc, processes_used = ProcU, system = Sys} = Mem, [{ProcData, Sz} | Rest]) when ProcData == bif_timer; - ProcData == link_lh; ProcData == process_table -> aa_mem_data(Mem#memory{processes = Proc+Sz, processes_used = ProcU+Sz, diff --git a/erts/preloaded/src/erts_code_purger.erl b/erts/preloaded/src/erts_code_purger.erl index fd214228c7..c41532ed87 100644 --- a/erts/preloaded/src/erts_code_purger.erl +++ b/erts/preloaded/src/erts_code_purger.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2016. All Rights Reserved. +%% Copyright Ericsson AB 2016-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ -export([start/0, purge/1, soft_purge/1, pending_purge_lambda/3, finish_after_on_load/2]). --spec start() -> term(). +-spec start() -> no_return(). start() -> register(erts_code_purger, self()), process_flag(trap_exit, true), diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl index a4ef42204d..6f53e67901 100644 --- a/erts/preloaded/src/zlib.erl +++ b/erts/preloaded/src/zlib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -87,7 +87,7 @@ %%------------------------------------------------------------------------ %% Public data types. --type zstream() :: term(). +-type zstream() :: reference(). -type zflush() :: 'none' | 'sync' | 'full' | 'finish'. -type zlevel() :: @@ -102,11 +102,11 @@ -type zmethod() :: 'deflated'. -record(zlib_opts, { - stream :: zstream(), - method :: term(), - input_chunk_size :: integer(), - output_chunk_size :: integer(), - flush :: integer() + stream :: zstream() | 'undefined', + method :: function(), + input_chunk_size :: pos_integer(), + output_chunk_size :: pos_integer(), + flush :: non_neg_integer() }). %%------------------------------------------------------------------------ @@ -168,7 +168,7 @@ deflateInit_nif(_Z, _Level, _Method, _WindowBits, _MemLevel, _Strategy) -> -spec deflateSetDictionary(Z, Dictionary) -> Adler32 when Z :: zstream(), Dictionary :: iodata(), - Adler32 :: integer(). + Adler32 :: non_neg_integer(). deflateSetDictionary(Z, Dictionary) -> deflateSetDictionary_nif(Z, Dictionary). deflateSetDictionary_nif(_Z, _Dictionary) -> @@ -295,7 +295,7 @@ inflate(Z, Data) -> Options :: list({exception_on_need_dict, boolean()}), Decompressed :: iolist() | {need_dictionary, - Adler32 :: integer(), + Adler32 :: non_neg_integer(), Output :: iolist()}. inflate(Z, Data, Options) -> enqueue_input(Z, Data), @@ -357,7 +357,7 @@ exception_on_need_dict(Z, Output) when is_list(Output); is_binary(Output) -> Result :: {continue, Output :: iolist()} | {finished, Output :: iolist()} | {need_dictionary, - Adler32 :: integer(), + Adler32 :: non_neg_integer(), Output :: iolist()}. safeInflate(Z, Data) -> enqueue_input(Z, Data), @@ -389,7 +389,7 @@ getBufSize_nif(_Z) -> -spec crc32(Z) -> CRC when Z :: zstream(), - CRC :: integer(). + CRC :: non_neg_integer(). crc32(Z) -> crc32_nif(Z). crc32_nif(_Z) -> @@ -398,7 +398,7 @@ crc32_nif(_Z) -> -spec crc32(Z, Data) -> CRC when Z :: zstream(), Data :: iodata(), - CRC :: integer(). + CRC :: non_neg_integer(). crc32(Z, Data) when is_reference(Z) -> erlang:crc32(Data); crc32(_Z, _Data) -> @@ -406,9 +406,9 @@ crc32(_Z, _Data) -> -spec crc32(Z, PrevCRC, Data) -> CRC when Z :: zstream(), - PrevCRC :: integer(), + PrevCRC :: non_neg_integer(), Data :: iodata(), - CRC :: integer(). + CRC :: non_neg_integer(). crc32(Z, CRC, Data) when is_reference(Z) -> erlang:crc32(CRC, Data); crc32(_Z, _CRC, _Data) -> @@ -416,10 +416,10 @@ crc32(_Z, _CRC, _Data) -> -spec crc32_combine(Z, CRC1, CRC2, Size2) -> CRC when Z :: zstream(), - CRC :: integer(), - CRC1 :: integer(), - CRC2 :: integer(), - Size2 :: integer(). + CRC :: non_neg_integer(), + CRC1 :: non_neg_integer(), + CRC2 :: non_neg_integer(), + Size2 :: non_neg_integer(). crc32_combine(Z, CRC1, CRC2, Size2) when is_reference(Z) -> erlang:crc32_combine(CRC1, CRC2, Size2); crc32_combine(_Z, _CRC1, _CRC2, _Size2) -> @@ -428,7 +428,7 @@ crc32_combine(_Z, _CRC1, _CRC2, _Size2) -> -spec adler32(Z, Data) -> CheckSum when Z :: zstream(), Data :: iodata(), - CheckSum :: integer(). + CheckSum :: non_neg_integer(). adler32(Z, Data) when is_reference(Z) -> erlang:adler32(Data); adler32(_Z, _Data) -> @@ -436,9 +436,9 @@ adler32(_Z, _Data) -> -spec adler32(Z, PrevAdler, Data) -> CheckSum when Z :: zstream(), - PrevAdler :: integer(), + PrevAdler :: non_neg_integer(), Data :: iodata(), - CheckSum :: integer(). + CheckSum :: non_neg_integer(). adler32(Z, Adler, Data) when is_reference(Z) -> erlang:adler32(Adler, Data); adler32(_Z, _Adler, _Data) -> @@ -446,10 +446,10 @@ adler32(_Z, _Adler, _Data) -> -spec adler32_combine(Z, Adler1, Adler2, Size2) -> Adler when Z :: zstream(), - Adler :: integer(), - Adler1 :: integer(), - Adler2 :: integer(), - Size2 :: integer(). + Adler :: non_neg_integer(), + Adler1 :: non_neg_integer(), + Adler2 :: non_neg_integer(), + Size2 :: non_neg_integer(). adler32_combine(Z, Adler1, Adler2, Size2) when is_reference(Z) -> erlang:adler32_combine(Adler1, Adler2, Size2); adler32_combine(_Z, _Adler1, _Adler2, _Size2) -> diff --git a/erts/vsn.mk b/erts/vsn.mk index 6a966f17b8..687c62343e 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% # -VSN = 10.0 +VSN = 9.3.2 # Port number 4365 in 4.2 # Port number 4366 in 4.3 diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml index 10b0e4c45f..bb15c9ff5f 100644 --- a/lib/asn1/doc/src/notes.xml +++ b/lib/asn1/doc/src/notes.xml @@ -32,21 +32,6 @@ <p>This document describes the changes made to the asn1 application.</p> -<section><title>Asn1 5.0.6</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Update to use the new string api instead of the old.</p> - <p> - Own Id: OTP-15036</p> - </item> - </list> - </section> - -</section> - <section><title>Asn1 5.0.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk index 30cbca3773..39dfe8f4fb 100644 --- a/lib/asn1/vsn.mk +++ b/lib/asn1/vsn.mk @@ -1 +1 @@ -ASN1_VSN = 5.0.6 +ASN1_VSN = 5.0.5 diff --git a/lib/common_test/doc/src/ct_hooks_chapter.xml b/lib/common_test/doc/src/ct_hooks_chapter.xml index 3957c0f4a5..ea4b67be08 100644 --- a/lib/common_test/doc/src/ct_hooks_chapter.xml +++ b/lib/common_test/doc/src/ct_hooks_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2011</year><year>2017</year> + <year>2011</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -379,7 +379,7 @@ (in Kernel): </p> <code> - %%% @doc Common Test Example Common Test Hook module. + %%% Common Test Example Common Test Hook module. -module(example_cth). %% Callbacks @@ -408,51 +408,51 @@ -record(state, { file_handle, total, suite_total, ts, tcs, data }). - %% @doc Return a unique id for this CTH. + %% Return a unique id for this CTH. id(Opts) -> proplists:get_value(filename, Opts, "/tmp/file.log"). - %% @doc Always called before any other callback function. Use this to initiate + %% Always called before any other callback function. Use this to initiate %% any common state. init(Id, Opts) -> {ok,D} = file:open(Id,[write]), {ok, #state{ file_handle = D, total = 0, data = [] }}. - %% @doc Called before init_per_suite is called. + %% Called before init_per_suite is called. pre_init_per_suite(Suite,Config,State) -> {Config, State#state{ suite_total = 0, tcs = [] }}. - %% @doc Called after init_per_suite. + %% Called after init_per_suite. post_init_per_suite(Suite,Config,Return,State) -> {Return, State}. - %% @doc Called before end_per_suite. + %% Called before end_per_suite. pre_end_per_suite(Suite,Config,State) -> {Config, State}. - %% @doc Called after end_per_suite. + %% Called after end_per_suite. post_end_per_suite(Suite,Config,Return,State) -> Data = {suites, Suite, State#state.suite_total, lists:reverse(State#state.tcs)}, {Return, State#state{ data = [Data | State#state.data] , total = State#state.total + State#state.suite_total } }. - %% @doc Called before each init_per_group. + %% Called before each init_per_group. pre_init_per_group(Suite,Group,Config,State) -> {Config, State}. - %% @doc Called after each init_per_group. + %% Called after each init_per_group. post_init_per_group(Suite,Group,Config,Return,State) -> {Return, State}. - %% @doc Called before each end_per_group. + %% Called before each end_per_group. pre_end_per_group(Suite,Group,Config,State) -> {Config, State}. - %% @doc Called after each end_per_group. + %% Called after each end_per_group. post_end_per_group(Suite,Group,Config,Return,State) -> {Return, State}. - %% @doc Called before each init_per_testcase. + %% Called before each init_per_testcase. pre_init_per_testcase(Suite,TC,Config,State) -> {Config, State#state{ ts = now(), total = State#state.suite_total + 1 } }. @@ -460,26 +460,26 @@ post_init_per_testcase(Suite,TC,Config,Return,State) -> {Return, State} -%% @doc Called before each end_per_testcase (immediately after the test case). +%% Called before each end_per_testcase (immediately after the test case). pre_end_per_testcase(Suite,TC,Config,State) -> {Config, State}. - %% @doc Called after each end_per_testcase. + %% Called after each end_per_testcase. post_end_per_testcase(Suite,TC,Config,Return,State) -> TCInfo = {testcase, Suite, TC, Return, timer:now_diff(now(), State#state.ts)}, {Return, State#state{ ts = undefined, tcs = [TCInfo | State#state.tcs] } }. - %% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group, + %% Called after post_init_per_suite, post_end_per_suite, post_init_per_group, %% post_end_per_group and post_end_per_testcase if the suite, group or test case failed. on_tc_fail(Suite, TC, Reason, State) -> State. - %% @doc Called when a test case is skipped by either user action + %% Called when a test case is skipped by either user action %% or due to an init function failing. on_tc_skip(Suite, TC, Reason, State) -> State. - %% @doc Called when the scope of the CTH is done + %% Called when the scope of the CTH is done terminate(State) -> io:format(State#state.file_handle, "~p.~n", [{test_run, State#state.total, State#state.data}]), diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml index c5df590b3f..7e909b24cd 100644 --- a/lib/common_test/doc/src/notes.xml +++ b/lib/common_test/doc/src/notes.xml @@ -33,21 +33,6 @@ <file>notes.xml</file> </header> -<section><title>Common_Test 1.16</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Use uri_string module instead of http_uri.</p> - <p> - Own Id: OTP-14902</p> - </item> - </list> - </section> - -</section> - <section><title>Common_Test 1.15.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl index 14a9ec07cf..778ea2e9e2 100644 --- a/lib/common_test/src/ct.erl +++ b/lib/common_test/src/ct.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,38 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Main user interface for the Common Test framework. -%%% -%%% <p> This module implements the command line interface for running -%%% tests and some basic functions for common test case issues -%%% such as configuration and logging. </p> -%%% -%%% <p><strong>Test Suite Support Macros</strong></p> -%%% -%%% <p>The <c>config</c> macro is defined in <c>ct.hrl</c>. This -%%% macro should be used to retrieve information from the -%%% <c>Config</c> variable sent to all test cases. It is used with two -%%% arguments, where the first is the name of the configuration -%%% variable you wish to retrieve, and the second is the <c>Config</c> -%%% variable supplied to the test case.</p> -%%% -%%% <p>Possible configuration variables include:</p> -%%% <ul> -%%% <li><c>data_dir</c> - Data file directory.</li> -%%% <li><c>priv_dir</c> - Scratch file directory.</li> -%%% <li>Whatever added by <c>init_per_suite/1</c> or -%%% <c>init_per_testcase/2</c> in the test suite.</li> -%%% </ul> - -%%% @type var_name() = atom(). A variable name which is specified when -%%% <c>ct:require/2</c> is called, -%%% e.g. <c>ct:require(mynodename,{node,[telnet]})</c> -%%% -%%% @type target_name() = var_name(). The name of a target. -%%% -%%% @type handle() = ct_gen_conn:handle() | term(). The identity of a -%%% specific connection. - -module(ct). -include("ct.hrl"). @@ -121,209 +89,34 @@ %%---------------------------------------------------------------------- - -%%%----------------------------------------------------------------- -%%% @spec install(Opts) -> ok | {error,Reason} -%%% Opts = [Opt] -%%% Opt = {config,ConfigFiles} | {event_handler,Modules} | -%%% {decrypt,KeyOrFile} -%%% ConfigFiles = [ConfigFile] -%%% ConfigFile = string() -%%% Modules = [atom()] -%%% KeyOrFile = {key,Key} | {file,KeyFile} -%%% Key = string() -%%% KeyFile = string() -%%% @doc Install config files and event handlers. -%%% -%%% <p>Run this function once before first test.</p> -%%% -%%% <p>Example:<br/> -%%% <c>install([{config,["config_node.ctc","config_user.ctc"]}])</c>.</p> -%%% -%%% <p>Note that this function is automatically run by the -%%% <c>ct_run</c> program.</p> install(Opts) -> ct_run:install(Opts). -%%%----------------------------------------------------------------- -%%% @spec run(TestDir,Suite,Cases) -> Result -%%% TestDir = string() -%%% Suite = atom() -%%% Cases = atom() | [atom()] -%%% Result = [TestResult] | {error,Reason} -%%% -%%% @doc Run the given test case(s). -%%% -%%% <p>Requires that <c>ct:install/1</c> has been run first.</p> -%%% -%%% <p>Suites (*_SUITE.erl) files must be stored in -%%% <c>TestDir</c> or <c>TestDir/test</c>. All suites -%%% will be compiled when test is run.</p> run(TestDir,Suite,Cases) -> ct_run:run(TestDir,Suite,Cases). -%%%----------------------------------------------------------------- -%%% @spec run(TestDir,Suite) -> Result -%%% -%%% @doc Run all test cases in the given suite. -%%% @see run/3. run(TestDir,Suite) -> ct_run:run(TestDir,Suite). -%%%----------------------------------------------------------------- -%%% @spec run(TestDirs) -> Result -%%% TestDirs = TestDir | [TestDir] -%%% -%%% @doc Run all test cases in all suites in the given directories. -%%% @see run/3. run(TestDirs) -> ct_run:run(TestDirs). -%%%----------------------------------------------------------------- -%%% @spec run_test(Opts) -> Result -%%% Opts = [OptTuples] -%%% OptTuples = {dir,TestDirs} | {suite,Suites} | {group,Groups} | -%%% {testcase,Cases} | {spec,TestSpecs} | {join_specs,Bool} | -%%% {label,Label} | {config,CfgFiles} | {userconfig, UserConfig} | -%%% {allow_user_terms,Bool} | {logdir,LogDir} | -%%% {silent_connections,Conns} | {stylesheet,CSSFile} | -%%% {cover,CoverSpecFile} | {cover_stop,Bool} | {step,StepOpts} | -%%% {event_handler,EventHandlers} | {include,InclDirs} | -%%% {auto_compile,Bool} | {abort_if_missing_suites,Bool} | -%%% {create_priv_dir,CreatePrivDir} | -%%% {multiply_timetraps,M} | {scale_timetraps,Bool} | -%%% {repeat,N} | {duration,DurTime} | {until,StopTime} | -%%% {force_stop,ForceStop} | {decrypt,DecryptKeyOrFile} | -%%% {refresh_logs,LogDir} | {logopts,LogOpts} | -%%% {verbosity,VLevels} | {basic_html,Bool} | -%%% {esc_chars,Bool} | {ct_hooks, CTHs} | -%%% {enable_builtin_hooks,Bool} | {release_shell,Bool} -%%% TestDirs = [string()] | string() -%%% Suites = [string()] | [atom()] | string() | atom() -%%% Cases = [atom()] | atom() -%%% Groups = GroupNameOrPath | [GroupNameOrPath] -%%% GroupNameOrPath = [atom()] | atom() | all -%%% TestSpecs = [string()] | string() -%%% Label = string() | atom() -%%% CfgFiles = [string()] | string() -%%% UserConfig = [{CallbackMod,CfgStrings}] | {CallbackMod,CfgStrings} -%%% CallbackMod = atom() -%%% CfgStrings = [string()] | string() -%%% LogDir = string() -%%% Conns = all | [atom()] -%%% CSSFile = string() -%%% CoverSpecFile = string() -%%% StepOpts = [StepOpt] | [] -%%% StepOpt = config | keep_inactive -%%% EventHandlers = EH | [EH] -%%% EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs} -%%% InitArgs = [term()] -%%% InclDirs = [string()] | string() -%%% CreatePrivDir = auto_per_run | auto_per_tc | manual_per_tc -%%% M = integer() -%%% N = integer() -%%% DurTime = string(HHMMSS) -%%% StopTime = string(YYMoMoDDHHMMSS) | string(HHMMSS) -%%% ForceStop = skip_rest | Bool -%%% DecryptKeyOrFile = {key,DecryptKey} | {file,DecryptFile} -%%% DecryptKey = string() -%%% DecryptFile = string() -%%% LogOpts = [LogOpt] -%%% LogOpt = no_nl | no_src -%%% VLevels = VLevel | [{Category,VLevel}] -%%% VLevel = integer() -%%% Category = atom() -%%% CTHs = [CTHModule | {CTHModule, CTHInitArgs}] -%%% CTHModule = atom() -%%% CTHInitArgs = term() -%%% Result = {Ok,Failed,{UserSkipped,AutoSkipped}} | TestRunnerPid | {error,Reason} -%%% Ok = integer() -%%% Failed = integer() -%%% UserSkipped = integer() -%%% AutoSkipped = integer() -%%% TestRunnerPid = pid() -%%% Reason = term() -%%% @doc <p>Run tests as specified by the combination of options in <c>Opts</c>. -%%% The options are the same as those used with the -%%% <seealso marker="ct_run#ct_run"><c>ct_run</c></seealso> program. -%%% Note that here a <c>TestDir</c> can be used to point out the path to -%%% a <c>Suite</c>. Note also that the option <c>testcase</c> -%%% corresponds to the <c>-case</c> option in the <c>ct_run</c> -%%% program. Configuration files specified in <c>Opts</c> will be -%%% installed automatically at startup.</p> -%%% <p><c>TestRunnerPid</c> is returned if <c>release_shell == true</c> -%%% (see <c>break/1</c> for details).</p> -%%% <p><c>Reason</c> indicates what type of error has been encountered.</p> run_test(Opts) -> ct_run:run_test(Opts). -%%%----------------------------------------------------------------- -%%% @spec run_testspec(TestSpec) -> Result -%%% TestSpec = [term()] -%%% Result = {Ok,Failed,{UserSkipped,AutoSkipped}} | {error,Reason} -%%% Ok = integer() -%%% Failed = integer() -%%% UserSkipped = integer() -%%% AutoSkipped = integer() -%%% Reason = term() -%%% @doc Run test specified by <c>TestSpec</c>. The terms are -%%% the same as those used in test specification files. -%%% <p><c>Reason</c> indicates what type of error has been encountered.</p> run_testspec(TestSpec) -> ct_run:run_testspec(TestSpec). -%%%----------------------------------------------------------------- -%%% @spec step(TestDir,Suite,Case) -> Result -%%% Case = atom() -%%% -%%% @doc Step through a test case with the debugger. -%%% @see run/3 step(TestDir,Suite,Case) -> ct_run:step(TestDir,Suite,Case). -%%%----------------------------------------------------------------- -%%% @spec step(TestDir,Suite,Case,Opts) -> Result -%%% Case = atom() -%%% Opts = [Opt] | [] -%%% Opt = config | keep_inactive -%%% -%%% @doc Step through a test case with the debugger. If the -%%% <c>config</c> option has been given, breakpoints will -%%% be set also on the configuration functions in <c>Suite</c>. -%%% @see run/3 step(TestDir,Suite,Case,Opts) -> ct_run:step(TestDir,Suite,Case,Opts). -%%%----------------------------------------------------------------- -%%% @spec start_interactive() -> ok -%%% -%%% @doc Start CT in interactive mode. -%%% -%%% <p>From this mode all test case support functions can be executed -%%% directly from the erlang shell. The interactive mode can also be -%%% started from the OS command line with <c>ct_run -shell -%%% [-config File...]</c>.</p> -%%% -%%% <p>If any functions using "required config data" (e.g. telnet or -%%% ftp functions) are to be called from the erlang shell, config data -%%% must first be required with <c>ct:require/2</c>.</p> -%%% -%%% <p>Example:<br/> -%%% <c>> ct:require(unix_telnet, unix).</c><br/> -%%% <c>ok</c><br/> -%%% <c>> ct_telnet:open(unix_telnet).</c><br/> -%%% <c>{ok,<0.105.0>}</c><br/> -%%% <c>> ct_telnet:cmd(unix_telnet, "ls .").</c><br/> -%%% <c>{ok,["ls","file1 ...",...]}</c></p> start_interactive() -> _ = ct_util:start(interactive), ok. -%%%----------------------------------------------------------------- -%%% @spec stop_interactive() -> ok -%%% -%%% @doc Exit the interactive mode. -%%% @see start_interactive/0 stop_interactive() -> ct_util:stop(normal), ok. @@ -332,181 +125,24 @@ stop_interactive() -> %%% MISC INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%----------------------------------------------------------------- -%%% @spec require(Required) -> ok | {error,Reason} -%%% Required = Key | {Key,SubKeys} | {Key,SubKey,SubKeys} -%%% Key = atom() -%%% SubKeys = SubKey | [SubKey] -%%% SubKey = atom() -%%% -%%% @doc Check if the required configuration is available. It is possible -%%% to specify arbitrarily deep tuples as <c>Required</c>. Note that it is -%%% only the last element of the tuple which can be a list of <c>SubKey</c>s. -%%% -%%% <p>Example 1: require the variable <c>myvar</c>:</p> -%%% <pre>ok = ct:require(myvar).</pre> -%%% -%%% <p>In this case the config file must at least contain:</p> -%%% <pre>{myvar,Value}.</pre> -%%% -%%% <p>Example 2: require the key <c>myvar</c> with -%%% subkeys <c>sub1</c> and <c>sub2</c>:</p> -%%% <pre>ok = ct:require({myvar,[sub1,sub2]}).</pre> -%%% -%%% <p>In this case the config file must at least contain:</p> -%%% <pre>{myvar,[{sub1,Value},{sub2,Value}]}.</pre> -%%% -%%% <p>Example 3: require the key <c>myvar</c> with -%%% subkey <c>sub1</c> with <c>subsub1</c>:</p> -%%% <pre>ok = ct:require({myvar,sub1,sub2}).</pre> -%%% -%%% <p>In this case the config file must at least contain:</p> -%%% <pre>{myvar,[{sub1,[{sub2,Value}]}]}.</pre> -%%% -%%% @see require/2 -%%% @see get_config/1 -%%% @see get_config/2 -%%% @see get_config/3 require(Required) -> ct_config:require(Required). -%%%----------------------------------------------------------------- -%%% @spec require(Name,Required) -> ok | {error,Reason} -%%% Name = atom() -%%% Required = Key | {Key,SubKey} | {Key,SubKey,SubKey} -%%% SubKey = Key -%%% Key = atom() -%%% -%%% @doc Check if the required configuration is available, and give it -%%% a name. The semantics for <c>Required</c> is the same as in -%%% <c>required/1</c> except that it is not possible to specify a list -%%% of <c>SubKey</c>s. -%%% -%%% <p>If the requested data is available, the sub entry will be -%%% associated with <c>Name</c> so that the value of the element -%%% can be read with <c>get_config/1,2</c> provided -%%% <c>Name</c> instead of the whole <c>Required</c> term.</p> -%%% -%%% <p>Example: Require one node with a telnet connection and an -%%% ftp connection. Name the node <c>a</c>: -%%% <pre>ok = ct:require(a,{machine,node}).</pre> -%%% All references to this node may then use the node name. -%%% E.g. you can fetch a file over ftp like this:</p> -%%% <pre>ok = ct:ftp_get(a,RemoteFile,LocalFile).</pre> -%%% -%%% <p>For this to work, the config file must at least contain:</p> -%%% <pre>{machine,[{node,[{telnet,IpAddr},{ftp,IpAddr}]}]}.</pre> -%%% -%%% <note><p>The behaviour of this function changed radically in common_test -%%% 1.6.2. In order too keep some backwards compatability it is still possible -%%% to do: <br/><c>ct:require(a,{node,[telnet,ftp]}).</c><br/> -%%% This will associate the name <c>a</c> with the top level <c>node</c> entry. -%%% For this to work, the config file must at least contain:<br/> -%%% <c>{node,[{telnet,IpAddr},{ftp,IpAddr}]}.</c></p></note> -%%% -%%% @see require/1 -%%% @see get_config/1 -%%% @see get_config/2 -%%% @see get_config/3 require(Name,Required) -> ct_config:require(Name,Required). -%%%----------------------------------------------------------------- -%%% @spec get_config(Required) -> Value -%%% @equiv get_config(Required,undefined,[]) get_config(Required) -> ct_config:get_config(Required,undefined,[]). -%%%----------------------------------------------------------------- -%%% @spec get_config(Required,Default) -> Value -%%% @equiv get_config(Required,Default,[]) get_config(Required,Default) -> ct_config:get_config(Required,Default,[]). -%%%----------------------------------------------------------------- -%%% @spec get_config(Required,Default,Opts) -> ValueOrElement -%%% Required = KeyOrName | {KeyOrName,SubKey} | {KeyOrName,SubKey,SubKey} -%%% KeyOrName = atom() -%%% SubKey = atom() -%%% Default = term() -%%% Opts = [Opt] | [] -%%% Opt = element | all -%%% ValueOrElement = term() | Default -%%% -%%% @doc Read config data values. -%%% -%%% <p>This function returns the matching value(s) or config element(s), -%%% given a config variable key or its associated name -%%% (if one has been specified with <c>require/2</c> or a -%%% require statement).</p> -%%% -%%% <p>Example, given the following config file:</p> -%%% <pre> -%%% {unix,[{telnet,IpAddr}, -%%% {user,[{username,Username}, -%%% {password,Password}]}]}.</pre> -%%% <p><c>ct:get_config(unix,Default) -> -%%% [{telnet,IpAddr}, -%%% {user, [{username,Username}, -%%% {password,Password}]}]</c><br/> -%%% <c>ct:get_config({unix,telnet},Default) -> IpAddr</c><br/> -%%% <c>ct:get_config({unix,user,username},Default) -> Username</c><br/> -%%% <c>ct:get_config({unix,ftp},Default) -> Default</c><br/> -%%% <c>ct:get_config(unknownkey,Default) -> Default</c></p> -%%% -%%% <p>If a config variable key has been associated with a name (by -%%% means of <c>require/2</c> or a require statement), the name -%%% may be used instead of the key to read the value:</p> -%%% -%%% <p><c>ct:require(myuser,{unix,user}) -> ok.</c><br/> -%%% <c>ct:get_config(myuser,Default) -> -%%% [{username,Username}, -%%% {password,Password}]</c></p> -%%% -%%% <p>If a config variable is defined in multiple files and you want to -%%% access all possible values, use the <c>all</c> option. The -%%% values will be returned in a list and the order of the elements -%%% corresponds to the order that the config files were specified at -%%% startup.</p> -%%% -%%% <p>If you want config elements (key-value tuples) returned as result -%%% instead of values, use the <c>element</c> option. -%%% The returned elements will then be on the form <c>{Required,Value}</c></p> -%%% -%%% @see get_config/1 -%%% @see get_config/2 -%%% @see require/1 -%%% @see require/2 get_config(Required,Default,Opts) -> ct_config:get_config(Required,Default,Opts). -%%%----------------------------------------------------------------- -%%% @spec reload_config(Required) -> ValueOrElement -%%% Required = KeyOrName | {KeyOrName,SubKey} | {KeyOrName,SubKey,SubKey} -%%% KeyOrName = atom() -%%% SubKey = atom() -%%% ValueOrElement = term() -%%% -%%% @doc Reload config file which contains specified configuration key. -%%% -%%% <p>This function performs updating of the configuration data from which the -%%% given configuration variable was read, and returns the (possibly) new -%%% value of this variable.</p> -%%% <p>Note that if some variables were present in the configuration but are not loaded -%%% using this function, they will be removed from the configuration table together -%%% with their aliases.</p> -%%% reload_config(Required)-> ct_config:reload_config(Required). -%%%----------------------------------------------------------------- -%%% @spec get_testspec_terms() -> TestSpecTerms | undefined -%%% TestSpecTerms = [{Tag,Value}] -%%% Value = [term()] -%%% -%%% @doc Get a list of all test specification terms used to -%%% configure and run this test. -%%% get_testspec_terms() -> case ct_util:get_testdata(testspec) of undefined -> @@ -515,25 +151,6 @@ get_testspec_terms() -> ct_testspec:testspec_rec2list(CurrSpecRec) end. -%%%----------------------------------------------------------------- -%%% @spec get_testspec_terms(Tags) -> TestSpecTerms | undefined -%%% Tags = [Tag] | Tag -%%% Tag = atom() -%%% TestSpecTerms = [{Tag,Value}] | {Tag,Value} -%%% Value = [{Node,term()}] | [term()] -%%% Node = atom() -%%% -%%% @doc Read one or more terms from the test specification used -%%% to configure and run this test. Tag is any valid test specification -%%% tag, such as e.g. <c>label</c>, <c>config</c>, <c>logdir</c>. -%%% User specific terms are also available to read if the -%%% <c>allow_user_terms</c> option has been set. Note that all value tuples -%%% returned, except user terms, will have the node name as first element. -%%% Note also that in order to read test terms, use <c>Tag = tests</c> -%%% (rather than <c>suites</c>, <c>groups</c> or <c>cases</c>). Value is -%%% then the list of *all* tests on the form: -%%% <c>[{Node,Dir,[{TestSpec,GroupsAndCases1},...]},...], where -%%% GroupsAndCases = [{Group,[Case]}] | [Case]</c>. get_testspec_terms(Tags) -> case ct_util:get_testdata(testspec) of undefined -> @@ -542,24 +159,9 @@ get_testspec_terms(Tags) -> ct_testspec:testspec_rec2list(Tags, CurrSpecRec) end. - -%%%----------------------------------------------------------------- -%%% @spec escape_chars(IoList1) -> IoList2 | {error,Reason} -%%% IoList1 = iolist() -%%% IoList2 = iolist() -%%% -%%% @doc Escape special characters to be printed in html log -%%% escape_chars(IoList) -> ct_logs:escape_chars(IoList). -%%%----------------------------------------------------------------- -%%% @spec escape_chars(Format, Args) -> IoList | {error,Reason} -%%% Format = string() -%%% Args = list() -%%% -%%% @doc Escape special characters to be printed in html log -%%% escape_chars(Format, Args) -> try io_lib:format(Format, Args) of IoList -> @@ -569,17 +171,9 @@ escape_chars(Format, Args) -> {error,Reason} end. -%%%----------------------------------------------------------------- -%%% @spec log(Format) -> ok -%%% @equiv log(default,50,Format,[],[]) log(Format) -> log(default,?STD_IMPORTANCE,Format,[],[]). -%%%----------------------------------------------------------------- -%%% @spec log(X1,X2) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Format | Args -%%% @equiv log(Category,Importance,Format,Args,[]) log(X1,X2) -> {Category,Importance,Format,Args} = if is_atom(X1) -> {X1,?STD_IMPORTANCE,X2,[]}; @@ -588,12 +182,6 @@ log(X1,X2) -> end, log(Category,Importance,Format,Args,[]). -%%%----------------------------------------------------------------- -%%% @spec log(X1,X2,X3) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Importance | Format | Args -%%% X3 = Format | Args | Opts -%%% @equiv log(Category,Importance,Format,Args,Opts) log(X1,X2,X3) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[],[]}; @@ -603,13 +191,6 @@ log(X1,X2,X3) -> end, log(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec log(X1,X2,X3,X4) -> ok -%%% X1 = Category | Importance -%%% X2 = Importance | Format -%%% X3 = Format | Args -%%% X4 = Args | Opts -%%% @equiv log(Category,Importance,Format,Args,Opts) log(X1,X2,X3,X4) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,X4,[]}; @@ -618,40 +199,12 @@ log(X1,X2,X3,X4) -> end, log(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec log(Category,Importance,Format,Args,Opts) -> ok -%%% Category = atom() -%%% Importance = integer() -%%% Format = string() -%%% Args = list() -%%% Opts = [Opt] -%%% Opt = {heading,string()} | esc_chars | no_css -%%% -%%% @doc Printout from a test case to the log file. -%%% -%%% <p>This function is meant for printing a string directly from a -%%% test case to the test case log file.</p> -%%% -%%% <p>Default <c>Category</c> is <c>default</c>, -%%% default <c>Importance</c> is <c>?STD_IMPORTANCE</c>, -%%% and default value for <c>Args</c> is <c>[]</c>.</p> -%%% <p>Please see the User's Guide for details on <c>Category</c> -%%% and <c>Importance</c>.</p> log(Category,Importance,Format,Args,Opts) -> ct_logs:tc_log(Category,Importance,Format,Args,Opts). - -%%%----------------------------------------------------------------- -%%% @spec print(Format) -> ok -%%% @equiv print(default,50,Format,[],[]) print(Format) -> print(default,?STD_IMPORTANCE,Format,[],[]). -%%%----------------------------------------------------------------- -%%% @spec print(X1,X2) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Format | Args -%%% @equiv print(Category,Importance,Format,Args,[]) print(X1,X2) -> {Category,Importance,Format,Args} = if is_atom(X1) -> {X1,?STD_IMPORTANCE,X2,[]}; @@ -660,12 +213,6 @@ print(X1,X2) -> end, print(Category,Importance,Format,Args,[]). -%%%----------------------------------------------------------------- -%%% @spec print(X1,X2,X3) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Importance | Format | Args -%%% X3 = Format | Args | Opts -%%% @equiv print(Category,Importance,Format,Args,Opts) print(X1,X2,X3) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[],[]}; @@ -675,13 +222,6 @@ print(X1,X2,X3) -> end, print(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec print(X1,X2,X3,X4) -> ok -%%% X1 = Category | Importance -%%% X2 = Importance | Format -%%% X3 = Format | Args -%%% X4 = Args | Opts -%%% @equiv print(Category,Importance,Format,Args,Opts) print(X1,X2,X3,X4) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,X4,[]}; @@ -690,40 +230,12 @@ print(X1,X2,X3,X4) -> end, print(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec print(Category,Importance,Format,Args,Opts) -> ok -%%% Category = atom() -%%% Importance = integer() -%%% Format = string() -%%% Args = list() -%%% Opts = [Opt] -%%% Opt = {heading,string()} -%%% -%%% @doc Printout from a test case to the console. -%%% -%%% <p>This function is meant for printing a string from a test case -%%% to the console.</p> -%%% -%%% <p>Default <c>Category</c> is <c>default</c>, -%%% default <c>Importance</c> is <c>?STD_IMPORTANCE</c>, -%%% and default value for <c>Args</c> is <c>[]</c>.</p> -%%% <p>Please see the User's Guide for details on <c>Category</c> -%%% and <c>Importance</c>.</p> print(Category,Importance,Format,Args,Opts) -> ct_logs:tc_print(Category,Importance,Format,Args,Opts). - -%%%----------------------------------------------------------------- -%%% @spec pal(Format) -> ok -%%% @equiv pal(default,50,Format,[],[]) pal(Format) -> pal(default,?STD_IMPORTANCE,Format,[]). -%%%----------------------------------------------------------------- -%%% @spec pal(X1,X2) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Format | Args -%%% @equiv pal(Category,Importance,Format,Args,[]) pal(X1,X2) -> {Category,Importance,Format,Args} = if is_atom(X1) -> {X1,?STD_IMPORTANCE,X2,[]}; @@ -732,12 +244,6 @@ pal(X1,X2) -> end, pal(Category,Importance,Format,Args,[]). -%%%----------------------------------------------------------------- -%%% @spec pal(X1,X2,X3) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Importance | Format | Args -%%% X3 = Format | Args | Opts -%%% @equiv pal(Category,Importance,Format,Args,Opts) pal(X1,X2,X3) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[],[]}; @@ -747,13 +253,6 @@ pal(X1,X2,X3) -> end, pal(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec pal(X1,X2,X3,X4) -> ok -%%% X1 = Category | Importance -%%% X2 = Importance | Format -%%% X3 = Format | Args -%%% X4 = Args | Opts -%%% @equiv pal(Category,Importance,Format,Args,Opts) pal(X1,X2,X3,X4) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,X4,[]}; @@ -762,91 +261,25 @@ pal(X1,X2,X3,X4) -> end, pal(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec pal(Category,Importance,Format,Args,Opts) -> ok -%%% Category = atom() -%%% Importance = integer() -%%% Format = string() -%%% Args = list() -%%% Opts = [Opt] -%%% Opt = {heading,string()} | no_css -%%% -%%% @doc Print and log from a test case. -%%% -%%% <p>This function is meant for printing a string from a test case, -%%% both to the test case log file and to the console.</p> -%%% -%%% <p>Default <c>Category</c> is <c>default</c>, -%%% default <c>Importance</c> is <c>?STD_IMPORTANCE</c>, -%%% and default value for <c>Args</c> is <c>[]</c>.</p> -%%% <p>Please see the User's Guide for details on <c>Category</c> -%%% and <c>Importance</c>.</p> pal(Category,Importance,Format,Args,Opts) -> ct_logs:tc_pal(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec set_verbosity(Category, Level) -> ok -%%% Category = default | atom() -%%% Level = integer() -%%% -%%% @doc Set the verbosity level for a category set_verbosity(Category, Level) -> ct_util:set_verbosity({Category,Level}). -%%%----------------------------------------------------------------- -%%% @spec get_verbosity(Category) -> Level | undefined -%%% Category = default | atom() -%%% Level = integer() -%%% -%%% @doc Read the verbosity level for a category get_verbosity(Category) -> ct_util:get_verbosity(Category). -%%%----------------------------------------------------------------- -%%% @spec capture_start() -> ok -%%% -%%% @doc Start capturing all text strings printed to stdout during -%%% execution of the test case. -%%% -%%% @see capture_stop/0 -%%% @see capture_get/1 capture_start() -> test_server:capture_start(). -%%%----------------------------------------------------------------- -%%% @spec capture_stop() -> ok -%%% -%%% @doc Stop capturing text strings (a session started with -%%% <c>capture_start/0</c>). -%%% -%%% @see capture_start/0 -%%% @see capture_get/1 capture_stop() -> test_server:capture_stop(). -%%%----------------------------------------------------------------- -%%% @spec capture_get() -> ListOfStrings -%%% ListOfStrings = [string()] -%%% -%%% @equiv capture_get([default]) capture_get() -> %% remove default log printouts (e.g. ct:log/2 printouts) capture_get([default]). -%%%----------------------------------------------------------------- -%%% @spec capture_get(ExclCategories) -> ListOfStrings -%%% ExclCategories = [atom()] -%%% ListOfStrings = [string()] -%%% -%%% @doc Return and purge the list of text strings buffered -%%% during the latest session of capturing printouts to stdout. -%%% With <c>ExclCategories</c> it's possible to specify -%%% log categories that should be ignored in <c>ListOfStrings</c>. -%%% If <c>ExclCategories = []</c>, no filtering takes place. -%%% -%%% @see capture_start/0 -%%% @see capture_stop/0 -%%% @see log/3 capture_get([ExclCat | ExclCategories]) -> Strs = test_server:capture_get(), CatsStr = [atom_to_list(ExclCat) | @@ -863,12 +296,6 @@ capture_get([ExclCat | ExclCategories]) -> capture_get([]) -> test_server:capture_get(). -%%%----------------------------------------------------------------- -%%% @spec fail(Reason) -> ok -%%% Reason = term() -%%% -%%% @doc Terminate a test case with the given error -%%% <c>Reason</c>. fail(Reason) -> try exit({test_case_failed,Reason}) @@ -881,14 +308,6 @@ fail(Reason) -> erlang:raise(Class, R, Stk) end. -%%%----------------------------------------------------------------- -%%% @spec fail(Format, Args) -> ok -%%% Format = string() -%%% Args = list() -%%% -%%% @doc Terminate a test case with an error message specified -%%% by a format string and a list of values (used as arguments to -%%% <c>io_lib:format/2</c>). fail(Format, Args) -> try io_lib:format(Format, Args) of Str -> @@ -907,16 +326,6 @@ fail(Format, Args) -> exit({BadArgs,{?MODULE,fail,[Format,Args]}}) end. -%%%----------------------------------------------------------------- -%%% @spec comment(Comment) -> ok -%%% Comment = term() -%%% -%%% @doc Print the given <c>Comment</c> in the comment field in -%%% the table on the test suite result page. -%%% -%%% <p>If called several times, only the last comment is printed. -%%% The test case return value <c>{comment,Comment}</c> -%%% overwrites the string set by this function.</p> comment(Comment) when is_list(Comment) -> Formatted = case (catch io_lib:format("~ts",[Comment])) of @@ -930,19 +339,6 @@ comment(Comment) -> Formatted = io_lib:format("~tp",[Comment]), send_html_comment(lists:flatten(Formatted)). -%%%----------------------------------------------------------------- -%%% @spec comment(Format, Args) -> ok -%%% Format = string() -%%% Args = list() -%%% -%%% @doc Print the formatted string in the comment field in -%%% the table on the test suite result page. -%%% -%%% <p>The <c>Format</c> and <c>Args</c> arguments are -%%% used in call to <c>io_lib:format/2</c> in order to create -%%% the comment string. The behaviour of <c>comment/2</c> is -%%% otherwise the same as the <c>comment/1</c> function (see -%%% above for details).</p> comment(Format, Args) when is_list(Format), is_list(Args) -> Formatted = case (catch io_lib:format(Format, Args)) of @@ -958,28 +354,12 @@ send_html_comment(Comment) -> ct_util:set_testdata({{comment,group_leader()},Html}), test_server:comment(Html). -%%%----------------------------------------------------------------- -%%% @spec make_priv_dir() -> ok | {error,Reason} -%%% Reason = term() -%%% @doc If the test has been started with the create_priv_dir -%%% option set to manual_per_tc, in order for the test case to use -%%% the private directory, it must first create it by calling -%%% this function. make_priv_dir() -> test_server:make_priv_dir(). -%%%----------------------------------------------------------------- -%%% @spec get_target_name(Handle) -> {ok,TargetName} | {error,Reason} -%%% Handle = handle() -%%% TargetName = target_name() -%%% @doc Return the name of the target that the given connection -%%% belongs to. get_target_name(Handle) -> ct_util:get_target_name(Handle). -%%%----------------------------------------------------------------- -%%% @doc Return the command used to start (this) erlang - -spec get_progname() -> string(). get_progname() -> @@ -990,44 +370,12 @@ get_progname() -> "no_prog_name" end. -%%%----------------------------------------------------------------- -%%% @spec parse_table(Data) -> {Heading,Table} -%%% Data = [string()] -%%% Heading = tuple() -%%% Table = [tuple()] -%%% -%%% @doc Parse the printout from an SQL table and return a list of tuples. -%%% -%%% <p>The printout to parse would typically be the result of a -%%% <c>select</c> command in SQL. The returned -%%% <c>Table</c> is a list of tuples, where each tuple is a row -%%% in the table.</p> -%%% -%%% <p><c>Heading</c> is a tuple of strings representing the -%%% headings of each column in the table.</p> parse_table(Data) -> ct_util:parse_table(Data). -%%%----------------------------------------------------------------- -%%% @spec listenv(Telnet) -> [Env] -%%% Telnet = term() -%%% Env = {Key,Value} -%%% Key = string() -%%% Value = string() -%%% -%%% @doc Performs the listenv command on the given telnet connection -%%% and returns the result as a list of Key-Value pairs. listenv(Telnet) -> ct_util:listenv(Telnet). -%%%----------------------------------------------------------------- -%%% @spec testcases(TestDir, Suite) -> Testcases | {error,Reason} -%%% TestDir = string() -%%% Suite = atom() -%%% Testcases = list() -%%% Reason = term() -%%% -%%% @doc Returns all test cases in the specified suite. testcases(TestDir, Suite) -> case make_and_load(TestDir, Suite) of E = {error,_} -> @@ -1067,15 +415,6 @@ make_and_load(Dir, Suite) -> end end. -%%%----------------------------------------------------------------- -%%% @spec userdata(TestDir, Suite) -> SuiteUserData | {error,Reason} -%%% TestDir = string() -%%% Suite = atom() -%%% SuiteUserData = [term()] -%%% Reason = term() -%%% -%%% @doc Returns any data specified with the tag <c>userdata</c> -%%% in the list of tuples returned from <c>Suite:suite/0</c>. userdata(TestDir, Suite) -> case make_and_load(TestDir, Suite) of E = {error,_} -> @@ -1101,18 +440,6 @@ get_userdata(List, _) when is_list(List) -> get_userdata(_BadTerm, Spec) -> {error,list_to_atom(Spec ++ " must return a list")}. -%%%----------------------------------------------------------------- -%%% @spec userdata(TestDir, Suite, GroupOrCase) -> TCUserData | {error,Reason} -%%% TestDir = string() -%%% Suite = atom() -%%% GroupOrCase = {group,GroupName} | atom() -%%% GroupName = atom() -%%% TCUserData = [term()] -%%% Reason = term() -%%% -%%% @doc Returns any data specified with the tag <c>userdata</c> -%%% in the list of tuples returned from <c>Suite:group(GroupName)</c> -%%% or <c>Suite:Case()</c>. userdata(TestDir, Suite, {group,GroupName}) -> case make_and_load(TestDir, Suite) of E = {error,_} -> @@ -1131,27 +458,6 @@ userdata(TestDir, Suite, Case) when is_atom(Case) -> get_userdata(Info, atom_to_list(Case)++"/0") end. - -%%%----------------------------------------------------------------- -%%% @spec get_status() -> TestStatus | {error,Reason} | no_tests_running -%%% TestStatus = [StatusElem] -%%% StatusElem = {current,TestCaseInfo} | {successful,Successful} | -%%% {failed,Failed} | {skipped,Skipped} | {total,Total} -%%% TestCaseInfo = {Suite,TestCase} | [{Suite,TestCase}] -%%% Suite = atom() -%%% TestCase = atom() -%%% Successful = integer() -%%% Failed = integer() -%%% Skipped = {UserSkipped,AutoSkipped} -%%% UserSkipped = integer() -%%% AutoSkipped = integer() -%%% Total = integer() -%%% Reason = term() -%%% -%%% @doc Returns status of ongoing test. The returned list contains info about -%%% which test case is currently executing (a list of cases when a -%%% parallel test case group is executing), as well as counters for -%%% successful, failed, skipped, and total test cases so far. get_status() -> case get_testdata(curr_tc) of {ok,TestCase} -> @@ -1183,176 +489,37 @@ get_testdata(Key) -> {ok,Data} end. -%%%----------------------------------------------------------------- -%%% @spec abort_current_testcase(Reason) -> ok | {error,ErrorReason} -%%% Reason = term() -%%% ErrorReason = no_testcase_running | parallel_group -%%% -%%% @doc <p>When calling this function, the currently executing test case will be aborted. -%%% It is the user's responsibility to know for sure which test case is currently -%%% executing. The function is therefore only safe to call from a function which -%%% has been called (or synchronously invoked) by the test case.</p> -%%% -%%% <p><c>Reason</c>, the reason for aborting the test case, is printed -%%% in the test case log.</p> abort_current_testcase(Reason) -> test_server_ctrl:abort_current_testcase(Reason). -%%%----------------------------------------------------------------- -%%% @spec get_event_mgr_ref() -> EvMgrRef -%%% EvMgrRef = atom() -%%% -%%% @doc <p>Call this function in order to get a reference to the -%%% CT event manager. The reference can be used to e.g. add -%%% a user specific event handler while tests are running. -%%% Example: -%%% <c>gen_event:add_handler(ct:get_event_mgr_ref(), my_ev_h, [])</c></p> get_event_mgr_ref() -> ?CT_EVMGR_REF. -%%%----------------------------------------------------------------- -%%% @spec encrypt_config_file(SrcFileName, EncryptFileName) -> -%%% ok | {error,Reason} -%%% SrcFileName = string() -%%% EncryptFileName = string() -%%% Reason = term() -%%% -%%% @doc <p>This function encrypts the source config file with DES3 and -%%% saves the result in file <c>EncryptFileName</c>. The key, -%%% a string, must be available in a text file named -%%% <c>.ct_config.crypt</c> in the current directory, or the -%%% home directory of the user (it is searched for in that order).</p> -%%% <p>See the Common Test User's Guide for information about using -%%% encrypted config files when running tests.</p> -%%% <p>See the <c>crypto</c> application for details on DES3 -%%% encryption/decryption.</p> encrypt_config_file(SrcFileName, EncryptFileName) -> ct_config:encrypt_config_file(SrcFileName, EncryptFileName). -%%%----------------------------------------------------------------- -%%% @spec encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) -> -%%% ok | {error,Reason} -%%% SrcFileName = string() -%%% EncryptFileName = string() -%%% KeyOrFile = {key,string()} | {file,string()} -%%% Reason = term() -%%% -%%% @doc <p>This function encrypts the source config file with DES3 and -%%% saves the result in the target file <c>EncryptFileName</c>. -%%% The encryption key to use is either the value in -%%% <c>{key,Key}</c> or the value stored in the file specified -%%% by <c>{file,File}</c>.</p> -%%% <p>See the Common Test User's Guide for information about using -%%% encrypted config files when running tests.</p> -%%% <p>See the <c>crypto</c> application for details on DES3 -%%% encryption/decryption.</p> encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) -> ct_config:encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile). -%%%----------------------------------------------------------------- -%%% @spec decrypt_config_file(EncryptFileName, TargetFileName) -> -%%% ok | {error,Reason} -%%% EncryptFileName = string() -%%% TargetFileName = string() -%%% Reason = term() -%%% -%%% @doc <p>This function decrypts <c>EncryptFileName</c>, previously -%%% generated with <c>encrypt_config_file/2/3</c>. The original -%%% file contents is saved in the target file. The encryption key, a -%%% string, must be available in a text file named -%%% <c>.ct_config.crypt</c> in the current directory, or the -%%% home directory of the user (it is searched for in that order).</p> decrypt_config_file(EncryptFileName, TargetFileName) -> ct_config:decrypt_config_file(EncryptFileName, TargetFileName). -%%%----------------------------------------------------------------- -%%% @spec decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile) -> -%%% ok | {error,Reason} -%%% EncryptFileName = string() -%%% TargetFileName = string() -%%% KeyOrFile = {key,string()} | {file,string()} -%%% Reason = term() -%%% -%%% @doc <p>This function decrypts <c>EncryptFileName</c>, previously -%%% generated with <c>encrypt_config_file/2/3</c>. The original -%%% file contents is saved in the target file. The key must have the -%%% the same value as that used for encryption.</p> decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile) -> ct_config:decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile). - -%%%----------------------------------------------------------------- -%%% @spec add_config(Callback, Config) -> ok | {error, Reason} -%%% Callback = atom() -%%% Config = string() -%%% Reason = term() -%%% -%%% @doc <p>This function loads configuration variables using the -%%% given callback module and configuration string. Callback module -%%% should be either loaded or present in the code part. Loaded -%%% configuration variables can later be removed using -%%% <c>remove_config/2</c> function.</p> add_config(Callback, Config)-> ct_config:add_config(Callback, Config). -%%%----------------------------------------------------------------- -%%% @spec remove_config(Callback, Config) -> ok -%%% Callback = atom() -%%% Config = string() -%%% Reason = term() -%%% -%%% @doc <p>This function removes configuration variables (together with -%%% their aliases) which were loaded with specified callback module and -%%% configuration string.</p> remove_config(Callback, Config) -> ct_config:remove_config(Callback, Config). -%%%----------------------------------------------------------------- -%%% @spec timetrap(Time) -> ok -%%% Time = {hours,Hours} | {minutes,Mins} | {seconds,Secs} | Millisecs | infinity | Func -%%% Hours = integer() -%%% Mins = integer() -%%% Secs = integer() -%%% Millisecs = integer() | float() -%%% Func = {M,F,A} | fun() -%%% M = atom() -%%% F = atom() -%%% A = list() -%%% -%%% @doc <p>Use this function to set a new timetrap for the running test case. -%%% If the argument is <c>Func</c>, the timetrap will be triggered -%%% when this function returns. <c>Func</c> may also return a new -%%% <c>Time</c> value, which in that case will be the value for the -%%% new timetrap.</p> timetrap(Time) -> test_server:timetrap_cancel(), test_server:timetrap(Time). -%%%----------------------------------------------------------------- -%%% @spec get_timetrap_info() -> {Time,Scale} -%%% Time = integer() | infinity -%%% Scale = true | false -%%% -%%% @doc <p>Read info about the timetrap set for the current test case. -%%% <c>Scale</c> indicates if Common Test will attempt to automatically -%%% compensate timetraps for runtime delays introduced by e.g. tools like -%%% cover.</p> get_timetrap_info() -> test_server:get_timetrap_info(). -%%%----------------------------------------------------------------- -%%% @spec sleep(Time) -> ok -%%% Time = {hours,Hours} | {minutes,Mins} | {seconds,Secs} | Millisecs | infinity -%%% Hours = integer() -%%% Mins = integer() -%%% Secs = integer() -%%% Millisecs = integer() | float() -%%% -%%% @doc <p>This function, similar to <c>timer:sleep/1</c>, suspends the test -%%% case for specified time. However, this function also multiplies -%%% <c>Time</c> with the 'multiply_timetraps' value (if set) and under -%%% certain circumstances also scales up the time automatically -%%% if 'scale_timetraps' is set to true (default is false).</p> sleep({hours,Hs}) -> sleep(trunc(Hs * 1000 * 60 * 60)); sleep({minutes,Ms}) -> @@ -1362,52 +529,12 @@ sleep({seconds,Ss}) -> sleep(Time) -> test_server:adjusted_sleep(Time). -%%%----------------------------------------------------------------- -%%% @spec notify(Name,Data) -> ok -%%% Name = atom() -%%% Data = term() -%%% -%%% @doc <p>Sends a asynchronous notification of type <c>Name</c> with -%%% <c>Data</c>to the common_test event manager. This can later be -%%% caught by any installed event manager. </p> -%%% @see //stdlib/gen_event notify(Name,Data) -> ct_event:notify(Name, Data). -%%%----------------------------------------------------------------- -%%% @spec sync_notify(Name,Data) -> ok -%%% Name = atom() -%%% Data = term() -%%% -%%% @doc <p>Sends a synchronous notification of type <c>Name</c> with -%%% <c>Data</c>to the common_test event manager. This can later be -%%% caught by any installed event manager. </p> -%%% @see //stdlib/gen_event sync_notify(Name,Data) -> ct_event:sync_notify(Name, Data). -%%%----------------------------------------------------------------- -%%% @spec break(Comment) -> ok | {error,Reason} -%%% Comment = string() -%%% Reason = {multiple_cases_running,TestCases} | -%%% 'enable break with release_shell option' -%%% TestCases = [atom()] -%%% -%%% @doc <p>This function will cancel any active timetrap and pause the -%%% execution of the current test case until the user calls the -%%% <c>continue/0</c> function. It gives the user the opportunity -%%% to interact with the erlang node running the tests, e.g. for -%%% debugging purposes or for manually executing a part of the -%%% test case. If a parallel group is executing, <c>break/2</c> -%%% should be called instead.</p> -%%% <p>A cancelled timetrap will not be automatically -%%% reactivated after the break, but must be started exlicitly with -%%% <c>ct:timetrap/1</c></p> -%%% <p>In order for the break/continue functionality to work, -%%% Common Test must release the shell process controlling stdin. -%%% This is done by setting the <c>release_shell</c> start option -%%% to <c>true</c>. See the User's Guide for more information.</p> - break(Comment) -> case {ct_util:get_testdata(starter), ct_util:get_testdata(release_shell)} of @@ -1430,19 +557,6 @@ break(Comment) -> end end. -%%%----------------------------------------------------------------- -%%% @spec break(TestCase, Comment) -> ok | {error,Reason} -%%% TestCase = atom() -%%% Comment = string() -%%% Reason = 'test case not running' | -%%% 'enable break with release_shell option' -%%% -%%% @doc <p>This function works the same way as <c>break/1</c>, -%%% only the <c>TestCase</c> argument makes it possible to -%%% pause a test case executing in a parallel group. The -%%% <c>continue/1</c> function should be used to resume -%%% execution of <c>TestCase</c>.</p> -%%% <p>See <c>break/1</c> for more details.</p> break(TestCase, Comment) -> case {ct_util:get_testdata(starter), ct_util:get_testdata(release_shell)} of @@ -1469,56 +583,12 @@ break(TestCase, Comment) -> end end. -%%%----------------------------------------------------------------- -%%% @spec continue() -> ok -%%% -%%% @doc <p>This function must be called in order to continue after a -%%% test case (not executing in a parallel group) has called -%%% <c>break/1</c>.</p> continue() -> test_server:continue(). -%%%----------------------------------------------------------------- -%%% @spec continue(TestCase) -> ok -%%% TestCase = atom() -%%% -%%% @doc <p>This function must be called in order to continue after a -%%% test case has called <c>break/2</c>. If the paused test case, -%%% <c>TestCase</c>, executes in a parallel group, this -%%% function - rather than <c>continue/0</c> - must be used -%%% in order to let the test case proceed.</p> continue(TestCase) -> test_server:continue(TestCase). -%%%----------------------------------------------------------------- -%%% @spec remaining_test_procs() -> {TestProcs,SharedGL,OtherGLs} -%%% TestProcs = [{pid(),GL}] -%%% GL = SharedGL = pid() -%%% OtherGLs = [pid()] -%%% -%%% @doc <p>This function will return the identity of test- and group -%%% leader processes that are still running at the time of this call. -%%% TestProcs are processes in the system that have a Common Test IO -%%% process as group leader. SharedGL is the central Common Test -%%% IO process, responsible for printing to log files for configuration -%%% functions and sequentially executing test cases. OtherGLs are -%%% Common Test IO processes that print to log files for test cases -%%% in parallel test case groups.</p> -%%% <p>The process information returned by this function may be -%%% used to locate and terminate remaining processes after tests have -%%% finished executing. The function would typically by called from -%%% Common Test Hook functions.</p> -%%% <p>Note that processes that execute configuration functions or -%%% test cases are never included in TestProcs. It is therefore safe -%%% to use post configuration hook functions (such as post_end_per_suite, -%%% post_end_per_group, post_end_per_testcase) to terminate all processes -%%% in TestProcs that have the current group leader process as its group -%%% leader.</p> -%%% <p>Note also that the shared group leader (SharedGL) must never be -%%% terminated by the user, only by Common Test. Group leader processes -%%% for parallel test case groups (OtherGLs) may however be terminated -%%% in post_end_per_group hook functions.</p> -%%% remaining_test_procs() -> ct_util:remaining_test_procs(). diff --git a/lib/common_test/src/ct_cover.erl b/lib/common_test/src/ct_cover.erl index c258516915..d286f20a4d 100644 --- a/lib/common_test/src/ct_cover.erl +++ b/lib/common_test/src/ct_cover.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2016. All Rights Reserved. +%% Copyright Ericsson AB 2006-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,11 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework code coverage support module. -%%% -%%% <p>This module exports help functions for performing code -%%% coverage analysis.</p> - -module(ct_cover). -export([get_spec/1, add_nodes/1, remove_nodes/1, cross_cover_analyse/2]). @@ -31,16 +26,6 @@ -include_lib("kernel/include/file.hrl"). -%%%----------------------------------------------------------------- -%%% @spec add_nodes(Nodes) -> {ok,StartedNodes} | {error,Reason} -%%% Nodes = [atom()] -%%% StartedNodes = [atom()] -%%% Reason = cover_not_running | not_main_node -%%% -%%% @doc Add nodes to current cover test (only works if cover support -%%% is active!). To have effect, this function should be called -%%% from init_per_suite/1 before any actual tests are performed. -%%% add_nodes([]) -> {ok,[]}; add_nodes(Nodes) -> @@ -67,17 +52,6 @@ add_nodes(Nodes) -> end end. - -%%%----------------------------------------------------------------- -%%% @spec remove_nodes(Nodes) -> ok | {error,Reason} -%%% Nodes = [atom()] -%%% Reason = cover_not_running | not_main_node -%%% -%%% @doc Remove nodes from current cover test. Call this function -%%% to stop cover test on nodes previously added with add_nodes/1. -%%% Results on the remote node are transferred to the Common Test -%%% node. -%%% remove_nodes([]) -> ok; remove_nodes(Nodes) -> @@ -103,25 +77,11 @@ remove_nodes(Nodes) -> end end. - -%%%----------------------------------------------------------------- -%%% @spec cross_cover_analyse(Level,Tests) -> ok -%%% Level = overview | details -%%% Tests = [{Tag,Dir}] -%%% Tag = atom() -%%% Dir = string() -%%% -%%% @doc Accumulate cover results over multiple tests. -%%% See the chapter about <seealso -%%% marker="cover_chapter#cross_cover">cross cover -%%% analysis</seealso> in the users's guide. -%%% cross_cover_analyse(Level,Tests) -> test_server_ctrl:cross_cover_analyse(Level,Tests). %%%----------------------------------------------------------------- -%%% @hidden %% Read cover specification file and return the parsed info. %% -> CoverSpec: {CoverFile,Nodes,Import,Export,AppCoverInfo} diff --git a/lib/common_test/src/ct_event.erl b/lib/common_test/src/ct_event.erl index 8b5bba7600..3689c6bc45 100644 --- a/lib/common_test/src/ct_event.erl +++ b/lib/common_test/src/ct_event.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2017. All Rights Reserved. +%% Copyright Ericsson AB 2006-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,14 +18,14 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework Event Handler +%%% doc Common Test Framework Event Handler %%% -%%% <p>This module implements an event handler that CT uses to +%%% This module implements an event handler that CT uses to %%% handle status and progress notifications during test runs. %%% The notifications are handled locally (per node) and passed %%% on to ct_master when CT runs in distributed mode. This %%% module may be used as a template for other event handlers -%%% that can be plugged in to handle local logging and reporting.</p> +%%% that can be plugged in to handle local logging and reporting. -module(ct_event). -behaviour(gen_event). diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index 7f7e9ae6f9..134ae0e1cc 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2017. All Rights Reserved. +%% Copyright Ericsson AB 2004-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,10 +18,10 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework callback module. +%%% Common Test Framework callback module. %%% -%%% <p>This module exports framework callback functions which are -%%% called from the test_server.</p> +%%% This module exports framework callback functions which are +%%% called from the test_server. -module(ct_framework). @@ -42,7 +42,7 @@ -define(rev(L), lists:reverse(L)). %%%----------------------------------------------------------------- -%%% @spec init_tc(Mod,Func,Args) -> {ok,NewArgs} | {error,Reason} | +%%% -spec init_tc(Mod,Func,Args) -> {ok,NewArgs} | {error,Reason} | %%% {skip,Reason} | {auto_skip,Reason} %%% Mod = atom() %%% Func = atom() @@ -50,7 +50,7 @@ %%% NewArgs = list() %%% Reason = term() %%% -%%% @doc Test server framework callback, called by the test_server +%%% Test server framework callback, called by the test_server %%% when a new test case is started. init_tc(_,{end_per_testcase_not_run,_},[Config]) -> %% Testcase is completed (skipped or failed), but end_per_testcase @@ -649,7 +649,7 @@ try_set_default(Name,Key,Info,Where) -> %%%----------------------------------------------------------------- -%%% @spec end_tc(Mod,Func,Args) -> {ok,NewArgs}| {error,Reason} | +%%% -spec end_tc(Mod,Func,Args) -> {ok,NewArgs}| {error,Reason} | %%% {skip,Reason} | {auto_skip,Reason} %%% Mod = atom() %%% Func = atom() @@ -657,7 +657,7 @@ try_set_default(Name,Key,Info,Where) -> %%% NewArgs = list() %%% Reason = term() %%% -%%% @doc Test server framework callback, called by the test_server +%%% Test server framework callback, called by the test_server %%% when a test case is finished. end_tc(Mod, Fun, Args) -> %% Have to keep end_tc/3 for backwards compatibility issues @@ -903,15 +903,15 @@ tag(_Other) -> ok. %%%----------------------------------------------------------------- -%%% @spec error_notification(Mod,Func,Args,Error) -> ok +%%% -spec error_notification(Mod,Func,Args,Error) -> ok %%% Mod = atom() %%% Func = atom() %%% Args = list() %%% Error = term() %%% -%%% @doc This function is called as the result of testcase -%%% <code>Func</code> in suite <code>Mod</code> crashing. -%%% <code>Error</code> specifies the reason for failing. +%%% This function is called as the result of testcase +%%% Func in suite Mod crashing. +%%% Error specifies the reason for failing. error_notification(Mod,Func,_Args,{Error,Loc}) -> ErrorSpec = case Error of {What={_E,_R},Trace} when is_list(Trace) -> @@ -1049,11 +1049,11 @@ group_or_func(Func, _Config) -> Func. %%%----------------------------------------------------------------- -%%% @spec get_suite(Mod, Func) -> Tests +%%% -spec get_suite(Mod, Func) -> Tests %%% -%%% @doc Called from test_server for every suite (<code>Func==all</code>) -%%% and every test case. If the former, all test cases in the suite -%%% should be returned. +%%% Called from test_server for every suite (Func==all) +%%% and every test case. If the former, all test cases in the suite +%%% should be returned. get_suite(Mod, all) -> case catch apply(Mod, groups, []) of @@ -1355,7 +1355,7 @@ end_per_group(GroupName, _) -> ok. %%%----------------------------------------------------------------- -%%% @spec report(What,Data) -> ok +%%% -spec report(What,Data) -> ok report(What,Data) -> case What of loginfo -> @@ -1519,14 +1519,14 @@ add_to_stats(Result) -> ct_util:update_testdata(stats, Update). %%%----------------------------------------------------------------- -%%% @spec warn(What) -> true | false +%%% -spec warn(What) -> true | false warn(What) when What==nodes; What==processes -> false; warn(_What) -> true. %%%----------------------------------------------------------------- -%%% @spec add_data_dir(File0, Config) -> File1 +%%% -spec add_data_dir(File0, Config) -> File1 add_data_dir(File,Config) when is_atom(File) -> add_data_dir(atom_to_list(File),Config); @@ -1545,7 +1545,7 @@ add_data_dir(File,Config) when is_list(File) -> end. %%%----------------------------------------------------------------- -%%% @spec get_logopts() -> [LogOpt] +%%% -spec get_logopts() -> [LogOpt] get_logopts() -> case ct_util:get_testdata(logopts) of undefined -> @@ -1555,12 +1555,12 @@ get_logopts() -> end. %%%----------------------------------------------------------------- -%%% @spec format_comment(Comment) -> HtmlComment +%%% -spec format_comment(Comment) -> HtmlComment format_comment(Comment) -> "<font color=\"green\">" ++ Comment ++ "</font>". %%%----------------------------------------------------------------- -%%% @spec get_html_wrapper(TestName, PrintLabel, Cwd) -> Header +%%% -spec get_html_wrapper(TestName, PrintLabel, Cwd) -> Header get_html_wrapper(TestName, PrintLabel, Cwd, TableCols) -> get_html_wrapper(TestName, PrintLabel, Cwd, TableCols, utf8). @@ -1568,6 +1568,6 @@ get_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding) -> ct_logs:get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding). %%%----------------------------------------------------------------- -%%% @spec get_log_dir() -> {ok,LogDir} +%%% -spec get_log_dir() -> {ok,LogDir} get_log_dir() -> ct_logs:get_log_dir(true). diff --git a/lib/common_test/src/ct_ftp.erl b/lib/common_test/src/ct_ftp.erl index 8b02ae3a0f..93d1f88041 100644 --- a/lib/common_test/src/ct_ftp.erl +++ b/lib/common_test/src/ct_ftp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,12 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc FTP client module (based on the FTP application). -%%% -%%% @type connection() = handle() | ct:target_name() -%%% @type handle() = ct_gen_conn:handle(). Handle for a specific -%%% ftp connection. - -module(ct_ftp). %% API @@ -42,76 +36,14 @@ %%%================================================================= %%% API -%%%----------------------------------------------------------------- -%%% @spec put(KeyOrName,LocalFile,RemoteFile) -> ok | {error,Reason} -%%% KeyOrName = Key | Name -%%% Key = atom() -%%% Name = ct:target_name() -%%% LocalFile = string() -%%% RemoteFile = string() -%%% -%%% @doc Open a ftp connection and send a file to the remote host. -%%% -%%% <p><code>LocalFile</code> and <code>RemoteFile</code> must be -%%% absolute paths.</p> -%%% -%%% <p>If the target host is a "special" node, the ftp address must be -%%% specified in the config file like this:</p> -%%% <pre> -%%% {node,[{ftp,IpAddr}]}.</pre> -%%% -%%% <p>If the target host is something else, e.g. a unix host, the -%%% config file must also include the username and password (both -%%% strings):</p> -%%% <pre> -%%% {unix,[{ftp,IpAddr}, -%%% {username,Username}, -%%% {password,Password}]}.</pre> -%%% @see ct:require/2 put(KeyOrName,LocalFile,RemoteFile) -> Fun = fun(Ftp) -> send(Ftp,LocalFile,RemoteFile) end, open_and_do(KeyOrName,Fun). -%%%----------------------------------------------------------------- -%%% @spec get(KeyOrName,RemoteFile,LocalFile) -> ok | {error,Reason} -%%% KeyOrName = Key | Name -%%% Key = atom() -%%% Name = ct:target_name() -%%% RemoteFile = string() -%%% LocalFile = string() -%%% -%%% @doc Open a ftp connection and fetch a file from the remote host. -%%% -%%% <p><code>RemoteFile</code> and <code>LocalFile</code> must be -%%% absolute paths.</p> -%%% -%%% <p>The config file must be as for put/3.</p> -%%% @see put/3 -%%% @see ct:require/2 get(KeyOrName,RemoteFile,LocalFile) -> Fun = fun(Ftp) -> recv(Ftp,RemoteFile,LocalFile) end, open_and_do(KeyOrName,Fun). - -%%%----------------------------------------------------------------- -%%% @spec open(KeyOrName) -> {ok,Handle} | {error,Reason} -%%% KeyOrName = Key | Name -%%% Key = atom() -%%% Name = ct:target_name() -%%% Handle = handle() -%%% -%%% @doc Open an FTP connection to the specified node. -%%% <p>You can open one connection for a particular <code>Name</code> and -%%% use the same name as reference for all subsequent operations. If you -%%% want the connection to be associated with <code>Handle</code> instead -%%% (in case you need to open multiple connections to a host for example), -%%% simply use <code>Key</code>, the configuration variable name, to -%%% specify the target. Note that a connection that has no associated target -%%% name can only be closed with the handle value.</p> -%%% -%%% <p>See <c>ct:require/2</c> for how to create a new <c>Name</c></p> -%%% -%%% @see ct:require/2 open(KeyOrName) -> case ct_util:get_key_from_name(KeyOrName) of {ok,node} -> @@ -152,25 +84,9 @@ open(KeyOrName,Username,Password) -> ct_gen_conn:start(KeyOrName,full_addr(Addr),{Username,Password},?MODULE) end. - -%%%----------------------------------------------------------------- -%%% @spec send(Connection,LocalFile) -> ok | {error,Reason} -%%% -%%% @doc Send a file over FTP. -%%% <p>The file will get the same name on the remote host.</p> -%%% @see send/3 send(Connection,LocalFile) -> send(Connection,LocalFile,filename:basename(LocalFile)). -%%%----------------------------------------------------------------- -%%% @spec send(Connection,LocalFile,RemoteFile) -> ok | {error,Reason} -%%% Connection = connection() -%%% LocalFile = string() -%%% RemoteFile = string() -%%% -%%% @doc Send a file over FTP. -%%% -%%% <p>The file will be named <code>RemoteFile</code> on the remote host.</p> send(Connection,LocalFile,RemoteFile) -> case get_handle(Connection) of {ok,Pid} -> @@ -179,24 +95,9 @@ send(Connection,LocalFile,RemoteFile) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec recv(Connection,RemoteFile) -> ok | {error,Reason} -%%% -%%% @doc Fetch a file over FTP. -%%% <p>The file will get the same name on the local host.</p> -%%% @see recv/3 recv(Connection,RemoteFile) -> recv(Connection,RemoteFile,filename:basename(RemoteFile)). -%%%----------------------------------------------------------------- -%%% @spec recv(Connection,RemoteFile,LocalFile) -> ok | {error,Reason} -%%% Connection = connection() -%%% RemoteFile = string() -%%% LocalFile = string() -%%% -%%% @doc Fetch a file over FTP. -%%% -%%% <p>The file will be named <code>LocalFile</code> on the local host.</p> recv(Connection,RemoteFile,LocalFile) -> case get_handle(Connection) of {ok,Pid} -> @@ -205,12 +106,6 @@ recv(Connection,RemoteFile,LocalFile) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec cd(Connection,Dir) -> ok | {error,Reason} -%%% Connection = connection() -%%% Dir = string() -%%% -%%% @doc Change directory on remote host. cd(Connection,Dir) -> case get_handle(Connection) of {ok,Pid} -> @@ -219,13 +114,6 @@ cd(Connection,Dir) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec ls(Connection,Dir) -> {ok,Listing} | {error,Reason} -%%% Connection = connection() -%%% Dir = string() -%%% Listing = string() -%%% -%%% @doc List the directory Dir. ls(Connection,Dir) -> case get_handle(Connection) of {ok,Pid} -> @@ -234,12 +122,6 @@ ls(Connection,Dir) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec type(Connection,Type) -> ok | {error,Reason} -%%% Connection = connection() -%%% Type = ascii | binary -%%% -%%% @doc Change file transfer type type(Connection,Type) -> case get_handle(Connection) of {ok,Pid} -> @@ -248,12 +130,6 @@ type(Connection,Type) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec delete(Connection,File) -> ok | {error,Reason} -%%% Connection = connection() -%%% File = string() -%%% -%%% @doc Delete a file on remote host delete(Connection,File) -> case get_handle(Connection) of {ok,Pid} -> @@ -262,11 +138,6 @@ delete(Connection,File) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec close(Connection) -> ok | {error,Reason} -%%% Connection = connection() -%%% -%%% @doc Close the FTP connection. close(Connection) -> case get_handle(Connection) of {ok,Pid} -> @@ -279,7 +150,6 @@ close(Connection) -> %%%================================================================= %%% Callback functions -%% @hidden init(KeyOrName,{IP,Port},{Username,Password}) -> case ftp_connect(IP,Port,Username,Password) of {ok,FtpPid} -> @@ -305,7 +175,6 @@ ftp_connect(IP,Port,Username,Password) -> {error,{open,Reason}} end. -%% @hidden handle_msg({send,LocalFile,RemoteFile},State) -> log(heading(send,State#state.target_name), "LocalFile: ~tp\nRemoteFile: ~tp\n",[LocalFile,RemoteFile]), @@ -333,11 +202,9 @@ handle_msg({delete,File},State) -> Result = ftp:delete(State#state.ftp_pid,File), {Result,State}. -%% @hidden reconnect(_Addr,_State) -> {error,no_reconnection_of_ftp}. -%% @hidden terminate(FtpPid,State) -> log(heading(terminate,State#state.target_name), "Closing FTP connection.\nHandle: ~p\n",[FtpPid]), diff --git a/lib/common_test/src/ct_gen_conn.erl b/lib/common_test/src/ct_gen_conn.erl index 456bfd8bd1..1ab9946d96 100644 --- a/lib/common_test/src/ct_gen_conn.erl +++ b/lib/common_test/src/ct_gen_conn.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,9 +18,9 @@ %% %CopyrightEnd% %% -%%% @doc Generic connection owner process. +%%% Generic connection owner process. %%% -%%% @type handle() = pid(). A handle for using a connection implemented +%%% -type handle() = pid(). A handle for using a connection implemented %%% with ct_gen_conn.erl. -module(ct_gen_conn). @@ -48,7 +48,7 @@ ct_util_server}). %%%----------------------------------------------------------------- -%%% @spec start(Address,InitData,CallbackMod,Opts) -> +%%% -spec start(Address,InitData,CallbackMod,Opts) -> %%% {ok,Handle} | {error,Reason} %%% Name = term() %%% CallbackMod = atom() @@ -58,57 +58,52 @@ %%% Opt = {name,Name} | {use_existing_connection,boolean()} | %%% {reconnect,boolean()} | {forward_messages,boolean()} %%% -%%% @doc Open a connection and start the generic connection owner process. +%%% Open a connection and start the generic connection owner process. %%% -%%% <p>The <code>CallbackMod</code> is a specific callback module for +%%% The CallbackMod is a specific callback module for %%% each type of connection (e.g. telnet, ftp,...). It must export the -%%% function <code>init/3</code> which takes the arguments -%%% <code>Name</code>, <code>Addresse</code>) and -%%% <code>InitData</code> and returna -%%% <code>{ok,ConnectionPid,State}</code> or -%%% <code>{error,Reason}</code>.</p> +%%% function init/3 which takes the arguments +%%% Name, Addresse) and +%%% InitData and returna +%%% {ok,ConnectionPid,State} or +%%% {error,Reason}. %%% -%%% If no name is given, the <code>Name</code> argument in init/3 will -%%% have the value <code>undefined</code>. +%%% If no name is given, the Name argument in init/3 will +%%% have the value undefined. %%% %%% The callback modules must also export -%%% ``` +%%% %%% handle_msg(Msg,From,State) -> {reply,Reply,State} | %%% {noreply,State} | %%% {stop,Reply,State} %%% terminate(ConnectionPid,State) -> term() %%% close(Handle) -> term() -%%% ''' %%% -%%% The <code>close/1</code> callback function is actually a callback +%%% The close/1 callback function is actually a callback %%% for ct_util, for closing registered connections when -%%% ct_util_server is terminated. <code>Handle</code> is the Pid of +%%% ct_util_server is terminated. Handle is the Pid of %%% the ct_gen_conn process. %%% -%%% If option <code>reconnect</code> is <code>true</code>, then the +%%% If option reconnect is true, then the %%% callback must also export -%%% ``` +%%% %%% reconnect(Address,State) -> {ok,ConnectionPid,State} -%%% ''' %%% -%%% If option <code>forward_messages</code> is <ocde>true</code>, then +%%% If option forward_messages is <ocde>true, then %%% the callback must also export -%%% ``` +%%% %%% handle_msg(Msg,State) -> {noreply,State} | {stop,State} -%%% ''' %%% %%% An old interface still exists. This is used by ct_telnet, ct_ftp %%% and ct_ssh. The start function then has an explicit -%%% <code>Name</code> argument, and no <code>Opts</code> argument. The +%%% Name argument, and no Opts argument. The %%% callback must export: %%% -%%% ``` %%% init(Name,Address,InitData) -> {ok,ConnectionPid,State} %%% handle_msg(Msg,State) -> {Reply,State} %%% reconnect(Address,State) -> {ok,ConnectionPid,State} %%% terminate(ConnectionPid,State) -> term() %%% close(Handle) -> term() -%%% ''' %%% start(Address,InitData,CallbackMod,Opts) when is_list(Opts) -> do_start(Address,InitData,CallbackMod,Opts); @@ -116,73 +111,73 @@ start(Name,Address,InitData,CallbackMod) -> do_start(Address,InitData,CallbackMod,[{name,Name},{old,true}]). %%%----------------------------------------------------------------- -%%% @spec stop(Handle) -> ok +%%% -spec stop(Handle) -> ok %%% Handle = handle() %%% -%%% @doc Close the connection and stop the process managing it. +%%% Close the connection and stop the process managing it. stop(Handle) -> call(Handle,stop,5000). %%%----------------------------------------------------------------- -%%% @spec get_conn_pid(Handle) -> ok +%%% -spec get_conn_pid(Handle) -> ok %%% Handle = handle() %%% -%%% @doc Return the connection pid associated with Handle +%%% Return the connection pid associated with Handle get_conn_pid(Handle) -> call(Handle,get_conn_pid). %%%----------------------------------------------------------------- -%%% @spec log(Heading,Format,Args) -> ok +%%% -spec log(Heading,Format,Args) -> ok %%% -%%% @doc Log activities on the current connection (tool-internal use only). -%%% @see ct_logs:log/3 +%%% Log activities on the current connection (tool-internal use only). +%%% See ct_logs:log/3 log(Heading,Format,Args) -> log(log,[Heading,Format,Args]). %%%----------------------------------------------------------------- -%%% @spec start_log(Heading) -> ok +%%% -spec start_log(Heading) -> ok %%% -%%% @doc Log activities on the current connection (tool-internal use only). -%%% @see ct_logs:start_log/1 +%%% Log activities on the current connection (tool-internal use only). +%%% See ct_logs:start_log/1 start_log(Heading) -> log(start_log,[Heading]). %%%----------------------------------------------------------------- -%%% @spec cont_log(Format,Args) -> ok +%%% -spec cont_log(Format,Args) -> ok %%% -%%% @doc Log activities on the current connection (tool-internal use only). -%%% @see ct_logs:cont_log/2 +%%% Log activities on the current connection (tool-internal use only). +%%% See ct_logs:cont_log/2 cont_log(Format,Args) -> log(cont_log,[Format,Args]). %%%----------------------------------------------------------------- -%%% @spec cont_log_no_timestamp(Format,Args) -> ok +%%% -spec cont_log_no_timestamp(Format,Args) -> ok %%% -%%% @doc Log activities on the current connection (tool-internal use only). -%%% @see ct_logs:cont_log/2 +%%% Log activities on the current connection (tool-internal use only). +%%% See ct_logs:cont_log/2 cont_log_no_timestamp(Format,Args) -> log(cont_log_no_timestamp,[Format,Args]). %%%----------------------------------------------------------------- -%%% @spec end_log() -> ok +%%% -spec end_log() -> ok %%% -%%% @doc Log activities on the current connection (tool-internal use only). -%%% @see ct_logs:end_log/0 +%%% Log activities on the current connection (tool-internal use only). +%%% See ct_logs:end_log/0 end_log() -> log(end_log,[]). %%%----------------------------------------------------------------- -%%% @spec do_within_time(Fun,Timeout) -> FunResult | {error,Reason} +%%% -spec do_within_time(Fun,Timeout) -> FunResult | {error,Reason} %%% Fun = function() %%% Timeout = integer() %%% -%%% @doc Execute a function within a limited time (tool-internal use only). +%%% Execute a function within a limited time (tool-internal use only). %%% -%%% <p>Execute the given <code>Fun</code>, but interrupt if it takes -%%% more than <code>Timeout</code> milliseconds.</p> +%%% Execute the given Fun, but interrupt if it takes +%%% more than Timeout milliseconds. %%% -%%% <p>The execution is also interrupted if the connection is -%%% closed.</p> +%%% The execution is also interrupted if the connection is +%%% closed. do_within_time(Fun,Timeout) -> Self = self(), Silent = get(silent), diff --git a/lib/common_test/src/ct_groups.erl b/lib/common_test/src/ct_groups.erl index 2235365a0e..d867069dce 100644 --- a/lib/common_test/src/ct_groups.erl +++ b/lib/common_test/src/ct_groups.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2017. All Rights Reserved. +%% Copyright Ericsson AB 2004-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,11 +18,9 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework callback module. -%%% -%%% <p>This module contains CT internal help functions for searching -%%% through groups specification trees and producing resulting -%%% tests.</p> +%%% This module contains CT internal help functions for searching +%%% through groups specification trees and producing resulting +%%% tests. -module(ct_groups). diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl index bb33f0243b..49587b3edd 100644 --- a/lib/common_test/src/ct_hooks.erl +++ b/lib/common_test/src/ct_hooks.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2017. All Rights Reserved. +%% Copyright Ericsson AB 2004-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,10 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework test execution control module. -%%% -%%% <p>This module is a proxy for calling and handling common test hooks.</p> - -module(ct_hooks). %% API Exports @@ -47,14 +43,12 @@ %% API Functions %% ------------------------------------------------------------------------- -%% @doc Called before any suites are started -spec init(State :: term()) -> ok | {fail, Reason :: term()}. init(Opts) -> call(get_builtin_hooks(Opts) ++ get_new_hooks(Opts, undefined), ok, init, []). -%% @doc Called after all suites are done. -spec terminate(Hooks :: term()) -> ok. terminate(Hooks) -> @@ -63,8 +57,6 @@ terminate(Hooks) -> ct_hooks_terminate_dummy, terminate, Hooks), ok. -%% @doc Called as each test case is started. This includes all configuration -%% tests. -spec init_tc(Mod :: atom(), FuncSpec :: atom() | {ConfigFunc :: init_per_testcase | end_per_testcase, @@ -104,8 +96,6 @@ init_tc(Mod, {end_per_testcase,TC}, Config) -> init_tc(Mod, TC = error_in_suite, Config) -> call(fun call_generic_fallback/3, Config, [pre_init_per_testcase, Mod, TC]). -%% @doc Called as each test case is completed. This includes all configuration -%% tests. -spec end_tc(Mod :: atom(), FuncSpec :: atom() | {ConfigFunc :: init_per_testcase | end_per_testcase, diff --git a/lib/common_test/src/ct_hooks_lock.erl b/lib/common_test/src/ct_hooks_lock.erl index a82be288e1..be50a33e01 100644 --- a/lib/common_test/src/ct_hooks_lock.erl +++ b/lib/common_test/src/ct_hooks_lock.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,11 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework test execution control module. -%%% -%%% <p>This module is a proxy for calling and handling locks in -%%% common test hooks.</p> - -module(ct_hooks_lock). -behaviour(gen_server). @@ -42,7 +37,6 @@ %%% API %%%=================================================================== -%% @doc Starts the server start(Id) -> case gen_server:start({local, ?SERVER}, ?MODULE, Id, []) of {error,{already_started, Pid}} -> @@ -76,12 +70,10 @@ release() -> %%% gen_server callbacks %%%=================================================================== -%% @doc Initiates the server init(Id) -> ct_util:mark_process(), {ok, #state{ id = Id }}. -%% @doc Handling call messages handle_call({stop,Id}, _From, #state{ id = Id, requests = Reqs } = State) -> _ = [gen_server:reply(Req, locker_stopped) || {Req,_ReqId} <- Reqs], {stop, normal, stopped, State}; @@ -108,11 +100,9 @@ handle_call({release, Pid}, _From, handle_call({release, _Pid}, _From, State) -> {reply, not_locked, State}. -%% @doc Handling cast messages handle_cast(_Msg, State) -> {noreply, State}. -%% @doc Handling all non call/cast messages handle_info({'DOWN',Ref,process,Pid,_}, #state{ locked = {true, Pid, Ref}, requests = [{NextFrom,NextPid}|Rest] } = State) -> @@ -121,11 +111,9 @@ handle_info({'DOWN',Ref,process,Pid,_}, {noreply,State#state{ locked = {true, NextPid, NextRef}, requests = Rest } }. -%% @doc This function is called by a gen_server when it is about to terminate. terminate(_Reason, _State) -> ok. -%% @doc Convert process state when code is changed code_change(_OldVsn, State, _Extra) -> {ok, State}. diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl index 9861b1e521..07a1693d5d 100644 --- a/lib/common_test/src/ct_logs.erl +++ b/lib/common_test/src/ct_logs.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,14 +18,12 @@ %% %CopyrightEnd% %% -%%% @doc Logging functionality for Common Test Framework. +%%% Logging functionality for Common Test Framework. %%% -%%% <p>This module implements -%%% <ul> -%%% <li>Internal logging of activities in Common Test Framework</li> -%%% <li>Compilation of test results into index pages on several levels</li> -%%% </ul> -%%% </p> +%%% This module implements: +%%% +%%% Internal logging of activities in Common Test Framework, and +%%% Compilation of test results into index pages on several levels -module(ct_logs). @@ -84,17 +82,17 @@ tests = []}). %%%----------------------------------------------------------------- -%%% @spec init(Mode, Verbosity) -> Result +%%% -spec init(Mode, Verbosity) -> Result %%% Mode = normal | interactive %%% Result = {StartTime,LogDir} %%% StartTime = term() %%% LogDir = string() %%% -%%% @doc Initiate the logging mechanism (tool-internal use only). +%%% Initiate the logging mechanism (tool-internal use only). %%% -%%% <p>This function is called by ct_util.erl when testing is -%%% started. A new directory named ct_run.<timestamp> is created -%%% and all logs are stored under this directory.</p> +%%% This function is called by ct_util.erl when testing is +%%% started. A new directory named ct_run.<timestamp> is created +%%% and all logs are stored under this directory. %%% init(Mode, Verbosity) -> Self = self(), @@ -129,9 +127,9 @@ datestr_from_dirname([]) -> "". %%%----------------------------------------------------------------- -%%% @spec close(Info, StartDir) -> ok +%%% -spec close(Info, StartDir) -> ok %%% -%%% @doc Create index pages with test results and close the CT Log +%%% Create index pages with test results and close the CT Log %%% (tool-internal use only). close(Info, StartDir) -> %% close executes on the ct_util process, not on the logger process @@ -204,22 +202,22 @@ close(Info, StartDir) -> ok. %%%----------------------------------------------------------------- -%%% @spec set_stylesheet(TC,SSFile) -> ok +%%% -spec set_stylesheet(TC,SSFile) -> ok set_stylesheet(TC, SSFile) -> cast({set_stylesheet,TC,SSFile}). %%%----------------------------------------------------------------- -%%% @spec clear_stylesheet(TC) -> ok +%%% -spec clear_stylesheet(TC) -> ok clear_stylesheet(TC) -> cast({clear_stylesheet,TC}). %%%----------------------------------------------------------------- -%%% @spec get_log_dir() -> {ok,Dir} | {error,Reason} +%%% -spec get_log_dir() -> {ok,Dir} | {error,Reason} get_log_dir() -> get_log_dir(false). %%%----------------------------------------------------------------- -%%% @spec get_log_dir(ReturnAbsName) -> {ok,Dir} | {error,Reason} +%%% -spec get_log_dir(ReturnAbsName) -> {ok,Dir} | {error,Reason} get_log_dir(ReturnAbsName) -> case call({get_log_dir,ReturnAbsName}) of {error,does_not_exist} when ReturnAbsName == true -> @@ -278,58 +276,58 @@ get_format_args(Content) -> end, Content). %%%----------------------------------------------------------------- -%%% @spec init_tc(RefreshLog) -> ok +%%% -spec init_tc(RefreshLog) -> ok %%% -%%% @doc Test case initiation (tool-internal use only). +%%% Test case initiation (tool-internal use only). %%% -%%% <p>This function is called by ct_framework:init_tc/3</p> +%%% This function is called by ct_framework:init_tc/3 init_tc(RefreshLog) -> call({init_tc,self(),group_leader(),RefreshLog}), tc_io_format(group_leader(), xhtml("", "<br />"), []), ok. %%%----------------------------------------------------------------- -%%% @spec end_tc(TCPid) -> ok +%%% -spec end_tc(TCPid) -> ok %%% -%%% @doc Test case clean up (tool-internal use only). +%%% Test case clean up (tool-internal use only). %%% -%%% <p>This function is called by ct_framework:end_tc/3</p> +%%% This function is called by ct_framework:end_tc/3 end_tc(TCPid) -> %% use call here so that the TC process will wait and receive %% possible exit signals from ct_logs before end_tc returns ok call({end_tc,TCPid}). %%%----------------------------------------------------------------- -%%% @spec register_groupleader(Pid,GroupLeader) -> ok +%%% -spec register_groupleader(Pid,GroupLeader) -> ok %%% -%%% @doc To enable logging to a group leader (tool-internal use only). +%%% To enable logging to a group leader (tool-internal use only). %%% -%%% <p>This function is called by ct_framework:report/2</p> +%%% This function is called by ct_framework:report/2 register_groupleader(Pid,GroupLeader) -> call({register_groupleader,Pid,GroupLeader}), ok. %%%----------------------------------------------------------------- -%%% @spec unregister_groupleader(Pid) -> ok +%%% -spec unregister_groupleader(Pid) -> ok %%% -%%% @doc To disable logging to a group leader (tool-internal use only). +%%% To disable logging to a group leader (tool-internal use only). %%% -%%% <p>This function is called by ct_framework:report/2</p> +%%% This function is called by ct_framework:report/2 unregister_groupleader(Pid) -> call({unregister_groupleader,Pid}), ok. %%%----------------------------------------------------------------- -%%% @spec log(Heading,Format,Args) -> ok +%%% -spec log(Heading,Format,Args) -> ok %%% -%%% @doc Log internal activity (tool-internal use only). +%%% Log internal activity (tool-internal use only). %%% -%%% <p>This function writes an entry to the currently active log, -%%% i.e. either the CT log or a test case log.</p> +%%% This function writes an entry to the currently active log, +%%% i.e. either the CT log or a test case log. %%% -%%% <p><code>Heading</code> is a short string indicating what type of -%%% activity it is. <code>Format</code> and <code>Args</code> is the -%%% data to log (as in <code>io:format(Format,Args)</code>).</p> +%%% Heading is a short string indicating what type of +%%% activity it is. Format and Args is the +%%% data to log (as in io:format(Format,Args)). log(Heading,Format,Args) -> cast({log,sync,self(),group_leader(),ct_internal,?MAX_IMPORTANCE, [{hd,int_header(),[log_timestamp(?now),Heading]}, @@ -339,32 +337,29 @@ log(Heading,Format,Args) -> ok. %%%----------------------------------------------------------------- -%%% @spec start_log(Heading) -> ok +%%% -spec start_log(Heading) -> ok %%% -%%% @doc Starts the logging of an activity (tool-internal use only). +%%% Starts the logging of an activity (tool-internal use only). %%% -%%% <p>This function must be used in combination with -%%% <code>cont_log/2</code> and <code>end_log/0</code>. The intention -%%% is to call <code>start_log</code> once, then <code>cont_log</code> -%%% any number of times and finally <code>end_log</code> once.</p> +%%% This function must be used in combination with +%%% cont_log/2 and end_log/0. The intention +%%% is to call start_log once, then cont_log +%%% any number of times and finally end_log once. %%% -%%% <p>For information about the parameters, see <code>log/3</code>.</p> +%%% For information about the parameters, see log/3. %%% -%%% @see log/3 -%%% @see cont_log/2 -%%% @see end_log/0 +%%% See log/3, cont_log/2, and end_log/0. start_log(Heading) -> cast({log,sync,self(),group_leader(),ct_internal,?MAX_IMPORTANCE, [{hd,int_header(),[log_timestamp(?now),Heading]}],false}), ok. %%%----------------------------------------------------------------- -%%% @spec cont_log(Format,Args) -> ok +%%% -spec cont_log(Format,Args) -> ok %%% -%%% @doc Adds information about an activity (tool-internal use only). +%%% Adds information about an activity (tool-internal use only). %%% -%%% @see start_log/1 -%%% @see end_log/0 +%%% See start_log/1 and end_log/0. cont_log([],[]) -> ok; cont_log(Format,Args) -> @@ -374,12 +369,11 @@ cont_log(Format,Args) -> ok. %%%----------------------------------------------------------------- -%%% @spec cont_log_no_timestamp(Format,Args) -> ok +%%% -spec cont_log_no_timestamp(Format,Args) -> ok %%% -%%% @doc Adds information about an activity (tool-internal use only). +%%% Adds information about an activity (tool-internal use only). %%% -%%% @see start_log/1 -%%% @see end_log/0 +%%% See start_log/1 and end_log/0. cont_log_no_timestamp([],[]) -> ok; cont_log_no_timestamp(Format,Args) -> @@ -388,12 +382,11 @@ cont_log_no_timestamp(Format,Args) -> ok. %%%----------------------------------------------------------------- -%%% @spec end_log() -> ok +%%% -spec end_log() -> ok %%% -%%% @doc Ends the logging of an activity (tool-internal use only). +%%% Ends the logging of an activity (tool-internal use only). %%% -%%% @see start_log/1 -%%% @see cont_log/2 +%%% See start_log/1 and cont_log/2. end_log() -> cast({log,sync,self(),group_leader(),ct_internal,?MAX_IMPORTANCE, [{ft,int_footer(), []}],false}), @@ -401,15 +394,15 @@ end_log() -> %%%----------------------------------------------------------------- -%%% @spec add_external_logs(Logs) -> ok +%%% -spec add_external_logs(Logs) -> ok %%% Logs = [Log] %%% Log = string() %%% -%%% @doc Print a link to each given <code>Log</code> in the test case +%%% Print a link to each given Log in the test case %%% log. %%% -%%% <p>The given <code>Logs</code> must exist in the priv dir of the -%%% calling test suite.</p> +%%% The given Logs must exist in the priv dir of the +%%% calling test suite. add_external_logs(Logs) -> start_log("External Logs"), [cont_log("<a href=\"~ts\">~ts</a>\n", @@ -417,12 +410,12 @@ add_external_logs(Logs) -> end_log(). %%%----------------------------------------------------------------- -%%% @spec add_link(Heading,File,Type) -> ok +%%% -spec add_link(Heading,File,Type) -> ok %%% Heading = string() %%% File = string() %%% Type = string() %%% -%%% @doc Print a link to a given file stored in the priv_dir of the +%%% Print a link to a given file stored in the priv_dir of the %%% calling test suite. add_link(Heading,File,Type) -> log(Heading,"<a href=\"~ts\" type=~tp>~ts</a>\n", @@ -430,25 +423,25 @@ add_link(Heading,File,Type) -> %%%----------------------------------------------------------------- -%%% @spec tc_log(Category,Format,Args) -> ok -%%% @equiv tc_log(Category,?STD_IMPORTANCE,Format,Args) +%%% -spec tc_log(Category,Format,Args) -> ok +%%% Equivalent to tc_log(Category,?STD_IMPORTANCE,Format,Args) tc_log(Category,Format,Args) -> tc_log(Category,?STD_IMPORTANCE,"User",Format,Args,[]). %%%----------------------------------------------------------------- -%%% @spec tc_log(Category,Importance,Format,Args) -> ok -%%% @equiv tc_log(Category,Importance,"User",Format,Args) +%%% -spec tc_log(Category,Importance,Format,Args) -> ok +%%% Equivalent to tc_log(Category,Importance,"User",Format,Args) tc_log(Category,Importance,Format,Args) -> tc_log(Category,Importance,"User",Format,Args,[]). %%%----------------------------------------------------------------- -%%% @spec tc_log(Category,Importance,Format,Args) -> ok -%%% @equiv tc_log(Category,Importance,"User",Format,Args) +%%% -spec tc_log(Category,Importance,Format,Args) -> ok +%%% Equivalent to tc_log(Category,Importance,"User",Format,Args) tc_log(Category,Importance,Format,Args,Opts) -> tc_log(Category,Importance,"User",Format,Args,Opts). %%%----------------------------------------------------------------- -%%% @spec tc_log(Category,Importance,Heading,Format,Args,Opts) -> ok +%%% -spec tc_log(Category,Importance,Heading,Format,Args,Opts) -> ok %%% Category = atom() %%% Importance = integer() %%% Heading = string() @@ -456,11 +449,11 @@ tc_log(Category,Importance,Format,Args,Opts) -> %%% Args = list() %%% Opts = list() %%% -%%% @doc Printout from a testcase. +%%% Printout from a testcase. %%% -%%% <p>This function is called by <code>ct</code> when logging +%%% This function is called by ct when logging %%% stuff directly from a testcase (i.e. not from within the CT -%%% framework).</p> +%%% framework). tc_log(Category,Importance,Heading,Format,Args,Opts) -> Data = case lists:member(no_css, Opts) of @@ -481,26 +474,26 @@ tc_log(Category,Importance,Heading,Format,Args,Opts) -> ok. %%%----------------------------------------------------------------- -%%% @spec tc_log_async(Category,Format,Args) -> ok -%%% @equiv tc_log_async(Category,?STD_IMPORTANCE,"User",Format,Args) +%%% -spec tc_log_async(Category,Format,Args) -> ok +%%% Equivalent to tc_log_async(Category,?STD_IMPORTANCE,"User",Format,Args) tc_log_async(Category,Format,Args) -> tc_log_async(Category,?STD_IMPORTANCE,"User",Format,Args). %%%----------------------------------------------------------------- -%%% @spec tc_log_async(Category,Importance,Format,Args) -> ok +%%% -spec tc_log_async(Category,Importance,Format,Args) -> ok %%% Category = atom() %%% Importance = integer() %%% Heading = string() %%% Format = string() %%% Args = list() %%% -%%% @doc Internal use only. +%%% Internal use only. %%% -%%% <p>This function is used to perform asynchronous printouts +%%% This function is used to perform asynchronous printouts %%% towards the test server IO handler. This is necessary in order %%% to avoid deadlocks when e.g. the hook that handles SASL printouts %%% prints to the test case log file at the same time test server -%%% asks ct_logs for an html wrapper.</p> +%%% asks ct_logs for an html wrapper. tc_log_async(Category,Importance,Heading,Format,Args) -> cast({log,async,self(),group_leader(),Category,Importance, [{hd,div_header(Category,Heading),[]}, @@ -509,29 +502,29 @@ tc_log_async(Category,Importance,Heading,Format,Args) -> true}), ok. %%%----------------------------------------------------------------- -%%% @spec tc_print(Category,Format,Args) -%%% @equiv tc_print(Category,?STD_IMPORTANCE,Format,Args,[]) +%%% -spec tc_print(Category,Format,Args) +%%% Equivalent to tc_print(Category,?STD_IMPORTANCE,Format,Args,[]) tc_print(Category,Format,Args) -> tc_print(Category,?STD_IMPORTANCE,Format,Args,[]). %%%----------------------------------------------------------------- -%%% @spec tc_print(Category,Importance,Format,Args) -%%% @equiv tc_print(Category,Importance,Format,Args,[]) +%%% -spec tc_print(Category,Importance,Format,Args) +%%% Equivalent to tc_print(Category,Importance,Format,Args,[]) tc_print(Category,Importance,Format,Args) -> tc_print(Category,Importance,Format,Args,[]). %%%----------------------------------------------------------------- -%%% @spec tc_print(Category,Importance,Format,Args,Opts) -> ok +%%% -spec tc_print(Category,Importance,Format,Args,Opts) -> ok %%% Category = atom() %%% Importance = integer() %%% Format = string() %%% Args = list() %%% Opts = list() %%% -%%% @doc Console printout from a testcase. +%%% Console printout from a testcase. %%% -%%% <p>This function is called by <code>ct</code> when printing -%%% stuff from a testcase on the user console.</p> +%%% This function is called by ct when printing +%%% stuff from a testcase on the user console. tc_print(Category,Importance,Format,Args,Opts) -> VLvl = case ct_util:get_verbosity(Category) of undefined -> @@ -572,44 +565,44 @@ get_header(Heading) -> %%%----------------------------------------------------------------- -%%% @spec tc_pal(Category,Format,Args) -> ok -%%% @equiv tc_pal(Category,?STD_IMPORTANCE,Format,Args,[]) -> ok +%%% -spec tc_pal(Category,Format,Args) -> ok +%%% Equivalent to tc_pal(Category,?STD_IMPORTANCE,Format,Args,[]) -> ok tc_pal(Category,Format,Args) -> tc_pal(Category,?STD_IMPORTANCE,Format,Args,[]). %%%----------------------------------------------------------------- -%%% @spec tc_pal(Category,Importance,Format,Args) -> ok -%%% @equiv tc_pal(Category,Importance,Format,Args,[]) -> ok +%%% -spec tc_pal(Category,Importance,Format,Args) -> ok +%%% Equivalent to tc_pal(Category,Importance,Format,Args,[]) -> ok tc_pal(Category,Importance,Format,Args) -> tc_pal(Category,Importance,Format,Args,[]). %%%----------------------------------------------------------------- -%%% @spec tc_pal(Category,Importance,Format,Args,Opts) -> ok +%%% -spec tc_pal(Category,Importance,Format,Args,Opts) -> ok %%% Category = atom() %%% Importance = integer() %%% Format = string() %%% Args = list() %%% Opts = list() %%% -%%% @doc Print and log from a testcase. +%%% Print and log from a testcase. %%% -%%% <p>This function is called by <code>ct</code> when logging +%%% This function is called by ct when logging %%% stuff directly from a testcase. The info is written both in the -%%% log and on the console.</p> +%%% log and on the console. tc_pal(Category,Importance,Format,Args,Opts) -> tc_print(Category,Importance,Format,Args,Opts), tc_log(Category,Importance,"User",Format,Args,[esc_chars|Opts]). %%%----------------------------------------------------------------- -%%% @spec ct_log(Category,Format,Args) -> ok +%%% -spec ct_log(Category,Format,Args) -> ok %%% Category = atom() %%% Format = string() %%% Args = list() %%% -%%% @doc Print to the ct framework log +%%% Print to the ct framework log %%% -%%% <p>This function is called by internal ct functions to -%%% force logging to the ct framework log</p> +%%% This function is called by internal ct functions to +%%% force logging to the ct framework log ct_log(Category,Format,Args) -> cast({ct_log,[{hd,div_header(Category),[]}, {Format,Args}, @@ -2993,13 +2986,13 @@ rm_files([]) -> ok. %%%----------------------------------------------------------------- -%%% @spec simulate() -> pid() +%%% -spec simulate() -> pid() %%% -%%% @doc Simulate the logger process. +%%% Simulate the logger process. %%% -%%% <p>Simulate the logger process - for use when testing code using +%%% Simulate the logger process - for use when testing code using %%% ct_logs logging mechanism without using the ct -%%% environment. (E.g. when testing code with ts)</p> +%%% environment. (E.g. when testing code with ts) simulate() -> cast(stop), S = self(), @@ -3027,9 +3020,7 @@ simulate_logger_loop() -> end. %%%----------------------------------------------------------------- -%%% @spec notify_and_lock_file(Files) -> ok -%%% -%%% @doc +%%% -spec notify_and_lock_file(Files) -> ok %%% notify_and_lock_file(File) -> case ct_event:is_alive() of @@ -3042,9 +3033,7 @@ notify_and_lock_file(File) -> end. %%%----------------------------------------------------------------- -%%% @spec notify_and_unlock_file(Files) -> ok -%%% -%%% @doc +%%% -spec notify_and_unlock_file(Files) -> ok %%% notify_and_unlock_file(File) -> case ct_event:is_alive() of @@ -3057,9 +3046,7 @@ notify_and_unlock_file(File) -> end. %%%----------------------------------------------------------------- -%%% @spec get_run_dirs(Dir) -> [string()] | false -%%% -%%% @doc +%%% -spec get_run_dirs(Dir) -> [string()] | false %%% get_run_dirs(Dir) -> case filelib:wildcard(filename:join(Dir, "run.[1-2]*")) of @@ -3070,9 +3057,7 @@ get_run_dirs(Dir) -> end. %%%----------------------------------------------------------------- -%%% @spec xhtml(HTML, XHTML) -> HTML | XHTML -%%% -%%% @doc +%%% -spec xhtml(HTML, XHTML) -> HTML | XHTML %%% xhtml(HTML, XHTML) when is_function(HTML), is_function(XHTML) -> @@ -3087,9 +3072,7 @@ xhtml(HTML, XHTML) -> end. %%%----------------------------------------------------------------- -%%% @spec odd_or_even() -> "odd" | "even" -%%% -%%% @doc +%%% -spec odd_or_even() -> "odd" | "even" %%% odd_or_even() -> case get(odd_or_even) of @@ -3102,9 +3085,7 @@ odd_or_even() -> end. %%%----------------------------------------------------------------- -%%% @spec basic_html() -> true | false -%%% -%%% @doc +%%% -spec basic_html() -> true | false %%% basic_html() -> case application:get_env(common_test, basic_html) of @@ -3115,9 +3096,7 @@ basic_html() -> end. %%%----------------------------------------------------------------- -%%% @spec locate_priv_file(FileName) -> PrivFile -%%% -%%% @doc +%%% -spec locate_priv_file(FileName) -> PrivFile %%% locate_priv_file(FileName) -> {ok,CWD} = file:get_cwd(), @@ -3147,13 +3126,13 @@ locate_priv_file(FileName) -> end. %%%----------------------------------------------------------------- -%%% @spec make_relative(AbsDir, Cwd) -> RelDir +%%% -spec make_relative(AbsDir, Cwd) -> RelDir %%% -%%% @doc Return directory path to File (last element of AbsDir), which -%%% is the path relative to Cwd. Examples when Cwd == "/ldisk/test/logs": -%%% make_relative("/ldisk/test/logs/run/trace.log") -> "run/trace.log" -%%% make_relative("/ldisk/test/trace.log") -> "../trace.log" -%%% make_relative("/ldisk/test/logs/trace.log") -> "trace.log" +%%% Return directory path to File (last element of AbsDir), which +%%% is the path relative to Cwd. Examples when Cwd == "/ldisk/test/logs": +%%% make_relative("/ldisk/test/logs/run/trace.log") -> "run/trace.log" +%%% make_relative("/ldisk/test/trace.log") -> "../trace.log" +%%% make_relative("/ldisk/test/logs/trace.log") -> "trace.log" make_relative(AbsDir) -> {ok,Cwd} = file:get_cwd(), make_relative(AbsDir, Cwd). @@ -3177,11 +3156,9 @@ make_relative1(DirTs, CwdTs) -> Ups ++ DirTs. %%%----------------------------------------------------------------- -%%% @spec get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding) +%%% -spec get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding) %%% -> {Mode,Header,Footer} %%% -%%% @doc -%%% get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding) -> get_ts_html_wrapper(TestName, undefined, PrintLabel, Cwd, TableCols, Encoding). diff --git a/lib/common_test/src/ct_master.erl b/lib/common_test/src/ct_master.erl index e2ea525cdd..fd33ee2280 100644 --- a/lib/common_test/src/ct_master.erl +++ b/lib/common_test/src/ct_master.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2017. All Rights Reserved. +%% Copyright Ericsson AB 2006-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,9 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Distributed test execution control for Common Test. -%%% <p>This module exports functions for running Common Test nodes -%%% on multiple hosts in parallel.</p> -module(ct_master). -export([run/1,run/3,run/4]). @@ -45,50 +42,14 @@ blocked=[] }). -%%%----------------------------------------------------------------- -%%% @spec run_test(Node,Opts) -> ok -%%% Node = atom() -%%% Opts = [OptTuples] -%%% OptTuples = {config,CfgFiles} | {dir,TestDirs} | {suite,Suites} | -%%% {testcase,Cases} | {spec,TestSpecs} | {allow_user_terms,Bool} | -%%% {logdir,LogDir} | {event_handler,EventHandlers} | -%%% {silent_connections,Conns} | {cover,CoverSpecFile} | -%%% {cover_stop,Bool} | {userconfig, UserCfgFiles} -%%% CfgFiles = string() | [string()] -%%% TestDirs = string() | [string()] -%%% Suites = atom() | [atom()] -%%% Cases = atom() | [atom()] -%%% TestSpecs = string() | [string()] -%%% LogDir = string() -%%% EventHandlers = EH | [EH] -%%% EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs} -%%% InitArgs = [term()] -%%% Conns = all | [atom()] -%%% -%%% @doc Tests are spawned on <code>Node</code> using <code>ct:run_test/1</code>. run_test(Node,Opts) -> run_test([{Node,Opts}]). -%%% @hidden run_test({Node,Opts}) -> run_test([{Node,Opts}]); run_test(NodeOptsList) when is_list(NodeOptsList) -> start_master(NodeOptsList). -%%%----------------------------------------------------------------- -%%% @spec run(TestSpecs,AllowUserTerms,InclNodes,ExclNodes) -> ok -%%% TestSpecs = string() | [SeparateOrMerged] -%%% SeparateOrMerged = string() | [string()] -%%% AllowUserTerms = bool() -%%% InclNodes = [atom()] -%%% ExclNodes = [atom()] -%%% -%%% @doc Tests are spawned on the nodes as specified in <code>TestSpecs</code>. -%%% Each specification in TestSpec will be handled separately. It is however -%%% possible to also specify a list of specifications that should be merged -%%% into one before the tests are executed. Any test without a particular node -%%% specification will also be executed on the nodes in <code>InclNodes</code>. -%%% Nodes in the <code>ExclNodes</code> list will be excluded from the test. run([TS|TestSpecs],AllowUserTerms,InclNodes,ExclNodes) when is_list(TS), is_list(InclNodes), is_list(ExclNodes) -> @@ -128,22 +89,9 @@ run(TS,AllowUserTerms,InclNodes,ExclNodes) when is_list(InclNodes), is_list(ExclNodes) -> run([TS],AllowUserTerms,InclNodes,ExclNodes). -%%%----------------------------------------------------------------- -%%% @spec run(TestSpecs,InclNodes,ExclNodes) -> ok -%%% TestSpecs = string() | [SeparateOrMerged] -%%% SeparateOrMerged = string() | [string()] -%%% InclNodes = [atom()] -%%% ExclNodes = [atom()] -%%% -%%% @equiv run(TestSpecs,false,InclNodes,ExclNodes) run(TestSpecs,InclNodes,ExclNodes) -> run(TestSpecs,false,InclNodes,ExclNodes). -%%%----------------------------------------------------------------- -%%% @spec run(TestSpecs) -> ok -%%% TestSpecs = string() | [SeparateOrMerged] -%%% -%%% @equiv run(TestSpecs,false,[],[]) run(TestSpecs=[TS|_]) when is_list(TS) -> run(TestSpecs,false,[],[]); run(TS) -> @@ -156,15 +104,6 @@ exclude_nodes([],RunSkipPerNode) -> RunSkipPerNode. -%%%----------------------------------------------------------------- -%%% @spec run_on_node(TestSpecs,AllowUserTerms,Node) -> ok -%%% TestSpecs = string() | [SeparateOrMerged] -%%% SeparateOrMerged = string() | [string()] -%%% AllowUserTerms = bool() -%%% Node = atom() -%%% -%%% @doc Tests are spawned on <code>Node</code> according to -%%% <code>TestSpecs</code>. run_on_node([TS|TestSpecs],AllowUserTerms,Node) when is_list(TS),is_atom(Node) -> case catch ct_testspec:collect_tests_from_file([TS],[Node], AllowUserTerms) of @@ -194,13 +133,6 @@ run_on_node([],_,_) -> run_on_node(TS,AllowUserTerms,Node) when is_atom(Node) -> run_on_node([TS],AllowUserTerms,Node). -%%%----------------------------------------------------------------- -%%% @spec run_on_node(TestSpecs,Node) -> ok -%%% TestSpecs = string() | [SeparateOrMerged] -%%% SeparateOrMerged = string() | [string()] -%%% Node = atom() -%%% -%%% @equiv run_on_node(TestSpecs,false,Node) run_on_node(TestSpecs,Node) -> run_on_node(TestSpecs,false,Node). @@ -264,64 +196,25 @@ run_all([],AllLogDirs,_,AllEvHs,_AllIncludes, ok. -%%%----------------------------------------------------------------- -%%% @spec abort() -> ok -%%% -%%% @doc Stops all running tests. abort() -> call(abort). -%%%----------------------------------------------------------------- -%%% @spec abort(Nodes) -> ok -%%% Nodes = atom() | [atom()] -%%% -%%% @doc Stops tests on specified nodes. abort(Nodes) when is_list(Nodes) -> call({abort,Nodes}); abort(Node) when is_atom(Node) -> abort([Node]). -%%%----------------------------------------------------------------- -%%% @spec progress() -> [{Node,Status}] -%%% Node = atom() -%%% Status = finished_ok | ongoing | aborted | {error,Reason} -%%% Reason = term() -%%% -%%% @doc Returns test progress. If <code>Status</code> is <code>ongoing</code>, -%%% tests are running on the node and have not yet finished. progress() -> call(progress). -%%%----------------------------------------------------------------- -%%% @spec get_event_mgr_ref() -> MasterEvMgrRef -%%% MasterEvMgrRef = atom() -%%% -%%% @doc <p>Call this function in order to get a reference to the -%%% CT master event manager. The reference can be used to e.g. -%%% add a user specific event handler while tests are running. -%%% Example: -%%% <c>gen_event:add_handler(ct_master:get_event_mgr_ref(), my_ev_h, [])</c></p> get_event_mgr_ref() -> ?CT_MEVMGR_REF. -%%%----------------------------------------------------------------- -%%% @spec basic_html(Bool) -> ok -%%% Bool = true | false -%%% -%%% @doc If set to true, the ct_master logs will be written on a -%%% primitive html format, not using the Common Test CSS style -%%% sheet. basic_html(Bool) -> application:set_env(common_test_master, basic_html, Bool), ok. -%%%----------------------------------------------------------------- -%%% @spec esc_chars(Bool) -> ok -%%% Bool = true | false -%%% -%%% @doc If set to false, the ct_master logs will be written without -%%% special characters being escaped in the HTML logs. esc_chars(Bool) -> application:set_env(common_test_master, esc_chars, Bool), ok. @@ -340,7 +233,6 @@ start_master(NodeOptsList,EvHandlers,MasterLogDir,LogDirs,InitOptions,Specs) -> {Master,Result} -> Result end. -%%% @hidden init_master(Parent,NodeOptsList,EvHandlers,MasterLogDir,LogDirs, InitOptions,Specs) -> case whereis(ct_master) of @@ -687,7 +579,6 @@ refresh_logs([],Refreshed) -> %%%----------------------------------------------------------------- %%% NODE CONTROLLER, runs and controls tests on a test node. %%%----------------------------------------------------------------- -%%% @hidden init_node_ctrl(MasterPid,Cookie,Opts) -> %% make sure tests proceed even if connection to master is lost process_flag(trap_exit, true), @@ -742,7 +633,6 @@ start_ct_event() -> %%%----------------------------------------------------------------- %%% Event handling %%%----------------------------------------------------------------- -%%% @hidden status(MasterPid,Event=#event{name=start_make}) -> call(MasterPid,Event); status(MasterPid,Event=#event{name=finished_make}) -> diff --git a/lib/common_test/src/ct_master_event.erl b/lib/common_test/src/ct_master_event.erl index bd4d1efc92..a6ec5a7a75 100644 --- a/lib/common_test/src/ct_master_event.erl +++ b/lib/common_test/src/ct_master_event.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2017. All Rights Reserved. +%% Copyright Ericsson AB 2006-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,13 +18,13 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework Event Handler +%%% Common Test Framework Event Handler %%% -%%% <p>This module implements an event handler that the CT Master +%%% This module implements an event handler that the CT Master %%% uses to handle status and progress notifications sent to the %%% master node during test runs. This module may be used as a %%% template for other event handlers that can be plugged in to -%%% handle logging and reporting on the master node.</p> +%%% handle logging and reporting on the master node. -module(ct_master_event). -behaviour(gen_event). diff --git a/lib/common_test/src/ct_master_logs.erl b/lib/common_test/src/ct_master_logs.erl index 1308720823..ea6f93b565 100644 --- a/lib/common_test/src/ct_master_logs.erl +++ b/lib/common_test/src/ct_master_logs.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2017. All Rights Reserved. +%% Copyright Ericsson AB 2006-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,10 +18,10 @@ %% %CopyrightEnd% %% -%%% @doc Logging functionality for Common Test Master. +%%% Logging functionality for Common Test Master. %%% -%%% <p>This module implements a logger for the master -%%% node.</p> +%%% This module implements a logger for the master +%%% node. -module(ct_master_logs). -export([start/2, make_all_runs_index/0, log/3, nodedir/2, diff --git a/lib/common_test/src/ct_master_status.erl b/lib/common_test/src/ct_master_status.erl index b27fdd341e..cb01220121 100644 --- a/lib/common_test/src/ct_master_status.erl +++ b/lib/common_test/src/ct_master_status.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2017. All Rights Reserved. +%% Copyright Ericsson AB 2006-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,12 +18,12 @@ %% %CopyrightEnd% %% -%%% @doc Logging functionality for Common Test Master. +%%% doc Logging functionality for Common Test Master. %%% -%%% <p>This module keeps a list of <code>{Node,Status}</code> +%%% This module keeps a list of {Node,Status} %%% tuples. It is possible to anytime during a test run get %%% a snapshot of the test status. The module is an event -%%% handler for the master event manager.</p> +%%% handler for the master event manager. -module(ct_master_status). -behaviour(gen_event). diff --git a/lib/common_test/src/ct_netconfc.hrl b/lib/common_test/src/ct_netconfc.hrl index 5eeeafa318..1d81c762ba 100644 --- a/lib/common_test/src/ct_netconfc.hrl +++ b/lib/common_test/src/ct_netconfc.hrl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2012-2016. All Rights Reserved. +%% Copyright Ericsson AB 2012-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,9 +24,7 @@ %% This file defines constant values and records used by the %% netconf client ct_netconfc. %% -%% @author Support -%% @doc Netconf Client Interface. -%% @end +%% Netconf Client Interface. %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- diff --git a/lib/common_test/src/ct_property_test.erl b/lib/common_test/src/ct_property_test.erl index 94ccb59af9..f51f454d08 100644 --- a/lib/common_test/src/ct_property_test.erl +++ b/lib/common_test/src/ct_property_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -28,46 +28,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% @doc EXPERIMENTAL support in common-test for calling property based tests. -%%% -%%% <p>This module is a first step towards running Property Based testing in the -%%% Common Test framework. A property testing tool like QuickCheck or PropEr is -%%% assumed to be installed.</p> -%%% -%%% <p>The idea is to have a common_test testsuite calling a property testing -%%% tool with special property test suites as defined by that tool. In this manual -%%% we assume the usual Erlang Application directory structure. The tests are -%%% collected in the application's <c>test</c> directory. The test directory -%%% has a sub-directory called <c>property_test</c> where everything needed for -%%% the property tests are collected.</p> -%%% -%%% <p>A typical ct test suite using <c>ct_property_test</c> is organized as follows: -%%% </p> -%%% ``` -%%% -include_lib("common_test/include/ct.hrl"). -%%% -%%% all() -> [prop_ftp_case]. -%%% -%%% init_per_suite(Config) -> -%%% ct_property_test:init_per_suite(Config). -%%% -%%% %%%---- test case -%%% prop_ftp_case(Config) -> -%%% ct_property_test:quickcheck( -%%% ftp_simple_client_server:prop_ftp(Config), -%%% Config -%%% ). -%%% ''' -%%% -%%% <warning> -%%% <p> -%%% This is experimental code which may be changed or removed -%%% anytime without any warning. -%%% </p> -%%% </warning> -%%% -%%% @end - -module(ct_property_test). %% API @@ -76,19 +36,6 @@ -include_lib("common_test/include/ct.hrl"). -%%%----------------------------------------------------------------- -%%% @spec init_per_suite(Config) -> Config | {skip,Reason} -%%% -%%% @doc Initializes Config for property testing. -%%% -%%% <p>The function investigates if support is available for either Quickcheck, PropEr, -%%% or Triq. -%%% The options <c>{property_dir,AbsPath}</c> and -%%% <c>{property_test_tool,Tool}</c> is set in the Config returned.</p> -%%% <p>The function is intended to be called in the init_per_suite in the test suite.</p> -%%% <p>The property tests are assumed to be in the subdirectory <c>property_test</c>.</p> -%%% @end - init_per_suite(Config) -> case which_module_exists([eqc,proper,triq]) of {ok,ToolModule} -> @@ -108,14 +55,6 @@ init_per_suite(Config) -> {skip, "No property testing tool found"} end. -%%%----------------------------------------------------------------- -%%% @spec quickcheck(Property, Config) -> true | {fail,Reason} -%%% -%%% @doc Call quickcheck and return the result in a form suitable for common_test. -%%% -%%% <p>The function is intended to be called in the test cases in the test suite.</p> -%%% @end - quickcheck(Property, Config) -> Tool = proplists:get_value(property_test_tool,Config), F = function_name(quickcheck, Tool), diff --git a/lib/common_test/src/ct_release_test.erl b/lib/common_test/src/ct_release_test.erl index 4af9afb45b..60d17f43dc 100644 --- a/lib/common_test/src/ct_release_test.erl +++ b/lib/common_test/src/ct_release_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2014-2017. All Rights Reserved. +%% Copyright Ericsson AB 2014-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ %% %CopyrightEnd% %% %%----------------------------------------------------------------- -%% @doc EXPERIMENTAL support for testing of upgrade. +%% EXPERIMENTAL support for testing of upgrade. %% %% This is a library module containing support for test of release %% related activities in one or more applications. Currenty it @@ -27,7 +27,7 @@ %% == Configuration == %% %% In order to find version numbers of applications to upgrade from, -%% `{@module}' needs to access and start old OTP +%% ct_release_test needs to access and start old OTP %% releases. A `common_test' configuration file can be used for %% specifying the location of such releases, for example: %% @@ -39,48 +39,45 @@ %% The configuration file should preferably point out the latest patch %% level on each major release. %% -%% If no such configuration file is given, {@link init/1} will return -%% `{skip,Reason}' and any attempt at running {@link upgrade/4} +%% If no such configuration file is given, init/1 will return +%% {skip,Reason} and any attempt at running upgrade/4 %% will fail. %% %% == Callback functions == %% -%% The following functions should be exported from a {@module} +%% The following functions should be exported from a ct_release_test %% callback module. %% %% All callback functions are called on the node where the upgrade is %% executed. %% -%% <dl> -%% <dt>Module:upgrade_init(CtData,State) -> NewState</dt> -%% <dd>Types: +%% Module:upgrade_init(CtData,State) -> NewState +%% Types: %% -%% <b><code>CtData = {@link ct_data()}</code></b><br/> -%% <b><code>State = NewState = cb_state()</code></b> +%% CtData = ct_data() +%% State = NewState = cb_state() %% %% Initialyze system before upgrade test starts. %% %% This function is called before the upgrade is started. All -%% applications given in {@link upgrade/4} are already started by +%% applications given in upgrade/4 are already started by %% the boot script, so this callback is intended for additional %% initialization, if necessary. %% -%% <code>CtData</code> is an opaque data structure which shall be used -%% in any call to <code>ct_release_test</code> inside the callback. +%% CtData is an opaque data structure which shall be used +%% in any call to ct_release_test inside the callback. %% %% Example: %% -%% ``` %% upgrade_init(CtData,State) -> %% {ok,{FromVsn,ToVsn}} = ct_release_test:get_app_vsns(CtData,myapp), -%% open_connection(State).''' -%% </dd> +%% open_connection(State). %% -%% <dt>Module:upgrade_upgraded(CtData,State) -> NewState</dt> -%% <dd>Types: +%% Module:upgrade_upgraded(CtData,State) -> NewState +%% Types: %% -%% <b><code>CtData = {@link ct_data()}</code></b><br/> -%% <b><code>State = NewState = cb_state()</code></b> +%% CtData = ct_data() +%% State = NewState = cb_state() %% %% Check that upgrade was successful. %% @@ -89,21 +86,19 @@ %% been made permanent. It allows application specific checks to %% ensure that the upgrade was successful. %% -%% <code>CtData</code> is an opaque data structure which shall be used -%% in any call to <code>ct_release_test</code> inside the callback. +%% CtData is an opaque data structure which shall be used +%% in any call to ct_release_test inside the callback. %% %% Example: %% -%% ``` %% upgrade_upgraded(CtData,State) -> -%% check_connection_still_open(State).''' -%% </dd> +%% check_connection_still_open(State). %% -%% <dt>Module:upgrade_downgraded(CtData,State) -> NewState</dt> -%% <dd>Types: +%% Module:upgrade_downgraded(CtData,State) -> NewState +%% Types: %% -%% <b><code>CtData = {@link ct_data()}</code></b><br/> -%% <b><code>State = NewState = cb_state()</code></b> +%% CtData = ct_data() +%% State = NewState = cb_state() %% %% Check that downgrade was successful. %% @@ -112,17 +107,13 @@ %% made permanent. It allows application specific checks to ensure %% that the downgrade was successful. %% -%% <code>CtData</code> is an opaque data structure which shall be used -%% in any call to <code>ct_release_test</code> inside the callback. +%% CtData is an opaque data structure which shall be used +%% in any call to ct_release_test inside the callback. %% %% Example: %% -%% ``` %% upgrade_downgraded(CtData,State) -> -%% check_connection_closed(State).''' -%% </dd> -%% </dl> -%% @end +%% check_connection_closed(State). %%----------------------------------------------------------------- -module(ct_release_test). @@ -152,7 +143,7 @@ Config :: config(), Result :: config() | SkipOrFail, SkipOrFail :: {skip,Reason} | {fail,Reason}. -%% @doc Initialize `{@module}'. +%% Initialize ct_release_test. %% %% This function can be called from any of the %% `init_per_*' functions in the test suite. It updates @@ -168,9 +159,8 @@ %% %% Example: %% -%% ``` %% init_per_suite(Config) -> -%% ct_release_test:init(Config).''' +%% ct_release_test:init(Config). %% init(Config) -> try init_upgrade_test() of @@ -194,47 +184,42 @@ init(Config) -> Callback :: {module(),InitState}, InitState :: cb_state(), Config :: config(). -%% @doc Test upgrade of the given application(s). +%% Test upgrade of the given application(s). %% %% This function can be called from a test case. It requires that -%% `Config' has been initialized by calling {@link -%% init/1} prior to this, for example from `init_per_suite/1'. +%% `Config' has been initialized by calling +%% init/1 prior to this, for example from `init_per_suite/1'. %% %% Upgrade tests are performed as follows: %% -%% <ol> -%% <li>Figure out which OTP release to test upgrade +%% Figure out which OTP release to test upgrade %% from. Start a node running that release and find the %% application versions on that node. Terminate the -%% node.</li> -%% <li>Figure out all dependencies for the applications under -%% test.</li> -%% <li>Create a release containing the core +%% node. +%% Figure out all dependencies for the applications under +%% test. +%% Create a release containing the core %% applications `kernel', `stdlib' and `sasl' %% in addition to the application(s) under test and all %% dependencies of these. The versions of the applications %% under test will be the ones found on the OTP release to %% upgrade from. The versions of all other applications will %% be those found on the current node, i.e. the common_test -%% node. This is the "From"-release.</li> -%% <li>Create another release containing the same +%% node. This is the "From"-release. +%% Create another release containing the same %% applications as in the previous step, but with all %% application versions taken from the current node. This is -%% the "To"-release.</li> -%% <li>Install the "From"-release and start a new node -%% running this release.</li> -%% <li>Perform the upgrade test and allow customized +%% the "To"-release. +%% Install the "From"-release and start a new node +%% running this release. +%% Perform the upgrade test and allow customized %% control by using callbacks: -%% <ol> -%% <li>Callback: `upgrade_init/2'</li> -%% <li>Unpack the new release</li> -%% <li>Install the new release</li> -%% <li>Callback: `upgrade_upgraded/2'</li> -%% <li>Install the original release</li> -%% <li>Callback: `upgrade_downgraded/2'</li> -%% </ol> -%% </li> -%% </ol> +%% Callback: `upgrade_init/2' +%% Unpack the new release +%% Install the new release +%% Callback: `upgrade_upgraded/2' +%% Install the original release +%% Callback: `upgrade_downgraded/2' %% %% `App' or `Apps' %% specifies the applications under test, i.e. the applications @@ -244,27 +229,25 @@ init(Config) -> %% %% `Level' specifies which OTP release to %% pick the "From" versions from. -%% <dl> -%% <dt>major</dt> -%% <dd>From verions are picked from the previous major +%% major +%% From verions are picked from the previous major %% release. For example, if the test is run on an OTP-17 -%% node, `{@module}' will pick the application +%% node, ct_release_test will pick the application %% "From" versions from an OTP installation running OTP -%% R16B.</dd> +%% R16B. %% -%% <dt>minor</dt> -%% <dd>From verions are picked from the current major +%% minor +%% From verions are picked from the current major %% release. For example, if the test is run on an OTP-17 -%% node, `{@module}' will pick the application +%% node, ct_release_test will pick the application %% "From" versions from an OTP installation running an -%% earlier patch level of OTP-17.</dd> -%% </dl> +%% earlier patch level of OTP-17. %% %% The application "To" versions are allways picked from the %% current node, i.e. the common_test node. %% %% `Callback' specifies the module (normally the -%% test suite) which implements the {@section Callback functions}, and +%% test suite) which implements the Callback functions, and %% the initial value of the `State' variable used in these %% functions. %% @@ -273,10 +256,8 @@ init(Config) -> %% %% Example: %% -%% ``` %% minor_upgrade(Config) -> %% ct_release_test:upgrade(ssl,minor,{?MODULE,[]},Config). -%% ''' %% upgrade(App,Level,Callback,Config) when is_atom(App) -> upgrade([App],Level,Callback,Config); @@ -318,10 +299,10 @@ upgrade(Apps,Level,Callback,Config) -> -spec cleanup(Config) -> Result when Config :: config(), Result :: config(). -%% @doc Clean up after tests. +%% Clean up after tests. %% %% This function shall be called from the `end_per_*' function -%% complementing the `init_per_*' function where {@link init/1} +%% complementing the `init_per_*' function where init/1 %% is called. %% %% It cleans up after the test, for example kills hanging @@ -329,9 +310,8 @@ upgrade(Apps,Level,Callback,Config) -> %% %% Example: %% -%% ``` %% end_per_suite(Config) -> -%% ct_release_test:cleanup(Config).''' +%% ct_release_test:cleanup(Config). %% cleanup(Config) -> AllNodes = [node_name(?testnode)|nodes()], @@ -352,15 +332,15 @@ cleanup(Config) -> From :: string(), To :: string(), Reason :: {app_not_found,App}. -%% @doc Get versions involved in this upgrade for the given application. +%% Get versions involved in this upgrade for the given application. %% %% This function can be called from inside any of the callback %% functions. It returns the old (From) and new (To) versions involved %% in the upgrade/downgrade test for the given application. %% -%% <code>CtData</code> must be the first argument received in the +%% CtData must be the first argument received in the %% calling callback function - an opaque data structure set by -%% <code>ct_release_tests</code>. +%% ct_release_tests. get_app_vsns(#ct_data{from=FromApps,to=ToApps},App) -> case {lists:keyfind(App,1,FromApps),lists:keyfind(App,1,ToApps)} of {{App,FromVsn,_},{App,ToVsn,_}} -> @@ -380,16 +360,16 @@ get_app_vsns(#ct_data{from=FromApps,to=ToApps},App) -> Down :: [Instr], Instr :: term(), Reason :: {app_not_found,App} | {vsn_not_found,{App,From}}. -%% @doc Get appup instructions for the given application. +%% Get appup instructions for the given application. %% %% This function can be called from inside any of the callback %% functions. It reads the appup file for the given application and %% returns the instructions for upgrade and downgrade for the versions %% in the test. %% -%% <code>CtData</code> must be the first argument received in the +%% CtData must be the first argument received in the %% calling callback function - an opaque data structure set by -%% <code>ct_release_tests</code>. +%% ct_release_tests. %% %% See reference manual for appup files for types definitions for the %% instructions. diff --git a/lib/common_test/src/ct_repeat.erl b/lib/common_test/src/ct_repeat.erl index 177ef37d1f..8b1c7d47bb 100644 --- a/lib/common_test/src/ct_repeat.erl +++ b/lib/common_test/src/ct_repeat.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2017. All Rights Reserved. +%% Copyright Ericsson AB 2007-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,14 +18,14 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework module that handles repeated test runs +%%% doc Common Test Framework module that handles repeated test runs %%% -%%% <p>This module exports functions for repeating tests. The following +%%% This module exports functions for repeating tests. The following %%% start flags (or equivalent ct:run_test/1 options) are supported: %%% -until <StopTime>, StopTime = YYMoMoDDHHMMSS | HHMMSS %%% -duration <DurTime>, DurTime = HHMMSS %%% -force_stop [skip_rest] -%%% -repeat <N>, N = integer()</p> +%%% -repeat <N>, N = integer() -module(ct_repeat). diff --git a/lib/common_test/src/ct_rpc.erl b/lib/common_test/src/ct_rpc.erl index b4a0bc9d74..cef5ad14e5 100644 --- a/lib/common_test/src/ct_rpc.erl +++ b/lib/common_test/src/ct_rpc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,8 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test specific layer on Erlang/OTP rpc. - -module(ct_rpc). %%% API @@ -29,49 +27,12 @@ %%%========================================================================= %%% API %%%========================================================================= -%%% @spec app_node(App, Candidates) -> NodeName -%%% -%%% App = atom() -%%% Candidates = [NodeName] -%%% NodeName = atom() -%%% -%%% @doc From a set of candidate nodes determines which of them is -%%% running the application App. If none of the candidate nodes -%%% is running the application the function will make the test case -%%% calling this function fail. This function is the same as calling -%%% <code>app_node(App, Candidates, true)</code>. -%%% app_node(App, Candidates) -> app_node(App, Candidates, true, []). -%%% @spec app_node(App, Candidates, FailOnBadRPC) -> NodeName -%%% -%%% App = atom() -%%% Candidates = [NodeName] -%%% NodeName = atom() -%%% FailOnBadRPC = true | false -%%% -%%% @doc Same as <code>app_node/2</code> only the <code>FailOnBadRPC</code> -%%% argument will determine if the search for a candidate node should -%%% stop or not if <code>badrpc</code> is received at some point. -%%% app_node(App, Candidates, FailOnBadRPC) -> app_node(App, Candidates, FailOnBadRPC, []). -%%% @spec app_node(App, Candidates, FailOnBadRPC, Cookie) -> NodeName -%%% -%%% App = atom() -%%% Candidates = [NodeName] -%%% NodeName = atom() -%%% FailOnBadRPC = true | false -%%% Cookie = atom() -%%% -%%% @doc Same as <code>app_node/2</code> only the <code>FailOnBadRPC</code> -%%% argument will determine if the search for a candidate node should -%%% stop or not if <code>badrpc</code> is received at some point. -%%% The cookie on the client node will be set to <code>Cookie</code> -%%% for this rpc operation (use to match the server node cookie). -%%% app_node(App, [], _, _) -> ct:fail({application_not_running, App}); @@ -96,49 +57,12 @@ app_node(App, _Candidates = [CandidateNode | Nodes], FailOnBadRPC, Cookie) -> end end. -%%% @spec call(Node, Module, Function, Args) -> term() | {badrpc, Reason} -%%% -%%% @doc Same as call(Node, Module, Function, Args, infinity) -%%% call(Node, Module, Function, Args) -> call(Node, Module, Function, Args, infinity, []). -%%% @spec call(Node, Module, Function, Args, TimeOut) -> -%%% term() | {badrpc, Reason} -%%% Node = NodeName | {Fun, FunArgs} -%%% Fun = fun() -%%% FunArgs = term() -%%% NodeName = atom() -%%% Module = atom() -%%% Function = atom() -%%% Args = [term()] -%%% Reason = timeout | term() -%%% -%%% @doc Evaluates apply(Module, Function, Args) on the node Node. -%%% Returns whatever Function returns or {badrpc, Reason} if the -%%% remote procedure call fails. If Node is {Fun, FunArgs} applying -%%% Fun to FunArgs should return a node name. call(Node, Module, Function, Args, TimeOut) -> call(Node, Module, Function, Args, TimeOut, []). -%%% @spec call(Node, Module, Function, Args, TimeOut, Cookie) -> -%%% term() | {badrpc, Reason} -%%% Node = NodeName | {Fun, FunArgs} -%%% Fun = fun() -%%% FunArgs = term() -%%% NodeName = atom() -%%% Module = atom() -%%% Function = atom() -%%% Args = [term()] -%%% Reason = timeout | term() -%%% Cookie = atom() -%%% -%%% @doc Evaluates apply(Module, Function, Args) on the node Node. -%%% Returns whatever Function returns or {badrpc, Reason} if the -%%% remote procedure call fails. If Node is {Fun, FunArgs} applying -%%% Fun to FunArgs should return a node name. -%%% The cookie on the client node will be set to <code>Cookie</code> -%%% for this rpc operation (use to match the server node cookie). call({Fun, FunArgs}, Module, Function, Args, TimeOut, Cookie) -> Node = Fun(FunArgs), call(Node, Module, Function, Args, TimeOut, Cookie); @@ -148,42 +72,9 @@ call(Node, Module, Function, Args, TimeOut, Cookie) when is_atom(Node) -> _ = set_the_cookie(Cookie0), Result. -%%% @spec cast(Node, Module, Function, Args) -> ok -%%% Node = NodeName | {Fun, FunArgs} -%%% Fun = fun() -%%% FunArgs = term() -%%% NodeName = atom() -%%% Module = atom() -%%% Function = atom() -%%% Args = [term()] -%%% Reason = timeout | term() -%%% -%%% @doc Evaluates apply(Module, Function, Args) on the node Node. -%%% No response is delivered and the process which makes the call is -%%% not suspended until the evaluation is compleated as in the case of -%%% call/[3,4]. If Node is {Fun, FunArgs} applying -%%% Fun to FunArgs should return a node name. cast(Node, Module, Function, Args) -> cast(Node, Module, Function, Args, []). -%%% @spec cast(Node, Module, Function, Args, Cookie) -> ok -%%% Node = NodeName | {Fun, FunArgs} -%%% Fun = fun() -%%% FunArgs = term() -%%% NodeName = atom() -%%% Module = atom() -%%% Function = atom() -%%% Args = [term()] -%%% Reason = timeout | term() -%%% Cookie = atom() -%%% -%%% @doc Evaluates apply(Module, Function, Args) on the node Node. -%%% No response is delivered and the process which makes the call is -%%% not suspended until the evaluation is compleated as in the case of -%%% call/[3,4]. If Node is {Fun, FunArgs} applying -%%% Fun to FunArgs should return a node name. -%%% The cookie on the client node will be set to <code>Cookie</code> -%%% for this rpc operation (use to match the server node cookie). cast({Fun, FunArgs}, Module, Function, Args, Cookie) -> Node = Fun(FunArgs), cast(Node, Module, Function, Args, Cookie); @@ -196,7 +87,6 @@ cast(Node, Module, Function, Args, Cookie) when is_atom(Node) -> %%%---------- Internal ----------- -%%% @hidden set_the_cookie([]) -> []; set_the_cookie(Cookie) -> diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index afc5fee4f7..223aa06e64 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2017. All Rights Reserved. +%% Copyright Ericsson AB 2004-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,11 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework test execution control module. -%%% -%%% <p>This module exports functions for installing and running tests -%%% withing the Common Test Framework.</p> - -module(ct_run). %% Script interface @@ -84,17 +79,6 @@ tests, starter}). -%%%----------------------------------------------------------------- -%%% @spec script_start() -> term() -%%% -%%% @doc Start tests via the ct_run program or script. -%%% -%%% <p>Example:<br/><code>./ct_run -config config.ctc -dir -%%% $TEST_DIR</code></p> -%%% -%%% <p>Example:<br/><code>./ct_run -config config.ctc -suite -%%% $SUITE_PATH/$SUITE_NAME [-case $CASE_NAME]</code></p> -%%% script_start() -> process_flag(trap_exit, true), Init = init:get_arguments(), @@ -799,9 +783,6 @@ script_start4(#opts{shell = true, cover = Cover}, _) -> script_start4(Opts = #opts{tests = Tests}, Args) -> do_run(Tests, [], Opts, Args). -%%%----------------------------------------------------------------- -%%% @spec script_usage() -> ok -%%% @doc Print usage information for <code>ct_run</code>. script_usage() -> io:format("\nUsage:\n\n"), io:format("Run tests from command line:\n\n" @@ -885,9 +866,6 @@ script_usage() -> "\n\t [-basic_html]" "\n\t [-no_esc_chars]\n\n"). -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:install/1 install(Opts) -> install(Opts, "."). @@ -931,15 +909,6 @@ install(Opts, LogDir) -> variables_file_name(Dir) -> filename:join(Dir, "variables-"++atom_to_list(node())). -%%%----------------------------------------------------------------- -%%% @spec run_test(Opts) -> Result -%%% Opts = [tuple()] -%%% Result = [TestResult] | {error,Reason} -%%% -%%% @doc Start tests from the erlang shell or from an erlang program. -%%% @equiv ct:run_test/1 -%%%----------------------------------------------------------------- - run_test(StartOpt) when is_tuple(StartOpt) -> run_test([StartOpt]); @@ -1427,14 +1396,6 @@ run_dir(Opts = #opts{logdir = LogDir, exit({error,{incorrect_start_options,{Dir,Suite,GsAndCs}}}) end. -%%%----------------------------------------------------------------- -%%% @spec run_testspec(TestSpec) -> Result -%%% TestSpec = [term()] -%%% -%%% @doc Run test specified by <code>TestSpec</code>. The terms are -%%% the same as those used in test specification files. -%%% @equiv ct:run_testspec/1 -%%%----------------------------------------------------------------- run_testspec(TestSpec) -> CTPid = spawn(run_testspec1_fun(TestSpec)), Ref = monitor(process, CTPid), @@ -1634,9 +1595,6 @@ delistify([E]) -> E; delistify(E) -> E. -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:run/3 run(TestDir, Suite, Cases) -> case install([]) of ok -> @@ -1645,9 +1603,6 @@ run(TestDir, Suite, Cases) -> Error end. -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:run/2 run(TestDir, Suite) when is_list(TestDir), is_integer(hd(TestDir)) -> case install([]) of ok -> @@ -1656,9 +1611,6 @@ run(TestDir, Suite) when is_list(TestDir), is_integer(hd(TestDir)) -> Error end. -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:run/1 run(TestDirs) -> case install([]) of ok -> @@ -2068,16 +2020,9 @@ get_bad_suites([], BadSuites) -> BadSuites. - -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:step/3 step(TestDir, Suite, Case) -> step(TestDir, Suite, Case, []). -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:step/4 step(TestDir, Suite, Case, Opts) when is_list(TestDir), is_atom(Suite), is_atom(Case), Suite =/= all, Case =/= all -> diff --git a/lib/common_test/src/ct_slave.erl b/lib/common_test/src/ct_slave.erl index 0c16ad5980..dde33440be 100644 --- a/lib/common_test/src/ct_slave.erl +++ b/lib/common_test/src/ct_slave.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -17,13 +17,6 @@ %% %% %CopyrightEnd% -%%% @doc Common Test Framework functions for starting and stopping nodes for -%%% Large Scale Testing. -%%% -%%% <p>This module exports functions which are used by the Common Test Master -%%% to start and stop "slave" nodes. It is the default callback module for the -%%% <code>{init, node_start}</code> term of the Test Specification.</p> - %%---------------------------------------------------------------------- %% File : ct_slave.erl %% Description : CT module for starting nodes for large-scale testing. @@ -41,42 +34,9 @@ kill_if_fail, erl_flags, env, ssh_port, ssh_opts, stop_timeout}). -%%%----------------------------------------------------------------- -%%% @spec start(Node) -> Result -%%% Node = atom() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = already_started | -%%% started_not_connected | -%%% boot_timeout | -%%% init_timeout | -%%% startup_timeout | -%%% not_alive -%%% NodeName = atom() -%%% @doc Starts an Erlang node with name <code>Node</code> on the local host. -%%% @see start/3 start(Node) -> start(gethostname(), Node). -%%%----------------------------------------------------------------- -%%% @spec start(HostOrNode, NodeOrOpts) -> Result -%%% HostOrNode = atom() -%%% NodeOrOpts = atom() | list() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = already_started | -%%% started_not_connected | -%%% boot_timeout | -%%% init_timeout | -%%% startup_timeout | -%%% not_alive -%%% NodeName = atom() -%%% @doc Starts an Erlang node with default options on a specified -%%% host, or on the local host with specified options. That is, -%%% the call is interpreted as <code>start(Host, Node)</code> when the -%%% second argument is atom-valued and <code>start(Node, Opts)</code> -%%% when it's list-valued. -%%% @see start/3 start(_HostOrNode = Node, _NodeOrOpts = Opts) %% match to satiate edoc when is_list(Opts) -> start(gethostname(), Node, Opts); @@ -84,104 +44,6 @@ start(_HostOrNode = Node, _NodeOrOpts = Opts) %% match to satiate edoc start(Host, Node) -> start(Host, Node, []). -%%%----------------------------------------------------------------- -%%% @spec start(Host, Node, Opts) -> Result -%%% Node = atom() -%%% Host = atom() -%%% Opts = [OptTuples] -%%% OptTuples = {username, Username} | -%%% {password, Password} | -%%% {boot_timeout, BootTimeout} | {init_timeout, InitTimeout} | -%%% {startup_timeout, StartupTimeout} | -%%% {startup_functions, StartupFunctions} | -%%% {monitor_master, Monitor} | -%%% {kill_if_fail, KillIfFail} | -%%% {erl_flags, ErlangFlags} | -%%% {env, [{EnvVar,Value}]} -%%% Username = string() -%%% Password = string() -%%% BootTimeout = integer() -%%% InitTimeout = integer() -%%% StartupTimeout = integer() -%%% StartupFunctions = [StartupFunctionSpec] -%%% StartupFunctionSpec = {Module, Function, Arguments} -%%% Module = atom() -%%% Function = atom() -%%% Arguments = [term] -%%% Monitor = bool() -%%% KillIfFail = bool() -%%% ErlangFlags = string() -%%% EnvVar = string() -%%% Value = string() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = already_started | -%%% started_not_connected | -%%% boot_timeout | -%%% init_timeout | -%%% startup_timeout | -%%% not_alive -%%% NodeName = atom() -%%% @doc Starts an Erlang node with name <code>Node</code> on host -%%% <code>Host</code> as specified by the combination of options in -%%% <code>Opts</code>. -%%% -%%% <p>Options <code>Username</code> and <code>Password</code> will be used -%%% to log in onto the remote host <code>Host</code>. -%%% Username, if omitted, defaults to the current user name, -%%% and password is empty by default.</p> -%%% -%%% <p>A list of functions specified in the <code>Startup</code> option will be -%%% executed after startup of the node. Note that all used modules should be -%%% present in the code path on the <code>Host</code>.</p> -%%% -%%% <p>The timeouts are applied as follows:</p> -%%% <list> -%%% <item> -%%% <code>BootTimeout</code> - time to start the Erlang node, in seconds. -%%% Defaults to 3 seconds. If node does not become pingable within this time, -%%% the result <code>{error, boot_timeout, NodeName}</code> is returned; -%%% </item> -%%% <item> -%%% <code>InitTimeout</code> - time to wait for the node until it calls the -%%% internal callback function informing master about successfull startup. -%%% Defaults to one second. -%%% In case of timed out message the result -%%% <code>{error, init_timeout, NodeName}</code> is returned; -%%% </item> -%%% <item> -%%% <code>StartupTimeout</code> - time to wait intil the node finishes to run -%%% the <code>StartupFunctions</code>. Defaults to one second. -%%% If this timeout occurs, the result -%%% <code>{error, startup_timeout, NodeName}</code> is returned. -%%% </item> -%%% </list> -%%% -%%% <p>Option <code>monitor_master</code> specifies, if the slave node should be -%%% stopped in case of master node stop. Defaults to false.</p> -%%% -%%% <p>Option <code>kill_if_fail</code> specifies, if the slave node should be -%%% killed in case of a timeout during initialization or startup. -%%% Defaults to true. Note that node also may be still alive it the boot -%%% timeout occurred, but it will not be killed in this case.</p> -%%% -%%% <p>Option <code>erlang_flags</code> specifies, which flags will be added -%%% to the parameters of the <code>erl</code> executable.</p> -%%% -%%% <p>Option <code>env</code> specifies a list of environment variables -%%% that will extended the environment.</p> -%%% -%%% <p>Special return values are:</p> -%%% <list> -%%% <item><code>{error, already_started, NodeName}</code> - if the node with -%%% the given name is already started on a given host;</item> -%%% <item><code>{error, started_not_connected, NodeName}</code> - if node is -%%% started, but not connected to the master node.</item> -%%% <item><code>{error, not_alive, NodeName}</code> - if node on which the -%%% <code>ct_slave:start/3</code> is called, is not alive. Note that -%%% <code>NodeName</code> is the name of current node in this case.</item> -%%% </list> -%%% start(Host, Node, Opts) -> ENode = enodename(Host, Node), case erlang:is_alive() of @@ -199,36 +61,9 @@ start(Host, Node, Opts) -> end end. -%%%----------------------------------------------------------------- -%%% @spec stop(Node) -> Result -%%% Node = atom() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = not_started | -%%% not_connected | -%%% stop_timeout -%%% NodeName = atom() -%%% @doc Stops the running Erlang node with name <code>Node</code> on -%%% the localhost. stop(Node) -> stop(gethostname(), Node). -%%%----------------------------------------------------------------- -%%% @spec stop(HostOrNode, NodeOrOpts) -> Result -%%% HostOrNode = atom() -%%% NodeOrOpts = atom() | list() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = not_started | -%%% not_connected | -%%% stop_timeout -%%% NodeName = atom() -%%% @doc Stops the running Erlang node with default options on a specified -%%% host, or on the local host with specified options. That is, -%%% the call is interpreted as <code>stop(Host, Node)</code> when the -%%% second argument is atom-valued and <code>stop(Node, Opts)</code> -%%% when it's list-valued. -%%% @see stop/3 stop(_HostOrNode = Node, _NodeOrOpts = Opts) %% match to satiate edoc when is_list(Opts) -> stop(gethostname(), Node, Opts); @@ -236,26 +71,6 @@ stop(_HostOrNode = Node, _NodeOrOpts = Opts) %% match to satiate edoc stop(Host, Node) -> stop(Host, Node, []). -%%% @spec stop(Host, Node, Opts) -> Result -%%% Host = atom() -%%% Node = atom() -%%% Opts = [OptTuples] -%%% OptTuples = {stop_timeout, StopTimeout} -%%% StopTimeout = integer() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = not_started | -%%% not_connected | -%%% stop_timeout -%%% NodeName = atom() -%%% @doc Stops the running Erlang node with name <code>Node</code> on -%%% host <code>Host</code> as specified by options <code>Opts</code>. -%%% -%%% <p>Option <code>stop_timeout</code> specifies, in seconds, -%%% the time to wait until the node is disconnected. -%%% Defaults to 5 seconds. If this timeout occurs, -%%% the result <code>{error, stop_timeout, NodeName}</code> is returned. -%%% stop(Host, Node, Opts) -> ENode = enodename(Host, Node), case is_started(ENode) of @@ -300,19 +115,16 @@ fetch_options(Options) -> stop_timeout=StopTimeout}. % send a message when slave node is started -% @hidden slave_started(ENode, MasterPid) -> MasterPid ! {node_started, ENode}, ok. % send a message when slave node has finished startup -% @hidden slave_ready(ENode, MasterPid) -> MasterPid ! {node_ready, ENode}, ok. % start monitoring of the master node -% @hidden monitor_master(MasterNode) -> spawn(fun() -> monitor_master_int(MasterNode) end). diff --git a/lib/common_test/src/ct_snmp.erl b/lib/common_test/src/ct_snmp.erl index 5844909d17..27b74dd04e 100644 --- a/lib/common_test/src/ct_snmp.erl +++ b/lib/common_test/src/ct_snmp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,139 +18,8 @@ %% %CopyrightEnd% %% -%%% @doc Common Test user interface module for the OTP snmp application -%%% -%%% <p>The purpose of this module is to make snmp configuration easier for -%%% the test case writer. Many test cases can use default values for common -%%% operations and then no snmp configuration files need to be supplied. When -%%% it is necessary to change particular configuration parameters, a subset -%%% of the relevant snmp configuration files may be passed to <code>ct_snmp</code> -%%% by means of Common Test configuration files. -%%% For more specialized configuration parameters, it is possible to place a -%%% "simple snmp configuration file" in the test suite data directory. -%%% To simplify the test suite, Common Test keeps track -%%% of some of the snmp manager information. This way the test suite doesn't -%%% have to handle as many input parameters as it would if it had to interface the -%%% OTP snmp manager directly.</p> -%%% -%%% <p> The following snmp manager and agent parameters are configurable: </p> -%%% -%%% <pre> -%%% {snmp, -%%% %%% Manager config -%%% [{start_manager, boolean()} % Optional - default is true -%%% {users, [{user_name(), [call_back_module(), user_data()]}]}, %% Optional -%%% {usm_users, [{usm_user_name(), [usm_config()]}]},%% Optional - snmp v3 only -%%% % managed_agents is optional -%%% {managed_agents,[{agent_name(), [user_name(), agent_ip(), agent_port(), [agent_config()]]}]}, -%%% {max_msg_size, integer()}, % Optional - default is 484 -%%% {mgr_port, integer()}, % Optional - default is 5000 -%%% {engine _id, string()}, % Optional - default is "mgrEngine" -%%% -%%% %%% Agent config -%%% {start_agent, boolean()}, % Optional - default is false -%%% {agent_sysname, string()}, % Optional - default is "ct_test" -%%% {agent_manager_ip, manager_ip()}, % Optional - default is localhost -%%% {agent_vsns, list()}, % Optional - default is [v2] -%%% {agent_trap_udp, integer()}, % Optional - default is 5000 -%%% {agent_udp, integer()}, % Optional - default is 4000 -%%% {agent_notify_type, atom()}, % Optional - default is trap -%%% {agent_sec_type, sec_type()}, % Optional - default is none -%%% {agent_passwd, string()}, % Optional - default is "" -%%% {agent_engine_id, string()}, % Optional - default is "agentEngine" -%%% {agent_max_msg_size, string()},% Optional - default is 484 -%%% -%%% %% The following parameters represents the snmp configuration files -%%% %% context.conf, standard.conf, community.conf, vacm.conf, -%%% %% usm.conf, notify.conf, target_addr.conf and target_params.conf. -%%% %% Note all values in agent.conf can be altered by the parametes -%%% %% above. All these configuration files have default values set -%%% %% up by the snmp application. These values can be overridden by -%%% %% suppling a list of valid configuration values or a file located -%%% %% in the test suites data dir that can produce a list -%%% %% of valid configuration values if you apply file:consult/1 to the -%%% %% file. -%%% {agent_contexts, [term()] | {data_dir_file, rel_path()}}, % Optional -%%% {agent_community, [term()] | {data_dir_file, rel_path()}},% Optional -%%% {agent_sysinfo, [term()] | {data_dir_file, rel_path()}}, % Optional -%%% {agent_vacm, [term()] | {data_dir_file, rel_path()}}, % Optional -%%% {agent_usm, [term()] | {data_dir_file, rel_path()}}, % Optional -%%% {agent_notify_def, [term()] | {data_dir_file, rel_path()}},% Optional -%%% {agent_target_address_def, [term()] | {data_dir_file, rel_path()}},% Optional -%%% {agent_target_param_def, [term()] | {data_dir_file, rel_path()}},% Optional -%%% ]}. -%%% </pre> -%%% -%%% <p>The <code>MgrAgentConfName</code> parameter in the functions -%%% should be a name you allocate in your test suite using a -%%% <code>require</code> statement. -%%% Example (where <code>MgrAgentConfName = snmp_mgr_agent</code>):</p> -%%% <pre> suite() -> [{require, snmp_mgr_agent, snmp}].</pre> -%%% <p>or</p> -%%% <pre> ct:require(snmp_mgr_agent, snmp).</pre> -%%% -%%% <p> Note that Usm users are needed for snmp v3 configuration and are -%%% not to be confused with users.</p> -%%% -%%% <p> Snmp traps, inform and report messages are handled by the -%%% user callback module. For more information about this see -%%% the snmp application. </p> -%%% <p> Note: It is recommended to use the .hrl-files created by the -%%% Erlang/OTP mib-compiler to define the oids. -%%% Example for the getting the erlang node name from the erlNodeTable -%%% in the OTP-MIB:</p> -%%% <pre>Oid = ?erlNodeEntry ++ [?erlNodeName, 1] </pre> -%%% -%%% <p>It is also possible to set values for snmp application configuration -%%% parameters, such as <code>config</code>, <code>server</code>, -%%% <code>net_if</code>, etc (see the "Configuring the application" chapter in -%%% the OTP snmp User's Guide for a list of valid parameters and types). This is -%%% done by defining a configuration data variable on the following form:</p> -%%% <pre> -%%% {snmp_app, [{manager, [snmp_app_manager_params()]}, -%%% {agent, [snmp_app_agent_params()]}]}.</pre> -%%% -%%% <p>A name for the data needs to be allocated in the suite using -%%% <code>require</code> (see example above), and this name passed as -%%% the <code>SnmpAppConfName</code> argument to <code>start/3</code>. -%%% <code>ct_snmp</code> specifies default values for some snmp application -%%% configuration parameters (such as <code>{verbosity,trace}</code> for the -%%% <code>config</code> parameter). This set of defaults will be -%%% merged with the parameters specified by the user, and user values -%%% override <code>ct_snmp</code> defaults.</p> - -module(ct_snmp). -%%% Common Types -%%% @type agent_ip() = ip() -%%% @type manager_ip() = ip() -%%% @type agent_name() = atom() -%%% @type ip() = string() | {integer(), integer(), -%%% integer(), integer()} -%%% @type agent_port() = integer() -%%% @type agent_config() = {Item, Value} -%%% @type user_name() = atom() -%%% @type usm_user_name() = string() -%%% @type usm_config() = {Item, Value} -%%% @type call_back_module() = atom() -%%% @type user_data() = term() -%%% @type oids() = [oid()] -%%% @type oid() = [byte()] -%%% @type snmpreply() = {error_status(), error_index(), varbinds()} -%%% @type error_status() = noError | atom() -%%% @type error_index() = integer() -%%% @type varbinds() = [varbind()] -%%% @type varbind() = term() -%%% @type value_type() = o ('OBJECT IDENTIFIER') | i ('INTEGER') | -%%% u ('Unsigned32') | g ('Unsigned32') | s ('OCTET STRING') -%%% @type varsandvals() = [var_and_val()] -%%% @type var_and_val() = {oid(), value_type(), value()} -%%% @type sec_type() = none | minimum | semi -%%% @type rel_path() = string() -%%% @type snmp_app_manager_params() = term() -%%% @type snmp_app_agent_params() = term() - - -include("snmp_types.hrl"). -include("inet.hrl"). -include("ct.hrl"). @@ -181,31 +50,9 @@ %%% API %%%========================================================================= -%%%----------------------------------------------------------------- -%%% @spec start(Config, MgrAgentConfName) -> ok -%%% @equiv start(Config, MgrAgentConfName, undefined) start(Config, MgrAgentConfName) -> start(Config, MgrAgentConfName, undefined). -%%% @spec start(Config, MgrAgentConfName, SnmpAppConfName) -> ok -%%% Config = [{Key, Value}] -%%% Key = atom() -%%% Value = term() -%%% MgrAgentConfName = atom() -%%% SnmpConfName = atom() -%%% -%%% @doc Starts an snmp manager and/or agent. In the manager case, -%%% registrations of users and agents as specified by the configuration -%%% <code>MgrAgentConfName</code> will be performed. When using snmp -%%% v3 also so called usm users will be registered. Note that users, -%%% usm_users and managed agents may also be registered at a later time -%%% using ct_snmp:register_users/2, ct_snmp:register_agents/2, and -%%% ct_snmp:register_usm_users/2. The agent started will be -%%% called <code>snmp_master_agent</code>. Use ct_snmp:load_mibs/1 to load -%%% mibs into the agent. With <code>SnmpAppConfName</code> it's possible -%%% to configure the snmp application with parameters such as <code>config</code>, -%%% <code>mibs</code>, <code>net_if</code>, etc. The values will be merged -%%% with (and possibly override) default values set by <code>ct_snmp</code>. start(Config, MgrAgentConfName, SnmpAppConfName) -> StartManager= ct:get_config({MgrAgentConfName, start_manager}, true), StartAgent = ct:get_config({MgrAgentConfName, start_agent}, false), @@ -233,12 +80,6 @@ start_application(App) -> Else end. -%%% @spec stop(Config) -> ok -%%% Config = [{Key, Value}] -%%% Key = atom() -%%% Value = term() -%%% -%%% @doc Stops the snmp manager and/or agent removes all files created. stop(Config) -> PrivDir = ?config(priv_dir, Config), ok = application:stop(snmp), @@ -251,41 +92,16 @@ stop(Config) -> catch del_dir(DbDir). -%%% @spec get_values(Agent, Oids, MgrAgentConfName) -> SnmpReply -%%% -%%% Agent = agent_name() -%%% Oids = oids() -%%% MgrAgentConfName = atom() -%%% SnmpReply = snmpreply() -%%% -%%% @doc Issues a synchronous snmp get request. get_values(Agent, Oids, MgrAgentConfName) -> [Uid | _] = agent_conf(Agent, MgrAgentConfName), {ok, SnmpReply, _} = snmpm:sync_get2(Uid, target_name(Agent), Oids), SnmpReply. -%%% @spec get_next_values(Agent, Oids, MgrAgentConfName) -> SnmpReply -%%% -%%% Agent = agent_name() -%%% Oids = oids() -%%% MgrAgentConfName = atom() -%%% SnmpReply = snmpreply() -%%% -%%% @doc Issues a synchronous snmp get next request. get_next_values(Agent, Oids, MgrAgentConfName) -> [Uid | _] = agent_conf(Agent, MgrAgentConfName), {ok, SnmpReply, _} = snmpm:sync_get_next2(Uid, target_name(Agent), Oids), SnmpReply. -%%% @spec set_values(Agent, VarsAndVals, MgrAgentConfName, Config) -> SnmpReply -%%% -%%% Agent = agent_name() -%%% Oids = oids() -%%% MgrAgentConfName = atom() -%%% Config = [{Key, Value}] -%%% SnmpReply = snmpreply() -%%% -%%% @doc Issues a synchronous snmp set request. set_values(Agent, VarsAndVals, MgrAgentConfName, Config) -> PrivDir = ?config(priv_dir, Config), [Uid | _] = agent_conf(Agent, MgrAgentConfName), @@ -301,19 +117,6 @@ set_values(Agent, VarsAndVals, MgrAgentConfName, Config) -> end, SnmpSetReply. -%%% @spec set_info(Config) -> [{Agent, OldVarsAndVals, NewVarsAndVals}] -%%% -%%% Config = [{Key, Value}] -%%% Agent = agent_name() -%%% OldVarsAndVals = varsandvals() -%%% NewVarsAndVals = varsandvals() -%%% -%%% @doc Returns a list of all successful set requests performed in -%%% the test case in reverse order. The list contains the involved -%%% user and agent, the value prior to the set and the new value. This -%%% is intended to facilitate the clean up in the end_per_testcase -%%% function i.e. the undoing of the set requests and its possible -%%% side-effects. set_info(Config) -> PrivDir = ?config(priv_dir, Config), SetLogFile = filename:join(PrivDir, ?CT_SNMP_LOG_FILE), @@ -325,18 +128,6 @@ set_info(Config) -> [] end. -%%% @spec register_users(MgrAgentConfName, Users) -> ok | {error, Reason} -%%% -%%% MgrAgentConfName = atom() -%%% Users = [user()] -%%% Reason = term() -%%% -%%% @doc Register the manager entity (=user) responsible for specific agent(s). -%%% Corresponds to making an entry in users.conf. -%%% -%%% <p>This function will try to register the given users, without -%%% checking if any of them already exist. In order to change an -%%% already registered user, the user must first be unregistered.</p> register_users(MgrAgentConfName, Users) -> case setup_users(Users) of ok -> @@ -350,19 +141,6 @@ register_users(MgrAgentConfName, Users) -> Error end. -%%% @spec register_agents(MgrAgentConfName, ManagedAgents) -> ok | {error, Reason} -%%% -%%% MgrAgentConfName = atom() -%%% ManagedAgents = [agent()] -%%% Reason = term() -%%% -%%% @doc Explicitly instruct the manager to handle this agent. -%%% Corresponds to making an entry in agents.conf -%%% -%%% <p>This function will try to register the given managed agents, -%%% without checking if any of them already exist. In order to change -%%% an already registered managed agent, the agent must first be -%%% unregistered.</p> register_agents(MgrAgentConfName, ManagedAgents) -> case setup_managed_agents(MgrAgentConfName,ManagedAgents) of ok -> @@ -377,18 +155,6 @@ register_agents(MgrAgentConfName, ManagedAgents) -> Error end. -%%% @spec register_usm_users(MgrAgentConfName, UsmUsers) -> ok | {error, Reason} -%%% -%%% MgrAgentConfName = atom() -%%% UsmUsers = [usm_user()] -%%% Reason = term() -%%% -%%% @doc Explicitly instruct the manager to handle this USM user. -%%% Corresponds to making an entry in usm.conf -%%% -%%% <p>This function will try to register the given users, without -%%% checking if any of them already exist. In order to change an -%%% already registered user, the user must first be unregistered.</p> register_usm_users(MgrAgentConfName, UsmUsers) -> EngineID = ct:get_config({MgrAgentConfName, engine_id}, ?ENGINE_ID), case setup_usm_users(UsmUsers, EngineID) of @@ -403,23 +169,10 @@ register_usm_users(MgrAgentConfName, UsmUsers) -> Error end. -%%% @spec unregister_users(MgrAgentConfName) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% Reason = term() -%%% -%%% @doc Unregister all users. unregister_users(MgrAgentConfName) -> Users = [Id || {Id,_} <- ct:get_config({MgrAgentConfName, users},[])], unregister_users(MgrAgentConfName,Users). -%%% @spec unregister_users(MgrAgentConfName,Users) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% Users = [user_name()] -%%% Reason = term() -%%% -%%% @doc Unregister the given users. unregister_users(MgrAgentConfName,Users) -> takedown_users(Users), SnmpVals = ct:get_config(MgrAgentConfName), @@ -432,25 +185,12 @@ unregister_users(MgrAgentConfName,Users) -> ct_config:update_config(MgrAgentConfName, NewSnmpVals), ok. -%%% @spec unregister_agents(MgrAgentConfName) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% Reason = term() -%%% -%%% @doc Unregister all managed agents. unregister_agents(MgrAgentConfName) -> ManagedAgents = [AgentName || {AgentName, _} <- ct:get_config({MgrAgentConfName,managed_agents},[])], unregister_agents(MgrAgentConfName,ManagedAgents). -%%% @spec unregister_agents(MgrAgentConfName,ManagedAgents) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% ManagedAgents = [agent_name()] -%%% Reason = term() -%%% -%%% @doc Unregister the given managed agents. unregister_agents(MgrAgentConfName,ManagedAgents) -> takedown_managed_agents(MgrAgentConfName, ManagedAgents), SnmpVals = ct:get_config(MgrAgentConfName), @@ -464,23 +204,10 @@ unregister_agents(MgrAgentConfName,ManagedAgents) -> ct_config:update_config(MgrAgentConfName, NewSnmpVals), ok. -%%% @spec unregister_usm_users(MgrAgentConfName) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% Reason = term() -%%% -%%% @doc Unregister all usm users. unregister_usm_users(MgrAgentConfName) -> UsmUsers = [Id || {Id,_} <- ct:get_config({MgrAgentConfName, usm_users},[])], unregister_usm_users(MgrAgentConfName,UsmUsers). -%%% @spec unregister_usm_users(MgrAgentConfName,UsmUsers) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% UsmUsers = [usm_user_name()] -%%% Reason = term() -%%% -%%% @doc Unregister the given usm users. unregister_usm_users(MgrAgentConfName,UsmUsers) -> EngineID = ct:get_config({MgrAgentConfName, engine_id}, ?ENGINE_ID), takedown_usm_users(UsmUsers,EngineID), @@ -495,23 +222,9 @@ unregister_usm_users(MgrAgentConfName,UsmUsers) -> ct_config:update_config(MgrAgentConfName, NewSnmpVals), ok. -%%% @spec load_mibs(Mibs) -> ok | {error, Reason} -%%% -%%% Mibs = [MibName] -%%% MibName = string() -%%% Reason = term() -%%% -%%% @doc Load the mibs into the agent 'snmp_master_agent'. load_mibs(Mibs) -> snmpa:load_mibs(snmp_master_agent, Mibs). -%%% @spec unload_mibs(Mibs) -> ok | {error, Reason} -%%% -%%% Mibs = [MibName] -%%% MibName = string() -%%% Reason = term() -%%% -%%% @doc Unload the mibs from the agent 'snmp_master_agent'. unload_mibs(Mibs) -> snmpa:unload_mibs(snmp_master_agent, Mibs). diff --git a/lib/common_test/src/ct_ssh.erl b/lib/common_test/src/ct_ssh.erl index 491d56dfc1..79ab122452 100644 --- a/lib/common_test/src/ct_ssh.erl +++ b/lib/common_test/src/ct_ssh.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2017. All Rights Reserved. +%% Copyright Ericsson AB 2009-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,44 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc SSH/SFTP client module. -%%% -%%% <p>ct_ssh uses the OTP ssh application and more detailed information -%%% about e.g. functions, types and options can be found in the -%%% documentation for this application.</p> -%%% -%%% <p>The <code>Server</code> argument in the SFTP functions should -%%% only be used for SFTP sessions that have been started on existing -%%% SSH connections (i.e. when the original connection type is -%%% <code>ssh</code>). Whenever the connection type is -%%% <code>sftp</code>, use the SSH connection reference only.</p> -%%% -%%% <p>The following options are valid for specifying an SSH/SFTP -%%% connection (i.e. may be used as config elements):</p> -%%% -%%% <pre> -%%% -%%% [{ConnType, Addr}, -%%% {port, Port}, -%%% {user, UserName} -%%% {password, Pwd} -%%% {user_dir, String} -%%% {public_key_alg, PubKeyAlg} -%%% {connect_timeout, Timeout} -%%% {key_cb, KeyCallbackMod}] -%%% </pre> -%%% -%%% <p><code>ConnType = ssh | sftp</code>.</p> -%%% <p>Please see ssh(3) for other types.</p> -%%% -%%% <p>All timeout parameters in ct_ssh functions are values in -%%% milliseconds.</p> -%%% -%%% @type connection() = handle() | ct:target_name() -%%% @type handle() = ct_gen_conn:handle(). Handle for a specific -%%% SSH/SFTP connection. -%%% @type ssh_sftp_return() = term(). A return value from an ssh_sftp function. - -module(ct_ssh). %% SSH Functions @@ -100,64 +62,15 @@ %%%----------------------------------------------------------------- %%%------------------------ SSH COMMANDS --------------------------- -%%%----------------------------------------------------------------- -%%% @spec connect(KeyOrName) -> {ok,Handle} | {error,Reason} -%%% @equiv connect(KeyOrName,host,[]) connect(KeyOrName) -> connect(KeyOrName, host). -%%%----------------------------------------------------------------- -%%% @spec connect(KeyOrName,ConnType) -> {ok,Handle} | {error,Reason} -%%% @equiv connect(KeyOrName,ConnType,[]) connect(KeyOrName, ConnType) when is_atom(ConnType) -> connect(KeyOrName, ConnType, []); -%%%----------------------------------------------------------------- -%%% @spec connect(KeyOrName,ExtraOpts) -> {ok,Handle} | {error,Reason} -%%% @equiv connect(KeyOrName,host,ExtraOpts) connect(KeyOrName, ExtraOpts) when is_list(ExtraOpts) -> connect(KeyOrName, host, ExtraOpts). -%%%----------------------------------------------------------------- -%%% @spec connect(KeyOrName,ConnType,ExtraOpts) -> -%%% {ok,Handle} | {error,Reason} -%%% KeyOrName = Key | Name -%%% Key = atom() -%%% Name = ct:target_name() -%%% ConnType = ssh | sftp | host -%%% ExtraOpts = ssh_connect_options() -%%% Handle = handle() -%%% Reason = term() -%%% -%%% @doc Open an SSH or SFTP connection using the information -%%% associated with <code>KeyOrName</code>. -%%% -%%% <p>If <code>Name</code> (an alias name for <code>Key</code>), -%%% is used to identify the connection, this name may -%%% be used as connection reference for subsequent calls. -%%% It's only possible to have one open connection at a time -%%% associated with <code>Name</code>. If <code>Key</code> is -%%% used, the returned handle must be used for subsequent calls -%%% (multiple connections may be opened using the config -%%% data specified by <code>Key</code>). See <c>ct:require/2</c> -%%% for how to create a new <c>Name</c></p> -%%% -%%% <p><code>ConnType</code> will always override the type -%%% specified in the address tuple in the configuration data (and -%%% in <code>ExtraOpts</code>). So it is possible to for example -%%% open an sftp connection directly using data originally -%%% specifying an ssh connection. The value <code>host</code> -%%% means the connection type specified by the host option -%%% (either in the configuration data or in <code>ExtraOpts</code>) -%%% will be used.</p> -%%% -%%% <p><code>ExtraOpts</code> (optional) are extra SSH options -%%% to be added to the config data for <code>KeyOrName</code>. -%%% The extra options will override any existing options with the -%%% same key in the config data. For details on valid SSH -%%% options, see the documentation for the OTP ssh application.</p> -%%% -%%% @see ct:require/2 connect(KeyOrName, ConnType, ExtraOpts) -> case ct:get_config(KeyOrName) of undefined -> @@ -232,12 +145,6 @@ connect(KeyOrName, ConnType, ExtraOpts) -> end end. -%%%----------------------------------------------------------------- -%%% @spec disconnect(SSH) -> ok | {error,Reason} -%%% SSH = connection() -%%% Reason = term() -%%% -%%% @doc Close an SSH/SFTP connection. disconnect(SSH) -> case get_handle(SSH) of {ok,Pid} -> @@ -252,242 +159,78 @@ disconnect(SSH) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec session_open(SSH) -> {ok,ChannelId} | {error, Reason} -%%% @equiv session_open(SSH,DefaultTimeout) session_open(SSH) -> call(SSH, {session_open,?DEFAULT_TIMEOUT}). -%%%----------------------------------------------------------------- -%%% @spec session_open(SSH,Timeout) -> {ok,ChannelId} | {error, Reason} -%%% SSH = connection() -%%% Timeout = integer() -%%% ChannelId = integer() -%%% Reason = term() -%%% -%%% @doc Opens a channel for an SSH session. session_open(SSH, Timeout) -> call(SSH, {session_open,Timeout}). -%%%----------------------------------------------------------------- -%%% @spec session_close(SSH,ChannelId) -> ok | {error, Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% Reason = term() -%%% -%%% @doc Closes an SSH session channel. session_close(SSH, ChannelId) -> call(SSH, {session_close,ChannelId}). -%%%----------------------------------------------------------------- -%%% @spec exec(SSH,Command) -> {ok,Data} | {error,Reason} -%%% @equiv exec(SSH,Command,DefaultTimeout) exec(SSH, Command) -> exec(SSH, undefined, Command, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec exec(SSH,Command,Timeout) -> {ok,Data} | {error,Reason} -%%% SSH = connection() -%%% Command = string() -%%% Timeout = integer() -%%% Data = list() -%%% Reason = term() -%%% -%%% @doc Requests server to perform <code>Command</code>. A session -%%% channel is opened automatically for the request. -%%% <code>Data</code> is received from the server as a result -%%% of the command. exec(SSH, Command, Timeout) when is_list(Command) -> exec(SSH, undefined, Command, Timeout); -%%%----------------------------------------------------------------- -%%% @spec exec(SSH,ChannelId,Command) -> {ok,Data} | {error,Reason} -%%% @equiv exec(SSH,ChannelId,Command,DefaultTimeout) exec(SSH, ChannelId, Command) when is_integer(ChannelId) -> exec(SSH, ChannelId, Command, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec exec(SSH,ChannelId,Command,Timeout) -> {ok,Data} | {error,Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% Command = string() -%%% Timeout = integer() -%%% Data = list() -%%% Reason = term() -%%% -%%% @doc Requests server to perform <code>Command</code>. A previously -%%% opened session channel is used for the request. -%%% <code>Data</code> is received from the server as a result -%%% of the command. exec(SSH, ChannelId, Command, Timeout) -> call(SSH, {exec,ChannelId,Command,Timeout}). -%%%----------------------------------------------------------------- -%%% @spec receive_response(SSH,ChannelId) -> {ok,Data} | {error,Reason} -%%% @equiv receive_response(SSH,ChannelId,close) receive_response(SSH, ChannelId) -> receive_response(SSH, ChannelId, close, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec receive_response(SSH,ChannelId,End) -> {ok,Data} | {error,Reason} -%%% @equiv receive_response(SSH,ChannelId,End,DefaultTimeout) receive_response(SSH, ChannelId, End) when is_function(End) -> receive_response(SSH, ChannelId, End, ?DEFAULT_TIMEOUT); -%%%----------------------------------------------------------------- -%%% @spec receive_response(SSH,ChannelId,Timeout) -> {ok,Data} | {error,Reason} -%%% @equiv receive_response(SSH,ChannelId,close,Timeout) receive_response(SSH, ChannelId, Timeout) when is_integer(Timeout) -> receive_response(SSH, ChannelId, close, Timeout). -%%%----------------------------------------------------------------- -%%% @spec receive_response(SSH,ChannelId,End,Timeout) -> -%%% {ok,Data} | {timeout,Data} | {error,Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% End = Fun | close | timeout -%%% Timeout = integer() -%%% Data = list() -%%% Reason = term() -%%% -%%% @doc Receives expected data from server on the specified -%%% session channel. -%%% -%%% <p>If <code>End == close</code>, data is returned -%%% to the caller when the channel is closed by the -%%% server. If a timeout occurs before this happens, -%%% the function returns <code>{timeout,Data}</code> -%%% (where <code>Data</code> is the data received so far). -%%% If <code>End == timeout</code>, a timeout is expected -%%% and <code>{ok,Data}</code> is returned both in the case -%%% of a timeout and when the channel is closed. If -%%% <code>End</code> is a fun, this fun will be -%%% called with one argument - the data value in a received -%%% <code>ssh_cm</code> message (see ssh_connection(3)). The -%%% fun should return <code>true</code> to end the receiving -%%% operation (and have the so far collected data returned), or -%%% <code>false</code> to wait for more data from the server. -%%% (Note that even if a fun is supplied, the function returns -%%% immediately if the server closes the channel).</p> receive_response(SSH, ChannelId, End, Timeout) -> call(SSH, {receive_response,ChannelId,End,Timeout}). -%%%----------------------------------------------------------------- -%%% @spec send(SSH,ChannelId,Data) -> ok | {error,Reason} -%%% @equiv send(SSH,ChannelId,0,Data,DefaultTimeout) send(SSH, ChannelId, Data) -> send(SSH, ChannelId, 0, Data, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec send(SSH,ChannelId,Data,Timeout) -> ok | {error,Reason} -%%% @equiv send(SSH,ChannelId,0,Data,Timeout) send(SSH, ChannelId, Data, Timeout) when is_integer(Timeout) -> send(SSH, ChannelId, 0, Data, Timeout); -%%%----------------------------------------------------------------- -%%% @spec send(SSH,ChannelId,Type,Data) -> ok | {error,Reason} -%%% @equiv send(SSH,ChannelId,Type,Data,DefaultTimeout) send(SSH, ChannelId, Type, Data) when is_integer(Type) -> send(SSH, ChannelId, Type, Data, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec send(SSH,ChannelId,Type,Data,Timeout) -> ok | {error,Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% Type = integer() -%%% Data = list() -%%% Timeout = integer() -%%% Reason = term() -%%% -%%% @doc Send data to server on specified session channel. send(SSH, ChannelId, Type, Data, Timeout) -> call(SSH, {send,ChannelId,Type,Data,Timeout}). -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Data) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,Data,close) send_and_receive(SSH, ChannelId, Data) -> send_and_receive(SSH, ChannelId, 0, Data, close, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Data,End) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,0,Data,End,DefaultTimeout) send_and_receive(SSH, ChannelId, Data, End) when is_function(End) -> send_and_receive(SSH, ChannelId, 0, Data, End, ?DEFAULT_TIMEOUT); -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Data,Timeout) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,0,Data,close,Timeout) send_and_receive(SSH, ChannelId, Data, Timeout) when is_integer(Timeout) -> send_and_receive(SSH, ChannelId, 0, Data, close, Timeout); -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Type,Data) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,Type,Data,close,DefaultTimeout) send_and_receive(SSH, ChannelId, Type, Data) when is_integer(Type) -> send_and_receive(SSH, ChannelId, Type, Data, close, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Data,End,Timeout) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,0,Data,End,Timeout) send_and_receive(SSH, ChannelId, Data, End, Timeout) when is_integer(Timeout) -> send_and_receive(SSH, ChannelId, 0, Data, End, Timeout); -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Type,Data,Timeout) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,Type,Data,close,Timeout) send_and_receive(SSH, ChannelId, Type, Data, Timeout) when is_integer(Type) -> send_and_receive(SSH, ChannelId, Type, Data, close, Timeout); -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Type,Data,End) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,Type,Data,End,DefaultTimeout) send_and_receive(SSH, ChannelId, Type, Data, End) when is_function(End) -> send_and_receive(SSH, ChannelId, Type, Data, End, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Type,Data,End,Timeout) -> -%%% {ok,Data} | {error,Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% Type = integer() -%%% Data = list() -%%% End = Fun | close | timeout -%%% Timeout = integer() -%%% Reason = term() -%%% -%%% @doc Send data to server on specified session channel and wait -%%% to receive the server response. -%%% -%%% <p>See <code>receive_response/4</code> for details on the -%%% <code>End</code> argument.</p> send_and_receive(SSH, ChannelId, Type, Data, End, Timeout) -> call(SSH, {send_and_receive,ChannelId,Type,Data,End,Timeout}). -%%%----------------------------------------------------------------- -%%% @spec subsystem(SSH,ChannelId,Subsystem) -> Status | {error,Reason} -%%% @equiv subsystem(SSH,ChannelId,Subsystem,DefaultTimeout) subsystem(SSH, ChannelId, Subsystem) -> subsystem(SSH, ChannelId, Subsystem, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec subsystem(SSH,ChannelId,Subsystem,Timeout) -> -%%% Status | {error,Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% Subsystem = string() -%%% Timeout = integer() -%%% Status = success | failure -%%% Reason = term() -%%% -%%% @doc Sends a request to execute a predefined subsystem. subsystem(SSH, ChannelId, Subsystem, Timeout) -> call(SSH, {subsystem,ChannelId,Subsystem,Timeout}). @@ -511,439 +254,157 @@ shell(SSH, ChannelId, Timeout) -> %%%----------------------------------------------------------------- %%%------------------------ SFTP COMMANDS -------------------------- -%%%----------------------------------------------------------------- -%%% @spec sftp_connect(SSH) -> {ok,Server} | {error,Reason} -%%% SSH = connection() -%%% Server = pid() -%%% Reason = term() -%%% @doc Starts an SFTP session on an already existing SSH connection. -%%% <code>Server</code> identifies the new session and must be -%%% specified whenever SFTP requests are to be sent. sftp_connect(SSH) -> call(SSH, sftp_connect). -%%%----------------------------------------------------------------- -%%% @spec read_file(SSH, File) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). read_file(SSH, File) -> call(SSH, {read_file,sftp,File}). -%%%----------------------------------------------------------------- -%%% @spec read_file(SSH, Server, File) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + read_file(SSH, Server, File) -> call(SSH, {read_file,Server,File}). -%%%----------------------------------------------------------------- -%%% @spec write_file(SSH, File, Iolist) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). write_file(SSH, File, Iolist) -> call(SSH, {write_file,sftp,File,Iolist}). -%%%----------------------------------------------------------------- -%%% @spec write_file(SSH, Server, File, Iolist) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + write_file(SSH, Server, File, Iolist) -> call(SSH, {write_file,Server,File,Iolist}). -%%%----------------------------------------------------------------- -%%% @spec list_dir(SSH, Path) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). list_dir(SSH, Path) -> call(SSH, {list_dir,sftp,Path}). -%%%----------------------------------------------------------------- -%%% @spec list_dir(SSH, Server, Path) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + list_dir(SSH, Server, Path) -> call(SSH, {list_dir,Server,Path}). -%%%----------------------------------------------------------------- -%%% @spec open(SSH, File, Mode) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). open(SSH, File, Mode) -> call(SSH, {open,sftp,File,Mode}). -%%%----------------------------------------------------------------- -%%% @spec open(SSH, Server, File, Mode) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + open(SSH, Server, File, Mode) -> call(SSH, {open,Server,File,Mode}). -%%%----------------------------------------------------------------- -%%% @spec opendir(SSH, Path) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). opendir(SSH, Path) -> call(SSH, {opendir,sftp,Path}). -%%%----------------------------------------------------------------- -%%% @spec opendir(SSH, Server, Path) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + opendir(SSH, Server, Path) -> call(SSH, {opendir,Server,Path}). -%%%----------------------------------------------------------------- -%%% @spec close(SSH, Handle) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). close(SSH, Handle) -> call(SSH, {close,sftp,Handle}). -%%%----------------------------------------------------------------- -%%% @spec close(SSH, Server, Handle) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + close(SSH, Server, Handle) -> call(SSH, {close,Server,Handle}). -%%%----------------------------------------------------------------- -%%% @spec read(SSH, Handle, Len) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). read(SSH, Handle, Len) -> call(SSH, {read,sftp,Handle,Len}). -%%%----------------------------------------------------------------- -%%% @spec read(SSH, Server, Handle, Len) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + read(SSH, Server, Handle, Len) -> call(SSH, {read,Server,Handle,Len}). -%%%----------------------------------------------------------------- -%%% @spec pread(SSH, Handle, Position, Length) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). pread(SSH, Handle, Position, Length) -> call(SSH, {pread,sftp,Handle,Position,Length}). -%%%----------------------------------------------------------------- -%%% @spec pread(SSH, Server, Handle, Position, Length) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + pread(SSH, Server, Handle, Position, Length) -> call(SSH, {pread,Server,Handle,Position,Length}). -%%%----------------------------------------------------------------- -%%% @spec aread(SSH, Handle, Len) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). aread(SSH, Handle, Len) -> call(SSH, {aread,sftp,Handle,Len}). -%%%----------------------------------------------------------------- -%%% @spec aread(SSH, Server, Handle, Len) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + aread(SSH, Server, Handle, Len) -> call(SSH, {aread,Server,Handle,Len}). -%%%----------------------------------------------------------------- -%%% @spec apread(SSH, Handle, Position, Length) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). apread(SSH, Handle, Position, Length) -> call(SSH, {apread,sftp,Handle,Position,Length}). -%%%----------------------------------------------------------------- -%%% @spec apread(SSH, Server, Handle, Position, Length) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + apread(SSH, Server, Handle, Position, Length) -> call(SSH, {apread,Server,Handle,Position,Length}). -%%%----------------------------------------------------------------- -%%% @spec write(SSH, Handle, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). write(SSH, Handle, Data) -> call(SSH, {write,sftp,Handle,Data}). -%%%----------------------------------------------------------------- -%%% @spec write(SSH, Server, Handle, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + write(SSH, Server, Handle, Data) -> call(SSH, {write,Server,Handle,Data}). -%%%----------------------------------------------------------------- -%%% @spec pwrite(SSH, Handle, Position, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). pwrite(SSH, Handle, Position, Data) -> call(SSH, {pwrite,sftp,Handle,Position,Data}). -%%%----------------------------------------------------------------- -%%% @spec pwrite(SSH, Server, Handle, Position, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + pwrite(SSH, Server, Handle, Position, Data) -> call(SSH, {pwrite,Server,Handle,Position,Data}). -%%%----------------------------------------------------------------- -%%% @spec awrite(SSH, Handle, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). awrite(SSH, Handle, Data) -> call(SSH, {awrite,sftp,Handle, Data}). -%%%----------------------------------------------------------------- -%%% @spec awrite(SSH, Server, Handle, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + awrite(SSH, Server, Handle, Data) -> call(SSH, {awrite,Server,Handle, Data}). -%%%----------------------------------------------------------------- -%%% @spec apwrite(SSH, Handle, Position, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). apwrite(SSH, Handle, Position, Data) -> call(SSH, {apwrite,sftp,Handle,Position,Data}). -%%%----------------------------------------------------------------- -%%% @spec apwrite(SSH, Server, Handle, Position, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + apwrite(SSH, Server, Handle, Position, Data) -> call(SSH, {apwrite,Server,Handle,Position,Data}). -%%%----------------------------------------------------------------- -%%% @spec position(SSH, Handle, Location) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). position(SSH, Handle, Location) -> call(SSH, {position,sftp,Handle,Location}). -%%%----------------------------------------------------------------- -%%% @spec position(SSH, Server, Handle, Location) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + position(SSH, Server, Handle, Location) -> call(SSH, {position,Server,Handle,Location}). -%%%----------------------------------------------------------------- -%%% @spec read_file_info(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). read_file_info(SSH, Name) -> call(SSH, {read_file_info,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec read_file_info(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + read_file_info(SSH, Server, Name) -> call(SSH, {read_file_info,Server,Name}). -%%%----------------------------------------------------------------- -%%% @spec get_file_info(SSH, Handle) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). get_file_info(SSH, Handle) -> call(SSH, {get_file_info,sftp,Handle}). -%%%----------------------------------------------------------------- -%%% @spec get_file_info(SSH, Server, Handle) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + get_file_info(SSH, Server, Handle) -> call(SSH, {get_file_info,Server,Handle}). -%%%----------------------------------------------------------------- -%%% @spec read_link_info(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). read_link_info(SSH, Name) -> call(SSH, {read_link_info,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec read_link_info(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + read_link_info(SSH, Server, Name) -> call(SSH, {read_link_info,Server,Name}). -%%%----------------------------------------------------------------- -%%% @spec write_file_info(SSH, Name, Info) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). write_file_info(SSH, Name, Info) -> call(SSH, {write_file_info,sftp,Name,Info}). -%%%----------------------------------------------------------------- -%%% @spec write_file_info(SSH, Server, Name, Info) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + write_file_info(SSH, Server, Name, Info) -> call(SSH, {write_file_info,Server,Name,Info}). -%%%----------------------------------------------------------------- -%%% @spec read_link(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). read_link(SSH, Name) -> call(SSH, {read_link,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec read_link(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + read_link(SSH, Server, Name) -> call(SSH, {read_link,Server,Name}). -%%%----------------------------------------------------------------- -%%% @spec make_symlink(SSH, Name, Target) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). make_symlink(SSH, Name, Target) -> call(SSH, {make_symlink,sftp,Name,Target}). -%%%----------------------------------------------------------------- -%%% @spec make_symlink(SSH, Server, Name, Target) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + make_symlink(SSH, Server, Name, Target) -> call(SSH, {make_symlink,Server,Name,Target}). -%%%----------------------------------------------------------------- -%%% @spec rename(SSH, OldName, NewName) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). rename(SSH, OldName, NewName) -> call(SSH, {rename,sftp,OldName,NewName}). -%%%----------------------------------------------------------------- -%%% @spec rename(SSH, Server, OldName, NewName) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + rename(SSH, Server, OldName, NewName) -> call(SSH, {rename,Server,OldName,NewName}). -%%%----------------------------------------------------------------- -%%% @spec delete(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + delete(SSH, Name) -> call(SSH, {delete,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec delete(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + delete(SSH, Server, Name) -> call(SSH, {delete,Server,Name}). -%%%----------------------------------------------------------------- -%%% @spec make_dir(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). make_dir(SSH, Name) -> call(SSH, {make_dir,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec make_dir(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + make_dir(SSH, Server, Name) -> call(SSH, {make_dir,Server,Name}). -%%%----------------------------------------------------------------- -%%% @spec del_dir(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). del_dir(SSH, Name) -> call(SSH, {del_dir,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec del_dir(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + del_dir(SSH, Server, Name) -> call(SSH, {del_dir,Server,Name}). @@ -952,7 +413,6 @@ del_dir(SSH, Server, Name) -> %%% Callback functions %%%================================================================= -%% @hidden init(KeyOrName, {ConnType,Addr,Port}, AllOpts) -> User = proplists:get_value(user, AllOpts), Password = case proplists:get_value(password, AllOpts) of @@ -1002,7 +462,6 @@ init(KeyOrName, {ConnType,Addr,Port}, AllOpts) -> target=KeyOrName}} end. -%% @hidden handle_msg(sftp_connect, State) -> #state{ssh_ref=SSHRef, target=Target} = State, try_log(heading(sftp_connect,Target), "SSH Ref: ~p", [SSHRef]), @@ -1246,15 +705,12 @@ handle_msg({del_dir,Srv,Name}=Cmd, S=#state{ssh_ref=SSHRef}) -> [SSHRef,ref(Srv,SSHRef),mod(Cmd)]), {ssh_sftp:del_dir(ref(Srv,SSHRef), Name),S}. -%% @hidden reconnect(_Addr,_State) -> {error,no_reconnection_of_ssh}. -%% @hidden close(SSHRef) -> disconnect(SSHRef). -%% @hidden terminate(SSHRef, State) -> case State#state.conn_type of ssh -> @@ -1271,8 +727,6 @@ terminate(SSHRef, State) -> %%%================================================================= %%% Internal functions -%%%----------------------------------------------------------------- -%%% do_recv_response(SSH, Chn, Data, End, Timeout) -> receive {ssh_cm, SSH, {open,Chn,RemoteChn,{session}}} -> @@ -1351,8 +805,6 @@ do_recv_response(SSH, Chn, Data, End, Timeout) -> end end. -%%%----------------------------------------------------------------- -%%% get_handle(SSH) when is_pid(SSH) -> {ok,SSH}; get_handle(SSH) -> @@ -1365,8 +817,6 @@ get_handle(SSH) -> Error end. -%%%----------------------------------------------------------------- -%%% call(SSH, Msg) -> call(SSH, Msg, infinity). @@ -1378,29 +828,19 @@ call(SSH, Msg, Timeout) -> Error end. -%%%----------------------------------------------------------------- -%%% ref(sftp, SSHRef) -> SSHRef; ref(Server, _) -> Server. -%%%----------------------------------------------------------------- -%%% mod(Cmd) -> [Op,_Server|Args] = tuple_to_list(Cmd), list_to_tuple([Op|Args]). -%%%----------------------------------------------------------------- -%%% heading(Function, Ref) -> io_lib:format("ct_ssh:~tw ~tp",[Function,Ref]). -%%%----------------------------------------------------------------- -%%% log(Heading, Str, Args) -> ct_gen_conn:log(Heading, Str, Args). -%%%----------------------------------------------------------------- -%%% try_log(Heading, Str, Args) -> try_log(Heading, Str, Args, infinity). @@ -1414,8 +854,6 @@ try_log(Heading, Str, Args, Timeout) -> ok end. -%%%----------------------------------------------------------------- -%%% debug(Str) -> debug(Str, []). diff --git a/lib/common_test/src/ct_telnet.erl b/lib/common_test/src/ct_telnet.erl index b50cddd492..f9abecfd38 100644 --- a/lib/common_test/src/ct_telnet.erl +++ b/lib/common_test/src/ct_telnet.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,131 +18,6 @@ %% %CopyrightEnd% %% -%% @doc Common Test specific layer on top of telnet client `ct_telnet_client.erl' -%% -%% <p>Use this module to set up telnet connections, send commands and -%% perform string matching on the result. -%% See the `unix_telnet' manual page for information about how to use -%% `ct_telnet', and configure connections, specifically for unix hosts.</p> -%% <p>The following default values are defined in `ct_telnet':</p> -%% <pre> -%% Connection timeout = 10 sec (time to wait for connection) -%% Command timeout = 10 sec (time to wait for a command to return) -%% Max no of reconnection attempts = 3 -%% Reconnection interval = 5 sek (time to wait in between reconnection attempts) -%% Keep alive = true (will send NOP to the server every 8 sec if connection is idle) -%% Polling limit = 0 (max number of times to poll to get a remaining string terminated) -%% Polling interval = 1 sec (sleep time between polls)</pre> -%% <p>These parameters can be altered by the user with the following -%% configuration term:</p> -%% <pre> -%% {telnet_settings, [{connect_timeout,Millisec}, -%% {command_timeout,Millisec}, -%% {reconnection_attempts,N}, -%% {reconnection_interval,Millisec}, -%% {keep_alive,Bool}, -%% {poll_limit,N}, -%% {poll_interval,Millisec}, -%% {tcp_nodelay,Bool}]}.</pre> -%% <p><code>Millisec = integer(), N = integer()</code></p> -%% <p>Enter the <code>telnet_settings</code> term in a configuration -%% file included in the test and ct_telnet will retrieve the information -%% automatically. Note that `keep_alive' may be specified per connection if -%% required. See `unix_telnet' for details.</p> -%% -%% == Logging == -%% -%% The default logging behaviour of `ct_telnet' is to print information -%% to the test case HTML log about performed operations and commands -%% and their corresponding results. What won't be printed to the HTML log -%% are text strings sent from the telnet server that are not explicitly -%% received by means of a `ct_telnet' function such as `expect/3'. -%% `ct_telnet' may however be configured to use a special purpose event handler, -%% implemented in `ct_conn_log_h', for logging <b>all</b> telnet traffic. -%% To use this handler, you need to install a Common Test hook named -%% `cth_conn_log'. Example (using the test suite info function): -%% -%% ``` -%% suite() -> -%% [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}]. -%% ''' -%% -%% `conn_mod()' is the name of the common_test module implementing -%% the connection protocol, i.e. `ct_telnet'. -%% -%% The `cth_conn_log' hook performs unformatted logging of telnet data to -%% a separate text file. All telnet communication is captured and printed, -%% including arbitrary data sent from the server. The link to this text file -%% can be found on the top of the test case HTML log. -%% -%% By default, data for all telnet connections is logged in one common -%% file (named `default'), which might get messy e.g. if multiple telnet -%% sessions are running in parallel. It is therefore possible to create a -%% separate log file for each connection. To configure this, use the hook -%% option `hosts' and list the names of the servers/connections that will be -%% used in the suite. Note that the connections must be named for this to work -%% (see the `open' function below). -%% -%% The hook option named `log_type' may be used to change the `cth_conn_log' -%% behaviour. The default value of this option is `raw', which results in the -%% behaviour described above. If the value is set to `html', all telnet -%% communication is printed to the test case HTML log instead. -%% -%% All `cth_conn_log' hook options described above can also be specified in -%% a configuration file with the configuration variable `ct_conn_log'. Example: -%% -%% ``` -%% {ct_conn_log, [{ct_telnet,[{log_type,raw}, -%% {hosts,[key_or_name()]}]}]} -%% ''' -%% -%% <b>Note</b> that hook options specified in a configuration file -%% will overwrite any hardcoded hook options in the test suite! -%% -%% === Logging example === -%% -%% The following `ct_hooks' statement will cause printing of telnet traffic -%% to separate logs for the connections named `server1' and `server2'. -%% Traffic for any other connections will be logged in the default telnet log. -%% -%% ``` -%% suite() -> -%% [{ct_hooks, -%% [{cth_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}]}]. -%%''' -%% -%% As previously explained, the above specification could also be provided -%% by means of an entry like this in a configuration file: -%% -%% ``` -%% {ct_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}. -%% ''' -%% -%% in which case the `ct_hooks' statement in the test suite may simply look -%% like this: -%% -%% ``` -%% suite() -> -%% [{ct_hooks, [{cth_conn_log, []}]}]. -%% ''' -%% -%% @end - -%% @type connection_type() = telnet | ts1 | ts2 - -%% @type connection() = handle() | -%% {ct:target_name(),connection_type()} | ct:target_name() - -%% @type handle() = ct_gen_conn:handle(). Handle for a -%% specific telnet connection. - -%% @type prompt_regexp() = string(). A regular expression which -%% matches all possible prompts for a specific type of target. The -%% regexp must not have any groups i.e. when matching, re:run/3 shall -%% return a list with one single element. -%% -%% @see unix_telnet - -module(ct_telnet). -export([open/1, open/2, open/3, open/4, close/1]). @@ -186,20 +61,9 @@ reconn_int=?RECONN_TIMEOUT, tcp_nodelay=false}). -%%%----------------------------------------------------------------- -%%% @spec open(Name) -> {ok,Handle} | {error,Reason} -%%% @equiv open(Name,telnet) open(Name) -> open(Name,telnet). -%%%----------------------------------------------------------------- -%%% @spec open(Name,ConnType) -> {ok,Handle} | {error,Reason} -%%% Name = target_name() -%%% ConnType = ct_telnet:connection_type() -%%% Handle = ct_telnet:handle() -%%% Reason = term() -%%% -%%% @doc Open a telnet connection to the specified target host. open(Name,ConnType) -> case ct_util:get_key_from_name(Name) of {ok, unix} -> % unix host @@ -210,44 +74,9 @@ open(Name,ConnType) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec open(KeyOrName,ConnType,TargetMod) -> -%%% {ok,Handle} | {error,Reason} -%%% @equiv open(KeyOrName,ConnType,TargetMod,[]) open(KeyOrName,ConnType,TargetMod) -> open(KeyOrName,ConnType,TargetMod,KeyOrName). -%%%----------------------------------------------------------------- -%%% @spec open(KeyOrName,ConnType,TargetMod,Extra) -> -%%% {ok,Handle} | {error,Reason} -%%% KeyOrName = Key | Name -%%% Key = atom() -%%% Name = ct:target_name() -%%% ConnType = connection_type() -%%% TargetMod = atom() -%%% Extra = term() -%%% Handle = handle() -%%% Reason = term() -%%% -%%% @doc Open a telnet connection to the specified target host. -%%% -%%% <p>The target data must exist in a configuration file. The connection -%%% may be associated with either <code>Name</code> and/or the returned -%%% <code>Handle</code>. To allocate a name for the target, -%%% use <code>ct:require/2</code> in a test case, or use a -%%% <code>require</code> statement in the suite info function -%%% (<code>suite/0</code>), or in a test case info function. -%%% If you want the connection to be associated with <code>Handle</code> only -%%% (in case you need to open multiple connections to a host for example), -%%% simply use <code>Key</code>, the configuration variable name, to -%%% specify the target. Note that a connection that has no associated target -%%% name can only be closed with the handle value.</p> -%%% -%%% <p><code>TargetMod</code> is a module which exports the functions -%%% <code>connect(Ip,Port,KeepAlive,Extra)</code> and <code>get_prompt_regexp()</code> -%%% for the given <code>TargetType</code> (e.g. <code>unix_telnet</code>).</p> -%%% -%%% @see ct:require/2 open(KeyOrName,ConnType,TargetMod,Extra) -> case ct:get_config({KeyOrName,ConnType}) of undefined -> @@ -287,17 +116,6 @@ open(KeyOrName,ConnType,TargetMod,Extra) -> {old,true}]) end. -%%%----------------------------------------------------------------- -%%% @spec close(Connection) -> ok | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% Reason = term() -%%% -%%% @doc Close the telnet connection and stop the process managing it. -%%% -%%% <p>A connection may be associated with a target name and/or a handle. -%%% If <code>Connection</code> has no associated target name, it may only -%%% be closed with the handle value (see the <code>open/4</code> -%%% function).</p> close(Connection) -> case get_handle(Connection) of {ok,Pid} -> @@ -315,30 +133,10 @@ close(Connection) -> %%%================================================================= %%% Test suite interface %%%----------------------------------------------------------------- -%%% @spec cmd(Connection,Cmd) -> {ok,Data} | {error,Reason} -%%% @equiv cmd(Connection,Cmd,[]) + cmd(Connection,Cmd) -> cmd(Connection,Cmd,[]). -%%%----------------------------------------------------------------- -%%% @spec cmd(Connection,Cmd,Opts) -> {ok,Data} | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% Cmd = string() -%%% Opts = [Opt] -%%% Opt = {timeout,timeout()} | {newline,boolean()} -%%% Data = [string()] -%%% Reason = term() -%%% @doc Send a command via telnet and wait for prompt. -%%% -%%% <p>This function will by default add a newline to the end of the -%%% given command. If this is not desired, the option -%%% `{newline,false}' can be used. This is necessary, for example, -%%% when sending telnet command sequences (prefixed with the -%%% Interprete As Command, IAC, character).</p> -%%% -%%% <p>The option `timeout' specifies how long the client shall wait for -%%% prompt. If the time expires, the function returns -%%% `{error,timeout}'. See the module description for information -%%% about the default value for the command timeout.</p> + cmd(Connection,Cmd,Opts) when is_list(Opts) -> case check_cmd_opts(Opts) of ok -> @@ -363,42 +161,13 @@ check_cmd_opts([]) -> check_cmd_opts(Opts) -> check_send_opts(Opts). -%%%----------------------------------------------------------------- -%%% @spec cmdf(Connection,CmdFormat,Args) -> {ok,Data} | {error,Reason} -%%% @equiv cmdf(Connection,CmdFormat,Args,[]) cmdf(Connection,CmdFormat,Args) -> cmdf(Connection,CmdFormat,Args,[]). -%%%----------------------------------------------------------------- -%%% @spec cmdf(Connection,CmdFormat,Args,Opts) -> {ok,Data} | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% CmdFormat = string() -%%% Args = list() -%%% Opts = [Opt] -%%% Opt = {timeout,timeout()} | {newline,boolean()} -%%% Data = [string()] -%%% Reason = term() -%%% @doc Send a telnet command and wait for prompt -%%% (uses a format string and list of arguments to build the command). -%%% -%%% <p>See {@link cmd/3} further description.</p> + cmdf(Connection,CmdFormat,Args,Opts) when is_list(Args) -> Cmd = lists:flatten(io_lib:format(CmdFormat,Args)), cmd(Connection,Cmd,Opts). -%%%----------------------------------------------------------------- -%%% @spec get_data(Connection) -> {ok,Data} | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% Data = [string()] -%%% Reason = term() -%%% @doc Get all data that has been received by the telnet client -%%% since the last command was sent. Note that only newline terminated -%%% strings are returned. If the last string received has not yet -%%% been terminated, the connection may be polled automatically until -%%% the string is complete. The polling feature is controlled -%%% by the `poll_limit' and `poll_interval' config values and is -%%% by default disabled (meaning the function will immediately -%%% return all complete strings received and save a remaining -%%% non-terminated string for a later `get_data' call). get_data(Connection) -> case get_handle(Connection) of {ok,Pid} -> @@ -407,29 +176,9 @@ get_data(Connection) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec send(Connection,Cmd) -> ok | {error,Reason} -%%% @equiv send(Connection,Cmd,[]) send(Connection,Cmd) -> send(Connection,Cmd,[]). -%%%----------------------------------------------------------------- -%%% @spec send(Connection,Cmd,Opts) -> ok | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% Cmd = string() -%%% Opts = [Opt] -%%% Opt = {newline,boolean()} -%%% Reason = term() -%%% @doc Send a telnet command and return immediately. -%%% -%%% This function will by default add a newline to the end of the -%%% given command. If this is not desired, the option -%%% `{newline,false}' can be used. This is necessary, for example, -%%% when sending telnet command sequences (prefixed with the -%%% Interprete As Command, IAC, character). -%%% -%%% <p>The resulting output from the command can be read with -%%% <code>get_data/1</code> or <code>expect/2/3</code>.</p> send(Connection,Cmd,Opts) -> case check_send_opts(Opts) of ok -> @@ -450,142 +199,16 @@ check_send_opts([Invalid|_]) -> check_send_opts([]) -> ok. - -%%%----------------------------------------------------------------- -%%% @spec sendf(Connection,CmdFormat,Args) -> ok | {error,Reason} -%%% @equiv sendf(Connection,CmdFormat,Args,[]) sendf(Connection,CmdFormat,Args) when is_list(Args) -> sendf(Connection,CmdFormat,Args,[]). -%%%----------------------------------------------------------------- -%%% @spec sendf(Connection,CmdFormat,Args,Opts) -> ok | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% CmdFormat = string() -%%% Args = list() -%%% Opts = [Opt] -%%% Opt = {newline,boolean()} -%%% Reason = term() -%%% @doc Send a telnet command and return immediately (uses a format -%%% string and a list of arguments to build the command). sendf(Connection,CmdFormat,Args,Opts) when is_list(Args) -> Cmd = lists:flatten(io_lib:format(CmdFormat,Args)), send(Connection,Cmd,Opts). -%%%----------------------------------------------------------------- -%%% @spec expect(Connection,Patterns) -> term() -%%% @equiv expect(Connections,Patterns,[]) expect(Connection,Patterns) -> expect(Connection,Patterns,[]). -%%%----------------------------------------------------------------- -%%% @spec expect(Connection,Patterns,Opts) -> {ok,Match} | -%%% {ok,MatchList,HaltReason} | -%%% {error,Reason} -%%% Connection = ct_telnet:connection() -%%% Patterns = Pattern | [Pattern] -%%% Pattern = string() | {Tag,string()} | prompt | {prompt,Prompt} -%%% Prompt = string() -%%% Tag = term() -%%% Opts = [Opt] -%%% Opt = {idle_timeout,IdleTimeout} | {total_timeout,TotalTimeout} | -%%% repeat | {repeat,N} | sequence | {halt,HaltPatterns} | -%%% ignore_prompt | no_prompt_check | wait_for_prompt | -%%% {wait_for_prompt,Prompt} -%%% IdleTimeout = infinity | integer() -%%% TotalTimeout = infinity | integer() -%%% N = integer() -%%% HaltPatterns = Patterns -%%% MatchList = [Match] -%%% Match = RxMatch | {Tag,RxMatch} | {prompt,Prompt} -%%% RxMatch = [string()] -%%% HaltReason = done | Match -%%% Reason = timeout | {prompt,Prompt} -%%% -%%% @doc Get data from telnet and wait for the expected pattern. -%%% -%%% <p><code>Pattern</code> can be a POSIX regular expression. The function -%%% returns as soon as a pattern has been successfully matched (at least one, -%%% in the case of multiple patterns).</p> -%%% -%%% <p><code>RxMatch</code> is a list of matched strings. It looks -%%% like this: <code>[FullMatch, SubMatch1, SubMatch2, ...]</code> -%%% where <code>FullMatch</code> is the string matched by the whole -%%% regular expression and <code>SubMatchN</code> is the string that -%%% matched subexpression no <code>N</code>. Subexpressions are -%%% denoted with '(' ')' in the regular expression</p> -%%% -%%% <p>If a <code>Tag</code> is given, the returned <code>Match</code> -%%% will also include the matched <code>Tag</code>. Else, only -%%% <code>RxMatch</code> is returned.</p> -%%% -%%% <p>The <code>idle_timeout</code> option indicates that the function -%%% shall return if the telnet client is idle (i.e. if no data is -%%% received) for more than <code>IdleTimeout</code> milliseconds. Default -%%% timeout is 10 seconds.</p> -%%% -%%% <p>The <code>total_timeout</code> option sets a time limit for -%%% the complete expect operation. After <code>TotalTimeout</code> -%%% milliseconds, <code>{error,timeout}</code> is returned. The default -%%% value is <code>infinity</code> (i.e. no time limit).</p> -%%% -%%% <p>The function will return when a prompt is received, even if no -%%% pattern has yet been matched. In this event, -%%% <code>{error,{prompt,Prompt}}</code> is returned. -%%% However, this behaviour may be modified with the -%%% <code>ignore_prompt</code> or <code>no_prompt_check</code> option, which -%%% tells <code>expect</code> to return only when a match is found or after a -%%% timeout.</p> -%%% -%%% <p>If the <code>ignore_prompt</code> option is used, -%%% <code>ct_telnet</code> will ignore any prompt found. This option -%%% is useful if data sent by the server could include a pattern that -%%% would match the prompt regexp (as returned by -%%% <code>TargedMod:get_prompt_regexp/0</code>), but which should not -%%% cause the function to return.</p> -%%% -%%% <p>If the <code>no_prompt_check</code> option is used, -%%% <code>ct_telnet</code> will not search for a prompt at all. This -%%% is useful if, for instance, the <code>Pattern</code> itself -%%% matches the prompt.</p> -%%% -%%% <p>The <code>wait_for_prompt</code> option forces <code>ct_telnet</code> -%%% to wait until the prompt string has been received before returning -%%% (even if a pattern has already been matched). This is equal to calling: -%%% <code>expect(Conn, Patterns++[{prompt,Prompt}], [sequence|Opts])</code>. -%%% Note that <code>idle_timeout</code> and <code>total_timeout</code> -%%% may abort the operation of waiting for prompt.</p> -%%% -%%% <p>The <code>repeat</code> option indicates that the pattern(s) -%%% shall be matched multiple times. If <code>N</code> is given, the -%%% pattern(s) will be matched <code>N</code> times, and the function -%%% will return with <code>HaltReason = done</code>.</p> -%%% -%%% <p>The <code>sequence</code> option indicates that all patterns -%%% shall be matched in a sequence. A match will not be concluded -%%% untill all patterns are matched.</p> -%%% -%%% <p>Both <code>repeat</code> and <code>sequence</code> can be -%%% interrupted by one or more <code>HaltPatterns</code>. When -%%% <code>sequence</code> or <code>repeat</code> is used, there will -%%% always be a <code>MatchList</code> returned, i.e. a list of -%%% <code>Match</code> instead of only one <code>Match</code>. There -%%% will also be a <code>HaltReason</code> returned.</p> -%%% -%%% <p><underline>Examples:</underline><br/> -%%% <code>expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],</code> -%%% <code>[sequence,{halt,[{nnn,"NNN"}]}]).</code><br/> will try to match -%%% "ABC" first and then "XYZ", but if "NNN" appears the function will -%%% return <code>{error,{nnn,["NNN"]}}</code>. If both "ABC" and "XYZ" -%%% are matched, the function will return -%%% <code>{ok,[AbcMatch,XyzMatch]}</code>.</p> -%%% -%%% <p><code>expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],</code> -%%% <code>[{repeat,2},{halt,[{nnn,"NNN"}]}]).</code><br/> will try to match -%%% "ABC" or "XYZ" twice. If "NNN" appears the function will return -%%% with <code>HaltReason = {nnn,["NNN"]}</code>.</p> -%%% -%%% <p>The <code>repeat</code> and <code>sequence</code> options can be -%%% combined in order to match a sequence multiple times.</p> expect(Connection,Patterns,Opts) -> case get_handle(Connection) of {ok,Pid} -> @@ -596,7 +219,7 @@ expect(Connection,Patterns,Opts) -> %%%================================================================= %%% Callback functions -%% @hidden + init(Name,{Ip,Port,Type},{TargetMod,KeepAlive,Extra}) -> S0 = case ct:get_config(telnet_settings) of undefined -> @@ -677,7 +300,6 @@ set_telnet_defaults([Unknown|Ss],S) -> set_telnet_defaults([],S) -> S. -%% @hidden handle_msg({cmd,Cmd,Opts},State) -> start_gen_log(heading(cmd,State#state.name)), log(State,cmd,"Cmd: ~tp",[Cmd]), @@ -803,7 +425,6 @@ handle_msg({expect,Pattern,Opts},State) -> {Return1,State#state{buffer=NewBuffer,prompt=Prompt}}. -%% @hidden reconnect({Ip,Port,_Type},State) -> reconnect(Ip,Port,State#state.reconns,State). reconnect(Ip,Port,N,State=#state{name=Name, @@ -834,7 +455,6 @@ reconnect(Ip,Port,N,State=#state{name=Name, end. -%% @hidden terminate(TelnPid,State) -> Result = ct_telnet_client:close(TelnPid), log(State,close,"Telnet connection for ~w closed.",[TelnPid]), @@ -902,7 +522,6 @@ force_log(State,Action,String,Args) -> log(State,Action,String,Args,true). %%%----------------------------------------------------------------- -%%% @hidden log(State,Action,String,Args) when is_record(State, state) -> log(State,Action,String,Args,false); log(Name,Action,String,Args) when is_atom(Name) -> @@ -911,7 +530,6 @@ log(TelnPid,Action,String,Args) when is_pid(TelnPid) -> log(#state{teln_pid=TelnPid},Action,String,Args,false). %%%----------------------------------------------------------------- -%%% @hidden log(undefined,String,Args) -> log(#state{},undefined,String,Args,false); log(Name,String,Args) when is_atom(Name) -> @@ -920,7 +538,6 @@ log(TelnPid,String,Args) when is_pid(TelnPid) -> log(#state{teln_pid=TelnPid},undefined,String,Args). %%%----------------------------------------------------------------- -%%% @hidden log(#state{name=Name,teln_pid=TelnPid,host=Host,port=Port}, Action,String,Args,ForcePrint) -> Name1 = if Name == undefined -> get({ct_telnet_pid2name,TelnPid}); @@ -971,7 +588,6 @@ log(#state{name=Name,teln_pid=TelnPid,host=Host,port=Port}, end. %%%----------------------------------------------------------------- -%%% @hidden start_gen_log(Heading) -> %% check if output is suppressed case ct_util:is_silenced(telnet) of @@ -980,7 +596,6 @@ start_gen_log(Heading) -> end. %%%----------------------------------------------------------------- -%%% @hidden end_gen_log() -> %% check if output is suppressed case ct_util:is_silenced(telnet) of @@ -988,7 +603,6 @@ end_gen_log() -> false -> ct_gen_conn:end_log() end. -%%% @hidden %% Debug printouts. debug_cont_gen_log(Str,Args) -> Old = put(silent,true), @@ -1038,8 +652,7 @@ teln_get_all_data(State=#state{teln_pid=Pid,prx=Prx},Data,Acc,LastLine,Polls) -> found_prompt=false, prompt_check=true}). -%% @hidden -%% @doc Externally the silent_teln_expect function shall only be used +%% Externally the silent_teln_expect function shall only be used %% by the TargetModule, i.e. the target specific module which %% implements connect/2 and get_prompt_regexp/0. silent_teln_expect(Name,Pid,Data,Pattern,Prx,Opts) -> @@ -1057,9 +670,9 @@ silent_teln_expect(Name,Pid,Data,Pattern,Prx,Opts) -> %% 2) Sequence: Several patterns are given, and they are matched in %% the order they appear in the pattern list. %% 3a) Repeat (single): 1) is repeated either N times or until a halt -%% condition is fullfilled. +%% condition is fulfilled. %% 3b) Repeat (sequence): 2) is repeated either N times or until a -%% halt condition is fullfilled. +%% halt condition is fulfilled. teln_expect(Name,Pid,Data,Pattern0,Prx,Opts) -> HaltPatterns = case get_ignore_prompt(Opts) of @@ -1203,7 +816,7 @@ wait_for_prompt2(Prompt, Pattern, Opts) -> {true,Pattern1,Opts1}. %% Repeat either single or sequence. All match results are accumulated -%% and returned when a halt condition is fulllfilled. +%% and returned when a halt condition is fulfilled. repeat_expect(_Name,_Pid,Rest,_Pattern,Acc,#eo{repeat=0}) -> {ok,lists:reverse(Acc),done,Rest}; repeat_expect(Name,Pid,Data,Pattern,Acc,EO) -> @@ -1342,7 +955,7 @@ one_expect1(Name,Pid,Data,Pattern,Rest,EO) -> %% 2) Sequence. %% First the whole data chunk is searched for a prompt (to avoid doing %% a regexp match for the prompt at each line). -%% If we are searching for anyting else, the datachunk is split into +%% If we are searching for anything else, the datachunk is split into %% lines and each line is matched against the first pattern in the list. %% When a match is found, the match result is accumulated, and we keep %% searching for the next pattern in the list. @@ -1530,8 +1143,6 @@ add_tabs([],[$\n|Acc],LastLine) -> add_tabs([],[],LastLine) -> {[],lists:reverse(LastLine)}. - -%%% @hidden teln_receive_until_prompt(Pid,Prx,Timeout) -> Fun = fun() -> teln_receive_until_prompt(Pid,Prx,[],[]) end, ct_gen_conn:do_within_time(Fun, Timeout). diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl index bd3755722f..2c18caf18f 100644 --- a/lib/common_test/src/ct_testspec.erl +++ b/lib/common_test/src/ct_testspec.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2017. All Rights Reserved. +%% Copyright Ericsson AB 2006-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,10 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework functions handling test specifications. -%%% -%%% <p>This module exports functions that are used within CT to -%%% scan and parse test specifikations.</p> -module(ct_testspec). -export([prepare_tests/1, prepare_tests/2, diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl index e904bb1e7c..d8fd401a64 100644 --- a/lib/common_test/src/ct_util.erl +++ b/lib/common_test/src/ct_util.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,11 +18,11 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework Utilities. +%%% Common Test Framework Utilities. %%% -%%% <p>This is a support module for the Common Test Framework. It +%%% This is a support module for the Common Test Framework. It %%% implements the process ct_util_server which acts like a data -%%% holder for suite, configuration and connection data.</p> +%%% holder for suite, configuration and connection data. %%% -module(ct_util). @@ -83,20 +83,20 @@ %%%----------------------------------------------------------------- start() -> start(normal, ".", ?default_verbosity). -%%% @spec start(Mode) -> Pid | exit(Error) +%%% -spec start(Mode) -> Pid | exit(Error) %%% Mode = normal | interactive %%% Pid = pid() %%% -%%% @doc Start start the ct_util_server process +%%% Start start the ct_util_server process %%% (tool-internal use only). %%% -%%% <p>This function is called from ct_run.erl. It starts and initiates -%%% the <code>ct_util_server</code></p> +%%% This function is called from ct_run.erl. It starts and initiates +%%% the ct_util_server %%% -%%% <p>Returns the process identity of the -%%% <code>ct_util_server</code>.</p> +%%% Returns the process identity of the +%%% ct_util_server. %%% -%%% @see ct +%%% See ct. start(LogDir) when is_list(LogDir) -> start(normal, LogDir, ?default_verbosity); start(Mode) -> @@ -520,19 +520,19 @@ get_key_from_name(Name)-> ct_config:get_key_from_name(Name). %%%----------------------------------------------------------------- -%%% @spec register_connection(TargetName,Address,Callback,Handle) -> +%%% -spec register_connection(TargetName,Address,Callback,Handle) -> %%% ok | {error,Reason} %%% TargetName = ct:target_name() %%% Address = term() %%% Callback = atom() %%% Handle = term %%% -%%% @doc Register a new connection (tool-internal use only). +%%% Register a new connection (tool-internal use only). %%% -%%% <p>This function can be called when a new connection is +%%% This function can be called when a new connection is %%% established. The connection data is stored in the connection %%% table, and ct_util will close all registered connections when the -%%% test is finished by calling <code>Callback:close/1</code>.</p> +%%% test is finished by calling Callback:close/1. register_connection(TargetName,Address,Callback,Handle) -> %% If TargetName is a registered alias for a config %% variable, use it as reference for the connection, @@ -553,28 +553,28 @@ register_connection(TargetName,Address,Callback,Handle) -> ok. %%%----------------------------------------------------------------- -%%% @spec unregister_connection(Handle) -> ok +%%% -spec unregister_connection(Handle) -> ok %%% Handle = term %%% -%%% @doc Unregister a connection (tool-internal use only). +%%% Unregister a connection (tool-internal use only). %%% -%%% <p>This function should be called when a registered connection is +%%% This function should be called when a registered connection is %%% closed. It removes the connection data from the connection -%%% table.</p> +%%% table. unregister_connection(Handle) -> ets:delete(?conn_table,Handle), ok. %%%----------------------------------------------------------------- -%%% @spec does_connection_exist(TargetName,Address,Callback) -> +%%% -spec does_connection_exist(TargetName,Address,Callback) -> %%% {ok,Handle} | false %%% TargetName = ct:target_name() %%% Address = address %%% Callback = atom() %%% Handle = term() %%% -%%% @doc Check if a connection already exists. +%%% Check if a connection already exists. does_connection_exist(TargetName,Address,Callback) -> case ct_config:get_key_from_name(TargetName) of {ok,_Key} -> @@ -594,7 +594,7 @@ does_connection_exist(TargetName,Address,Callback) -> end. %%%----------------------------------------------------------------- -%%% @spec get_connection(TargetName,Callback) -> +%%% -spec get_connection(TargetName,Callback) -> %%% {ok,Connection} | {error,Reason} %%% TargetName = ct:target_name() %%% Callback = atom() @@ -602,8 +602,8 @@ does_connection_exist(TargetName,Address,Callback) -> %%% Handle = term() %%% Address = term() %%% -%%% @doc Return the connection for <code>Callback</code> on the -%%% given target (<code>TargetName</code>). +%%% Return the connection for Callback on the +%%% given target (TargetName). get_connection(TargetName,Callback) -> %% check that TargetName is a registered alias case ct_config:get_key_from_name(TargetName) of @@ -624,7 +624,7 @@ get_connection(TargetName,Callback) -> end. %%%----------------------------------------------------------------- -%%% @spec get_connections(ConnPid) -> +%%% -spec get_connections(ConnPid) -> %%% {ok,Connections} | {error,Reason} %%% Connections = [Connection] %%% Connection = {TargetName,Handle,Callback,Address} @@ -633,8 +633,8 @@ get_connection(TargetName,Callback) -> %%% Callback = atom() %%% Address = term() %%% -%%% @doc Get data for all connections associated with a particular -%%% connection pid (see Callback:init/3). +%%% Get data for all connections associated with a particular +%%% connection pid (see Callback:init/3). get_connections(ConnPid) -> Conns = ets:tab2list(?conn_table), lists:flatmap(fun(#conn{targetref=TargetName, @@ -654,8 +654,7 @@ get_connections(ConnPid) -> end, Conns). %%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:get_target_name/1 +%%% Equivalent to ct:get_target_name/1 get_target_name(Handle) -> case ets:select(?conn_table,[{#conn{handle=Handle,targetref='$1',_='_'}, [], @@ -667,17 +666,14 @@ get_target_name(Handle) -> end. %%%----------------------------------------------------------------- -%%% @spec close_connections() -> ok +%%% -spec close_connections() -> ok %%% -%%% @doc Close all open connections. +%%% Close all open connections. close_connections() -> close_connections(ets:tab2list(?conn_table)), ok. %%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc override_silence_all_connections() -> Protocols = [telnet,ftp,rpc,snmp,ssh], override_silence_connections(Protocols), @@ -738,12 +734,12 @@ reset_silent_connections() -> %%%----------------------------------------------------------------- -%%% @spec stop(Info) -> ok +%%% -spec stop(Info) -> ok %%% -%%% @doc Stop the ct_util_server and close all existing connections +%%% Stop the ct_util_server and close all existing connections %%% (tool-internal use only). %%% -%%% @see ct +%%% See ct. stop(Info) -> case whereis(ct_util_server) of undefined -> @@ -757,26 +753,25 @@ stop(Info) -> end. %%%----------------------------------------------------------------- -%%% @spec update_last_run_index() -> ok +%%% -spec update_last_run_index() -> ok %%% -%%% @doc Update <code>ct_run.<timestamp>/index.html</code> +%%% Update ct_run.<timestamp>/index.html %%% (tool-internal use only). update_last_run_index() -> call(update_last_run_index). %%%----------------------------------------------------------------- -%%% @spec get_mode() -> Mode +%%% -spec get_mode() -> Mode %%% Mode = normal | interactive %%% -%%% @doc Return the current mode of the ct_util_server +%%% Return the current mode of the ct_util_server %%% (tool-internal use only). get_mode() -> call(get_mode). %%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:listenv/1 +%%% Equivalent to ct:listenv/1 listenv(Telnet) -> case ct_telnet:send(Telnet,"listenv") of ok -> @@ -790,8 +785,7 @@ listenv(Telnet) -> end. %%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:parse_table/1 +%%% Equivalent to ct:parse_table/1 parse_table(Data) -> {Heading, Rest} = get_headings(Data), Lines = parse_row(Rest,[],size(Heading)), @@ -831,16 +825,10 @@ remove_space([],Acc) -> %%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc is_test_dir(Dir) -> lists:last(string:lexemes(filename:basename(Dir), "_")) == "test". %%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc get_testdir(Dir, all) -> Abs = abs_name(Dir), case is_test_dir(Abs) of @@ -884,9 +872,6 @@ get_testdir(Dir, _) -> get_testdir(Dir, all). %%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc get_attached(TCPid) -> case dbg_iserver:safe_call({get_attpid,TCPid}) of {ok,AttPid} when is_pid(AttPid) -> @@ -896,9 +881,6 @@ get_attached(TCPid) -> end. %%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc kill_attached(undefined,_AttPid) -> ok; kill_attached(_TCPid,undefined) -> @@ -913,9 +895,6 @@ kill_attached(TCPid,AttPid) -> %%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc warn_duplicates(Suites) -> Warn = fun(Mod) -> @@ -934,9 +913,6 @@ warn_duplicates(Suites) -> ok. %%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc mark_process() -> mark_process(system). @@ -998,9 +974,6 @@ remaining_test_procs() -> {TestProcs, SharedGL, OtherGLs}. %%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc get_profile_data() -> get_profile_data(all). diff --git a/lib/common_test/src/cth_log_redirect.erl b/lib/common_test/src/cth_log_redirect.erl index 417ea615a3..99c484de48 100644 --- a/lib/common_test/src/cth_log_redirect.erl +++ b/lib/common_test/src/cth_log_redirect.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2017. All Rights Reserved. +%% Copyright Ericsson AB 2011-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,11 +19,9 @@ %% -module(cth_log_redirect). -%%% @doc Common Test Framework functions handling test specifications. +%%% Common Test Framework functions handling test specifications. %%% -%%% <p>This module redirects sasl and error logger info to common test log.</p> -%%% @end - +%%% This module redirects sasl and error logger info to common test log. %% CTH Callbacks -export([id/1, init/2, @@ -138,7 +136,7 @@ start_log_handler() -> init([]) -> {ok, #eh_state{log_func = tc_log_async}}. -log(#{msg:={report,Msg},meta:=#{domain:=[beam,erlang,otp,sasl]}}=Log,Config) -> +log(#{msg:={report,Msg},meta:=#{domain:=[otp,sasl]}}=Log,Config) -> case whereis(sasl_sup) of undefined -> ok; % sasl application is not started @@ -164,7 +162,7 @@ log(#{msg:={report,Msg},meta:=#{domain:=[beam,erlang,otp,sasl]}}=Log,Config) -> do_log(add_log_category(Log,sasl),Config) end end; -log(#{meta:=#{domain:=[beam,erlang,otp]}}=Log,Config) -> +log(#{meta:=#{domain:=[otp]}}=Log,Config) -> do_log(add_log_category(Log,error_logger),Config); log(#{meta:=#{domain:=_}},_) -> ok; diff --git a/lib/common_test/src/cth_surefire.erl b/lib/common_test/src/cth_surefire.erl index 4407ff56c1..b0742717ae 100644 --- a/lib/common_test/src/cth_surefire.erl +++ b/lib/common_test/src/cth_surefire.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2012-2017. All Rights Reserved. +%% Copyright Ericsson AB 2012-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,10 +18,10 @@ %% %CopyrightEnd% %%-------------------------------------------------------------------- -%%% @doc Common Test Framework functions handling test specifications. +%%% Common Test Framework functions handling test specifications. %%% -%%% <p>This module creates a junit report of the test run if plugged in -%%% as a suite_callback.</p> +%%% This module creates a junit report of the test run if plugged in +%%% as a suite_callback. -module(cth_surefire). diff --git a/lib/common_test/src/unix_telnet.erl b/lib/common_test/src/unix_telnet.erl index 5992f26e6d..7a210237a8 100644 --- a/lib/common_test/src/unix_telnet.erl +++ b/lib/common_test/src/unix_telnet.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2017. All Rights Reserved. +%% Copyright Ericsson AB 2004-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,39 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Callback module for ct_telnet, for connecting to a telnet -%%% server on a unix host. -%%% -%%% <p>It requires the following entry in the config file:</p> -%%% <pre> -%%% {unix,[{telnet,HostNameOrIpAddress}, -%%% {port,PortNum}, % optional -%%% {username,UserName}, -%%% {password,Password}, -%%% {keep_alive,Bool}, % optional -%%% {tcp_nodely,Bool}]} % optional</pre> -%%% -%%% <p>To communicate via telnet to the host specified by -%%% <code>HostNameOrIpAddress</code>, use the interface functions in -%%% <code>ct_telnet</code>, e.g. <code>open(Name), cmd(Name,Cmd), ...</code>.</p> -%%% -%%% <p><code>Name</code> is the name you allocated to the unix host in -%%% your <code>require</code> statement. E.g.</p> -%%% <pre> suite() -> [{require,Name,{unix,[telnet]}}].</pre> -%%% <p>or</p> -%%% <pre> ct:require(Name,{unix,[telnet]}).</pre> -%%% -%%% <p>The "keep alive" activity (i.e. that Common Test sends NOP to the server -%%% every 10 seconds if the connection is idle) may be enabled or disabled for one -%%% particular connection as described here. It may be disabled for all connections -%%% using <c>telnet_settings</c> (see <c>ct_telnet</c>).</p> -%%% -%%% <p>Note that the <code>{port,PortNum}</code> tuple is optional and if -%%% omitted, default telnet port 23 will be used. Also the <c>keep_alive</c> tuple -%%% is optional, and the value defauls to true (enabled).</p> -%%% -%%% @see ct -%%% @see ct_telnet -module(unix_telnet). %% Callbacks for ct_telnet.erl @@ -61,36 +28,9 @@ -define(password,"Password: "). -define(prx,"login: |Password: |\\\$ |> "). -%%%----------------------------------------------------------------- -%%% @spec get_prompt_regexp() -> PromptRegexp -%%% PromptRegexp = ct_telnet:prompt_regexp() -%%% -%%% @doc Callback for ct_telnet.erl. -%%% -%%% <p>Return a suitable regexp string that will match common -%%% prompts for users on unix hosts.</p> get_prompt_regexp() -> ?prx. - -%%%----------------------------------------------------------------- -%%% @spec connect(ConnName,Ip,Port,Timeout,KeepAlive,Extra) -> -%%% {ok,Handle} | {error,Reason} -%%% ConnName = ct:target_name() -%%% Ip = string() | {integer(),integer(),integer(),integer()} -%%% Port = integer() -%%% Timeout = integer() -%%% KeepAlive = bool() -%%% TCPNoDelay = bool() -%%% Extra = ct:target_name() | {Username,Password} -%%% Username = string() -%%% Password = string() -%%% Handle = ct_telnet:handle() -%%% Reason = term() -%%% -%%% @doc Callback for ct_telnet.erl. -%%% -%%% <p>Setup telnet connection to a unix host.</p> connect(ConnName,Ip,Port,Timeout,KeepAlive,TCPNoDelay,Extra) -> case Extra of {Username,Password} -> diff --git a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl index 4e013b8056..e9e8b2a54d 100644 --- a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl +++ b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2012-2016. All Rights Reserved. +%% Copyright Ericsson AB 2012-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -23,9 +23,7 @@ %% Description: %% This file contains the test cases for the code coverage support %% -%% @author Support -%% @doc Test of code coverage support in common_test -%% @end +%% Test of code coverage support in common_test %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- -module(cover_SUITE). diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl index 530ee09654..ef8c05cb2e 100644 --- a/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl +++ b/lib/common_test/test/ct_error_SUITE_data/error/test/verify_config.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,9 +18,9 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Example Suite Callback module. +%%% Common Test Example Suite Callback module. %%% -%%% <p>This module gives an example of a common test CTH (Common Test Hook). +%%% This module gives an example of a common test CTH (Common Test Hook). %%% There are many ways to add a CTH to a test run, you can do it either in %%% the command line using -ct_hook, in a test spec using %%% {ct_hook,M} or in the suite it self by returning ct_hook @@ -31,7 +31,7 @@ %%% it will be stopped after end_per_suite and so on. See terminate %%% documentation for a table describing the scoping machanics. %%% -%%% All of callbacks except init/1 in a CTH are optional.</p> +%%% All of callbacks except init/1 in a CTH are optional. -module(verify_config). @@ -69,14 +69,14 @@ -record(state, { id = ?MODULE :: term()}). -%% @doc Always called before any other callback function. Use this to initiate +%% Always called before any other callback function. Use this to initiate %% any common state. It should return an state for this CTH. -spec init(Id :: term(), Opts :: proplists:proplist()) -> {ok, State :: #state{}}. init(Id, Opts) -> {ok,Opts}. -%% @doc The ID is used to uniquly identify an CTH instance, if two CTH's +%% The ID is used to uniquly identify an CTH instance, if two CTH's %% return the same ID the seconds CTH is ignored. This function should NOT %% have any side effects as it might be called multiple times by common test. -spec id(Opts :: proplists:proplist()) -> @@ -84,7 +84,7 @@ init(Id, Opts) -> id(Opts) -> os:timestamp(). -%% @doc Called before init_per_suite is called. Note that this callback is +%% Called before init_per_suite is called. Note that this callback is %% only called if the CTH is added before init_per_suite is run (eg. in a test %% specification, suite/0 function etc). %% You can change the config in the this function. @@ -95,7 +95,7 @@ id(Opts) -> pre_init_per_suite(Suite,Config,State) -> {Config, State}. -%% @doc Called after init_per_suite. +%% Called after init_per_suite. %% you can change the return value in this function. -spec post_init_per_suite(Suite :: atom(), Config :: config(), @@ -105,7 +105,7 @@ pre_init_per_suite(Suite,Config,State) -> post_init_per_suite(Suite,Config,Return,State) -> {Return, State}. -%% @doc Called before end_per_suite. The config/state can be changed here, +%% Called before end_per_suite. The config/state can be changed here, %% though it will only affect the *end_per_suite function. -spec pre_end_per_suite(Suite :: atom(), Config :: config() | skip_or_fail(), @@ -114,7 +114,7 @@ post_init_per_suite(Suite,Config,Return,State) -> pre_end_per_suite(Suite,Config,State) -> {Config, State}. -%% @doc Called after end_per_suite. Note that the config cannot be +%% Called after end_per_suite. Note that the config cannot be %% changed here, only the status of the suite. -spec post_end_per_suite(Suite :: atom(), Config :: config(), @@ -124,7 +124,7 @@ pre_end_per_suite(Suite,Config,State) -> post_end_per_suite(Suite,Config,Return,State) -> {Return, State}. -%% @doc Called before each init_per_group. +%% Called before each init_per_group. %% You can change the config in this function. -spec pre_init_per_group(Group :: atom(), Config :: config(), @@ -133,7 +133,7 @@ post_end_per_suite(Suite,Config,Return,State) -> pre_init_per_group(Group,Config,State) -> {Config, State}. -%% @doc Called after each init_per_group. +%% Called after each init_per_group. %% You can change the return value in this function. -spec post_init_per_group(Group :: atom(), Config :: config(), @@ -143,7 +143,7 @@ pre_init_per_group(Group,Config,State) -> post_init_per_group(Group,Config,Return,State) -> {Return, State}. -%% @doc Called after each end_per_group. The config/state can be changed here, +%% Called after each end_per_group. The config/state can be changed here, %% though it will only affect the *end_per_group functions. -spec pre_end_per_group(Group :: atom(), Config :: config() | skip_or_fail(), @@ -152,7 +152,7 @@ post_init_per_group(Group,Config,Return,State) -> pre_end_per_group(Group,Config,State) -> {Config, State}. -%% @doc Called after each end_per_group. Note that the config cannot be +%% Called after each end_per_group. Note that the config cannot be %% changed here, only the status of the group. -spec post_end_per_group(Group :: atom(), Config :: config(), @@ -162,7 +162,7 @@ pre_end_per_group(Group,Config,State) -> post_end_per_group(Group,Config,Return,State) -> {Return, State}. -%% @doc Called before each test case. +%% Called before each test case. %% You can change the config in this function. -spec pre_init_per_testcase(TC :: atom(), Config :: config(), @@ -171,7 +171,7 @@ post_end_per_group(Group,Config,Return,State) -> pre_init_per_testcase(TC,Config,State) -> {Config, State}. -%% @doc Called after each test case. Note that the config cannot be +%% Called after each test case. Note that the config cannot be %% changed here, only the status of the test case. -spec post_end_per_testcase(TC :: atom(), Config :: config(), @@ -198,7 +198,7 @@ post_end_per_testcase(TC,Config,Return,State) -> end, {Return, State}. -%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group, +%% Called after post_init_per_suite, post_end_per_suite, post_init_per_group, %% post_end_per_group and post_end_per_tc if the suite, group or test case failed. %% This function should be used for extra cleanup which might be needed. %% It is not possible to modify the config or the status of the test run. @@ -209,7 +209,7 @@ post_end_per_testcase(TC,Config,Return,State) -> on_tc_fail(TC, Reason, State) -> State. -%% @doc Called when a test case is skipped by either user action +%% Called when a test case is skipped by either user action %% or due to an init function failing. Test case can be %% end_per_suite, init_per_group, end_per_group and the actual test cases. -spec on_tc_skip(TC :: end_per_suite | @@ -221,7 +221,7 @@ on_tc_fail(TC, Reason, State) -> on_tc_skip(TC, Reason, State) -> State. -%% @doc Called when the scope of the CTH is done, this depends on +%% Called when the scope of the CTH is done, this depends on %% when the CTH was specified. This translation table describes when this %% function is called. %% diff --git a/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl b/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl index 07b21b4178..e4c7be3cac 100644 --- a/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl +++ b/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2016. All Rights Reserved. +%% Copyright Ericsson AB 2008-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,10 +18,10 @@ %% %CopyrightEnd% %% -%%% @doc Event handler module +%%% Event handler module %%% -%%% <p>This is an event handler module used for testing that -%%% Common Test generates events as expected.</p> +%%% This is an event handler module used for testing that +%%% Common Test generates events as expected. %%% -module(eh_A). diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl index d400348354..404fb33476 100644 --- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl @@ -1,7 +1,7 @@ %%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -29,7 +29,6 @@ %% Test server callback functions
%%--------------------------------------------------------------------
-%% @doc
%% Config - [tuple()]
%% A list of key/value pairs, holding the test case configuration.
%%
@@ -38,27 +37,23 @@ %% Note: This function is free to add any key/value pairs to the Config
%% variable, but should NOT alter/remove any existing entries.
%%
-%% @spec init_per_suite(Config) -> Config
-%% @end
+%% -spec init_per_suite(Config) -> Config
%%--------------------------------------------------------------------
init_per_suite(Config) ->
Config.
%%--------------------------------------------------------------------
-%% @doc
%% Config - [tuple()]
%% A list of key/value pairs, holding the test case configuration.
%%
%% Cleanup after the whole suite
%%
-%% @spec end_per_suite(Config) -> _
-%% @end
+%% -spec end_per_suite(Config) -> _
%%--------------------------------------------------------------------
end_per_suite(_Config) ->
ok.
%%--------------------------------------------------------------------
-%% @doc
%% Case - atom()
%% Name of the test case that is about to be run.
%% Config - [tuple()]
@@ -70,14 +65,12 @@ end_per_suite(_Config) -> %% variable, but should NOT alter/remove any existing entries.
%% Initiation before each test case
%%
-%% @spec init_per_testcase(TestCase, Config) -> Config
-%% @end
+%% -spec init_per_testcase(TestCase, Config) -> Config
%%--------------------------------------------------------------------
init_per_testcase(_TestCase, Config) ->
[{ct_hooks,[empty_cth]}|Config].
%%--------------------------------------------------------------------
-%% @doc
%% Case - atom()
%% Name of the test case that is about to be run.
%% Config - [tuple()]
@@ -85,22 +78,19 @@ init_per_testcase(_TestCase, Config) -> %%
%% Cleanup after each test case
%%
-%% @spec end_per_testcase(TestCase, Config) -> _
-%% @end
+%% -spec end_per_testcase(TestCase, Config) -> _
%%--------------------------------------------------------------------
end_per_testcase(_TestCase, _Config) ->
ok.
%%--------------------------------------------------------------------
-%% @doc
%% TestCases - [Case]
%% Case - atom()
%% Name of a test case.
%%
%% Returns a list of all test cases in this test suite
%%
-%% @spec all() -> TestCases
-%% @end
+%% -spec all() -> TestCases
%%--------------------------------------------------------------------
all() ->
[test_case].
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl index 961ea68d2d..c648367838 100644 --- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,9 +18,9 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Example Suite Callback module. +%%% Common Test Example Suite Callback module. %%% -%%% <p>This module gives an example of a common test CTH (Common Test Hook). +%%% This module gives an example of a common test CTH (Common Test Hook). %%% There are many ways to add a CTH to a test run, you can do it either in %%% the command line using -ct_hook, in a test spec using %%% {ct_hook,M} or in the suite it self by returning ct_hook @@ -31,7 +31,7 @@ %%% it will be stopped after end_per_suite and so on. See terminate %%% documentation for a table describing the scoping machanics. %%% -%%% All of callbacks except init/1 in a CTH are optional.</p> +%%% All of callbacks except init/1 in a CTH are optional. -module(empty_cth). @@ -71,7 +71,7 @@ -record(state, { id = ?MODULE :: term()}). -%% @doc Always called before any other callback function. Use this to initiate +%% Always called before any other callback function. Use this to initiate %% any common state. It should return an state for this CTH. -spec init(Id :: term(), Opts :: proplists:proplist()) -> {ok, State :: #state{}}. @@ -81,7 +81,7 @@ init(Id, Opts) -> ct:log("~w:init called", [?MODULE]), {ok,Opts}. -%% @doc The ID is used to uniquly identify an CTH instance, if two CTH's +%% The ID is used to uniquly identify an CTH instance, if two CTH's %% return the same ID the seconds CTH is ignored. This function should NOT %% have any side effects as it might be called multiple times by common test. -spec id(Opts :: proplists:proplist()) -> @@ -92,7 +92,7 @@ id(Opts) -> ct:log("~w:id called", [?MODULE]), ct_test_support:unique_timestamp(). -%% @doc Called before init_per_suite is called. Note that this callback is +%% Called before init_per_suite is called. Note that this callback is %% only called if the CTH is added before init_per_suite is run (eg. in a test %% specification, suite/0 function etc). %% You can change the config in the this function. @@ -108,7 +108,7 @@ pre_init_per_suite(Suite,Config,State) -> ct:log("~w:pre_init_per_suite(~w) called", [?MODULE,Suite]), {Config, State}. -%% @doc Called after init_per_suite. +%% Called after init_per_suite. %% you can change the return value in this function. -spec post_init_per_suite(Suite :: atom(), Config :: config(), @@ -123,7 +123,7 @@ post_init_per_suite(Suite,Config,Return,State) -> ct:log("~w:post_init_per_suite(~w) called", [?MODULE,Suite]), {Return, State}. -%% @doc Called before end_per_suite. The config/state can be changed here, +%% Called before end_per_suite. The config/state can be changed here, %% though it will only affect the *end_per_suite function. -spec pre_end_per_suite(Suite :: atom(), Config :: config() | skip_or_fail(), @@ -137,7 +137,7 @@ pre_end_per_suite(Suite,Config,State) -> ct:log("~w:pre_end_per_suite(~w) called", [?MODULE,Suite]), {Config, State}. -%% @doc Called after end_per_suite. Note that the config cannot be +%% Called after end_per_suite. Note that the config cannot be %% changed here, only the status of the suite. -spec post_end_per_suite(Suite :: atom(), Config :: config(), @@ -152,7 +152,7 @@ post_end_per_suite(Suite,Config,Return,State) -> ct:log("~w:post_end_per_suite(~w) called", [?MODULE,Suite]), {Return, State}. -%% @doc Called before each init_per_group. +%% Called before each init_per_group. %% You can change the config in this function. -spec pre_init_per_group(Suite :: atom(), Group :: atom(), @@ -167,7 +167,7 @@ pre_init_per_group(Suite,Group,Config,State) -> ct:log("~w:pre_init_per_group(~w,~w) called", [?MODULE,Suite,Group]), {Config, State}. -%% @doc Called after each init_per_group. +%% Called after each init_per_group. %% You can change the return value in this function. -spec post_init_per_group(Suite :: atom(), Group :: atom(), @@ -183,7 +183,7 @@ post_init_per_group(Suite,Group,Config,Return,State) -> ct:log("~w:post_init_per_group(~w,~w) called", [?MODULE,Suite,Group]), {Return, State}. -%% @doc Called after each end_per_group. The config/state can be changed here, +%% Called after each end_per_group. The config/state can be changed here, %% though it will only affect the *end_per_group functions. -spec pre_end_per_group(Suite :: atom(), Group :: atom(), @@ -198,7 +198,7 @@ pre_end_per_group(Suite,Group,Config,State) -> ct:log("~w:pre_end_per_group(~w~w) called", [?MODULE,Suite,Group]), {Config, State}. -%% @doc Called after each end_per_group. Note that the config cannot be +%% Called after each end_per_group. Note that the config cannot be %% changed here, only the status of the group. -spec post_end_per_group(Suite :: atom(), Group :: atom(), @@ -214,7 +214,7 @@ post_end_per_group(Suite,Group,Config,Return,State) -> ct:log("~w:post_end_per_group(~w,~w) called", [?MODULE,Suite,Group]), {Return, State}. -%% @doc Called before init_per_testcase/2 for each test case. +%% Called before init_per_testcase/2 for each test case. %% You can change the config in this function. -spec pre_init_per_testcase(Suite :: atom(), TC :: atom(), @@ -229,7 +229,7 @@ pre_init_per_testcase(Suite,TC,Config,State) -> ct:log("~w:pre_init_per_testcase(~w,~w) called", [?MODULE,Suite,TC]), {Config, State}. -%% @doc Called after init_per_testcase/2, and before the test case. +%% Called after init_per_testcase/2, and before the test case. -spec post_init_per_testcase(Suite :: atom(), TC :: atom(), Config :: config(), @@ -244,7 +244,7 @@ post_init_per_testcase(Suite,TC,Config,Return,State) -> ct:log("~w:post_init_per_testcase(~w,~w) called", [?MODULE,Suite,TC]), {Return, State}. -%% @doc Called before end_per_testacse/2. No skip or fail allowed here, +%% Called before end_per_testacse/2. No skip or fail allowed here, %% only config additions. -spec pre_end_per_testcase(Suite :: atom(), TC :: atom(), @@ -259,7 +259,7 @@ pre_end_per_testcase(Suite,TC,Config,State) -> ct:log("~w:pre_end_per_testcase(~w,~w) called", [?MODULE,Suite,TC]), {Config, State}. -%% @doc Called after end_per_testcase/2 for each test case. Note that +%% Called after end_per_testcase/2 for each test case. Note that %% the config cannot be changed here, only the status of the test case. -spec post_end_per_testcase(Suite :: atom(), TC :: atom(), @@ -275,7 +275,7 @@ post_end_per_testcase(Suite,TC,Config,Return,State) -> ct:log("~w:post_end_per_testcase(~w,~w) called", [?MODULE,Suite,TC]), {Return, State}. -%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group, +%% Called after post_init_per_suite, post_end_per_suite, post_init_per_group, %% post_end_per_group and post_end_per_tc if the suite, group or test case failed. %% This function should be used for extra cleanup which might be needed. %% It is not possible to modify the config or the status of the test run. @@ -292,7 +292,7 @@ on_tc_fail(Suite, TC, Reason, State) -> ct:log("~w:on_tc_fail(~w,~w) called", [?MODULE,Suite,TC]), State. -%% @doc Called when a test case is skipped by either user action +%% Called when a test case is skipped by either user action %% or due to an init function failing. Test case can be %% end_per_suite, init_per_group, end_per_group and the actual test cases. -spec on_tc_skip(Suite :: atom(), @@ -310,7 +310,7 @@ on_tc_skip(Suite, TC, Reason, State) -> ct:log("~w:on_tc_skip(~w,~w) called", [?MODULE,Suite,TC]), State. -%% @doc Called when the scope of the CTH is done, this depends on +%% Called when the scope of the CTH is done, this depends on %% when the CTH was specified. This translation table describes when this %% function is called. %% diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl index 586589ad40..a2fa099a8c 100644 --- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl +++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2017. All Rights Reserved. +%% Copyright Ericsson AB 2013-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -23,9 +23,7 @@ %% Description: %% This file contains the test cases for the ct_netconfc API. %% -%% @author Support -%% @doc Netconf Client Interface. -%% @end +%% Netconf Client Interface. %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- -module(netconfc1_SUITE). diff --git a/lib/common_test/test/ct_repeat_testrun_SUITE_data/a_test/r1_SUITE.erl b/lib/common_test/test/ct_repeat_testrun_SUITE_data/a_test/r1_SUITE.erl index 4ce375b4ee..1a305b1516 100644 --- a/lib/common_test/test/ct_repeat_testrun_SUITE_data/a_test/r1_SUITE.erl +++ b/lib/common_test/test/ct_repeat_testrun_SUITE_data/a_test/r1_SUITE.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2016. All Rights Reserved. +%% Copyright Ericsson AB 2013-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,14 +19,6 @@ %% %%---------------------------------------------------------------------- %% File: r1_SUITE.erl -%% -%% Description: -%% -%% -%% @author Support -%% @doc -%% @end -%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- -module(r1_SUITE). -include_lib("common_test/include/ct.hrl"). diff --git a/lib/common_test/test/ct_repeat_testrun_SUITE_data/b_test/r2_SUITE.erl b/lib/common_test/test/ct_repeat_testrun_SUITE_data/b_test/r2_SUITE.erl index 77bb544080..393cbcc780 100644 --- a/lib/common_test/test/ct_repeat_testrun_SUITE_data/b_test/r2_SUITE.erl +++ b/lib/common_test/test/ct_repeat_testrun_SUITE_data/b_test/r2_SUITE.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2016. All Rights Reserved. +%% Copyright Ericsson AB 2013-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,14 +19,6 @@ %% %%---------------------------------------------------------------------- %% File: r2_SUITE.erl -%% -%% Description: -%% -%% -%% @author Support -%% @doc -%% @end -%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- -module(r2_SUITE). -include_lib("common_test/include/ct.hrl"). diff --git a/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl b/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl index a6533641d8..1c81bbe95d 100644 --- a/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl +++ b/lib/common_test/test/ct_snmp_SUITE_data/snmp_SUITE.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2012-2016. All Rights Reserved. +%% Copyright Ericsson AB 2012-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -23,9 +23,7 @@ %% Description: %% This file contains the test cases for the ct_snmp API. %% -%% @author Support -%% @doc Test of SNMP support in common_test -%% @end +%% Test of SNMP support in common_test %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- -module(snmp_SUITE). diff --git a/lib/common_test/test/ct_surefire_SUITE_data/surefire_SUITE.erl b/lib/common_test/test/ct_surefire_SUITE_data/surefire_SUITE.erl index ed10356cdd..7a73e45b43 100644 --- a/lib/common_test/test/ct_surefire_SUITE_data/surefire_SUITE.erl +++ b/lib/common_test/test/ct_surefire_SUITE_data/surefire_SUITE.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2012-2016. All Rights Reserved. +%% Copyright Ericsson AB 2012-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -23,9 +23,7 @@ %% Description: %% This file contains the test cases for cth_surefire. %% -%% @author Support -%% @doc Test of surefire support in common_test -%% @end +%% Test of surefire support in common_test %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- -module(surefire_SUITE). diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl index 2ba7c7c13f..388d5d46c6 100644 --- a/lib/common_test/test/ct_test_support.erl +++ b/lib/common_test/test/ct_test_support.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2017. All Rights Reserved. +%% Copyright Ericsson AB 2008-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,9 +18,9 @@ %% %CopyrightEnd% %% -%%% @doc Test support functions +%%% Test support functions %%% -%%% <p>This is a support module for testing the Common Test Framework.</p> +%%% This is a support module for testing the Common Test Framework. %%% -module(ct_test_support). diff --git a/lib/common_test/test/ct_test_support_eh.erl b/lib/common_test/test/ct_test_support_eh.erl index e8db52dcd3..120692dc7c 100644 --- a/lib/common_test/test/ct_test_support_eh.erl +++ b/lib/common_test/test/ct_test_support_eh.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2016. All Rights Reserved. +%% Copyright Ericsson AB 2009-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,10 +18,10 @@ %% %CopyrightEnd% %% -%%% @doc Event handler module +%%% Event handler module %%% -%%% <p>This is an event handler module used for testing that -%%% Common Test generates events as expected.</p> +%%% This is an event handler module used for testing that +%%% Common Test generates events as expected. %%% -module(ct_test_support_eh). diff --git a/lib/common_test/test/ct_verbosity_SUITE_data/simple_evh.erl b/lib/common_test/test/ct_verbosity_SUITE_data/simple_evh.erl index 03a0832e53..d1c293b4af 100644 --- a/lib/common_test/test/ct_verbosity_SUITE_data/simple_evh.erl +++ b/lib/common_test/test/ct_verbosity_SUITE_data/simple_evh.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2016. All Rights Reserved. +%% Copyright Ericsson AB 2006-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,14 +18,14 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework Event Handler +%%% Common Test Framework Event Handler %%% -%%% <p>This module implements an event handler that CT uses to +%%% This module implements an event handler that CT uses to %%% handle status and progress notifications during test runs. %%% The notifications are handled locally (per node) and passed %%% on to ct_master when CT runs in distributed mode. This %%% module may be used as a template for other event handlers -%%% that can be plugged in to handle local logging and reporting.</p> +%%% that can be plugged in to handle local logging and reporting. -module(simple_evh). -behaviour(gen_event). diff --git a/lib/common_test/test/test_server_SUITE.erl b/lib/common_test/test/test_server_SUITE.erl index edfaea1d08..05737cfac9 100644 --- a/lib/common_test/test/test_server_SUITE.erl +++ b/lib/common_test/test/test_server_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,12 +18,7 @@ %% %CopyrightEnd% %% %%%------------------------------------------------------------------- -%%% @author Lukas Larsson <[email protected]> -%%% @copyright (C) 2011, Erlang Solutions Ltd. -%%% @doc -%%% -%%% @end -%%% Created : 15 Feb 2011 by Lukas Larsson <[email protected]> +%%% Author: Lukas Larsson <[email protected]> %%%------------------------------------------------------------------- -module(test_server_SUITE). diff --git a/lib/common_test/test_server/ts_install_cth.erl b/lib/common_test/test_server/ts_install_cth.erl index 35a5ec916c..b6503fb864 100644 --- a/lib/common_test/test_server/ts_install_cth.erl +++ b/lib/common_test/test_server/ts_install_cth.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ %% %CopyrightEnd% %% -%%% @doc TS Installed SCB +%%% TS Installed SCB %%% %%% This module does what the make parts of the ts:run/x command did, %%% but not the Makefile.first parts! So they have to be done by ts or @@ -60,13 +60,13 @@ -record(state, { ts_conf_dir, target_system, install_opts, nodenames, nodes }). -%% @doc The id of this SCB +%% The id of this SCB -spec id(Opts :: term()) -> Id :: term(). id(_Opts) -> ?MODULE. -%% @doc Always called before any other callback function. +%% Always called before any other callback function. -spec init(Id :: term(), Opts :: proplists:proplist()) -> {ok, State :: #state{}}. init(_Id, Opts) -> @@ -81,7 +81,7 @@ init(_Id, Opts) -> target_system = TargetSystem, install_opts = InstallOpts } }. -%% @doc Called before init_per_suite is called. +%% Called before init_per_suite is called. -spec pre_init_per_suite(Suite :: atom(), Config :: config(), State :: #state{}) -> @@ -113,7 +113,7 @@ pre_init_per_suite(_Suite,Config,State) -> {{fail,{?MODULE,{Error,Reason, Stack}}},State} end. -%% @doc Called after init_per_suite. +%% Called after init_per_suite. -spec post_init_per_suite(Suite :: atom(), Config :: config(), Return :: config() | skip_or_fail(), @@ -123,7 +123,7 @@ post_init_per_suite(_Suite,_Config,Return,State) -> test_server_ctrl:kill_slavenodes(), {Return, State}. -%% @doc Called before end_per_suite. +%% Called before end_per_suite. -spec pre_end_per_suite(Suite :: atom(), Config :: config() | skip_or_fail(), State :: #state{}) -> @@ -131,7 +131,7 @@ post_init_per_suite(_Suite,_Config,Return,State) -> pre_end_per_suite(_Suite,Config,State) -> {Config, State}. -%% @doc Called after end_per_suite. +%% Called after end_per_suite. -spec post_end_per_suite(Suite :: atom(), Config :: config(), Return :: term(), @@ -140,7 +140,7 @@ pre_end_per_suite(_Suite,Config,State) -> post_end_per_suite(_Suite,_Config,Return,State) -> {Return, State}. -%% @doc Called before each init_per_group. +%% Called before each init_per_group. -spec pre_init_per_group(Group :: atom(), Config :: config(), State :: #state{}) -> @@ -148,7 +148,7 @@ post_end_per_suite(_Suite,_Config,Return,State) -> pre_init_per_group(_Group,Config,State) -> {add_node_name(Config, State), State}. -%% @doc Called after each init_per_group. +%% Called after each init_per_group. -spec post_init_per_group(Group :: atom(), Config :: config(), Return :: config() | skip_or_fail(), @@ -157,7 +157,7 @@ pre_init_per_group(_Group,Config,State) -> post_init_per_group(_Group,_Config,Return,State) -> {Return, State}. -%% @doc Called after each end_per_group. +%% Called after each end_per_group. -spec pre_end_per_group(Group :: atom(), Config :: config() | skip_or_fail(), State :: #state{}) -> @@ -165,7 +165,7 @@ post_init_per_group(_Group,_Config,Return,State) -> pre_end_per_group(_Group,Config,State) -> {Config, State}. -%% @doc Called after each end_per_group. +%% Called after each end_per_group. -spec post_end_per_group(Group :: atom(), Config :: config(), Return :: term(), @@ -174,7 +174,7 @@ pre_end_per_group(_Group,Config,State) -> post_end_per_group(_Group,_Config,Return,State) -> {Return, State}. -%% @doc Called before each test case. +%% Called before each test case. -spec pre_init_per_testcase(TC :: atom(), Config :: config(), State :: #state{}) -> @@ -190,7 +190,7 @@ pre_init_per_testcase(_TC,Config,State) -> post_init_per_testcase(_TC,_Config,Return,State) -> {Return, State}. -%% @doc Called after each test case. +%% Called after each test case. -spec pre_end_per_testcase(TC :: atom(), Config :: config(), State :: #state{}) -> @@ -206,7 +206,7 @@ pre_end_per_testcase(_TC,Config,State) -> post_end_per_testcase(_TC,_Config,Return,State) -> {Return, State}. -%% @doc Called after a test case failed. +%% Called after a test case failed. -spec on_tc_fail(TC :: init_per_suite | end_per_suite | init_per_group | end_per_group | atom(), Reason :: term(), State :: #state{}) -> @@ -214,7 +214,7 @@ post_end_per_testcase(_TC,_Config,Return,State) -> on_tc_fail(_TC, _Reason, State) -> State. -%% @doc Called when a test case is skipped. +%% Called when a test case is skipped. -spec on_tc_skip(TC :: end_per_suite | init_per_group | end_per_group | atom(), {tc_auto_skip, {failed, {Mod :: atom(), Function :: atom(), Reason :: term()}}} | @@ -224,7 +224,7 @@ on_tc_fail(_TC, _Reason, State) -> on_tc_skip(_TC, _Reason, State) -> State. -%% @doc Called when the scope of the SCB is done. +%% Called when the scope of the SCB is done. -spec terminate(State :: #state{}) -> term(). terminate(_State) -> diff --git a/lib/common_test/test_server/ts_run.erl b/lib/common_test/test_server/ts_run.erl index 5dbbaca916..7e12b9652c 100644 --- a/lib/common_test/test_server/ts_run.erl +++ b/lib/common_test/test_server/ts_run.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2016. All Rights Reserved. +%% Copyright Ericsson AB 1997-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -411,9 +411,9 @@ make_common_test_args(Args0, Options0, _Vars) -> end, ConfigFiles = [{config,[filename:join(ConfigPath,File) || File <- get_config_files()]}], - io_lib:format("~100000p",[[{abort_if_missing_suites,true} | - Args0++Trace++Cover++Logdir++ - ConfigFiles++Options++TimeTrap]]). + io_lib:format("~0p",[[{abort_if_missing_suites,true} | + Args0++Trace++Cover++Logdir++ + ConfigFiles++Options++TimeTrap]]). to_list(X) when is_atom(X) -> atom_to_list(X); diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk index 2dc1965878..ea3e9871cb 100644 --- a/lib/common_test/vsn.mk +++ b/lib/common_test/vsn.mk @@ -1 +1 @@ -COMMON_TEST_VSN = 1.16 +COMMON_TEST_VSN = 1.15.4 diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml index 357a940f24..bc1f68337b 100644 --- a/lib/compiler/doc/src/notes.xml +++ b/lib/compiler/doc/src/notes.xml @@ -32,219 +32,6 @@ <p>This document describes the changes made to the Compiler application.</p> -<section><title>Compiler 7.2</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p>Fixed an error in an optimization pass that caused - impossible tuple matching.</p> - <p> - Own Id: OTP-14855 Aux Id: ERL-549 </p> - </item> - <item> - <p>The exception thrown when a list comprehension was - given a non-list term was not always correct.</p> - <p> - Own Id: OTP-14992 Aux Id: ERL-572 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>Changed the default behaviour of <c>.erlang</c> - loading: <c>.erlang</c> is no longer loaded from the - current directory. <c>c:erlangrc(PathList)</c> can be - used to search and load an <c>.erlang</c> file from user - specified directories.</p> <p><c>escript</c>, - <c>erlc</c>, <c>dialyzer</c> and <c>typer</c> no longer - load an <c>.erlang</c> at all.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14439</p> - </item> - <item> - <p>Support for "tuple calls" have been removed from the - run-time system. Tuple calls was an undocumented and - unsupported feature which allowed the module argument for - an apply operation to be a tuple: <c>Var = dict:new(), - Var:size()</c>. This "feature" frequently caused - confusion, especially when such call failed. The - stacktrace would point out functions that don't exist in - the source code.</p> - <p>For legacy code that need to use parameterized modules - or tuple calls for some other reason, there is a new - compiler option called <c>tuple_calls</c>. When this - option is given, the compiler will generate extra code - that emulates the old behavior for calls where the module - is a variable.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14497</p> - </item> - <item> - <p>In code such as <c>example({ok, Val}) -> {ok, - Val}.</c> a tuple would be built. The compiler will now - automatically rewrite the code to - <c>example({ok,Val}=Tuple) -> Tuple.</c> which will - reduce code size, execution time, and remove GC - pressure.</p> - <p> - Own Id: OTP-14505</p> - </item> - <item> - <p>The optimization of <c>case</c> expression where only - one of the case arms can execute successfully has been - improved.</p> - <p> - Own Id: OTP-14525</p> - </item> - <item> - <p>Some uses of binary matching has been slightly - improved, eliminating unnecessary register shuffling.</p> - <p> - Own Id: OTP-14594 Aux Id: ERL-444 </p> - </item> - <item> - <p>There is a new <c>{compile_info,Info}</c> option for - the compiler that allows BEAM-based languages such as - Elixir and LFE to add their own compiler versions.</p> - <p> - Own Id: OTP-14615 Aux Id: PR-1558 </p> - </item> - <item> - <p>Loaded BEAM code in a 64-bit system requires less - memory because of better packing of operands for - instructions.</p> - <p>These memory savings were achieved by major - improvements to the <c>beam_makeops</c> scripts used when - building the run time system and BEAM compiler. There is - also new for documentation for <c>beam_makeops</c> that - describes how new BEAM instructions and loader - transformations can be implemented. The documentation is - found in here in a source directory or git repository: - erts/emulator/internal_doc/beam_makeops.md. An online - version can be found here: - https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/beam_makeops.md</p> - <p> - Own Id: OTP-14626</p> - </item> - <item> - <p>Size calculations for binary constructions has been - somewhat optimized, producing smaller code.</p> - <p> - Own Id: OTP-14654</p> - </item> - <item> - <p>When the value returned from a '<c>catch</c>' - expression is ignored, no stacktrace will be built if an - exception is caught. That will save time and produce less - garbage. There are also some minor optimizations of - '<c>try</c>/<c>catch</c>' both in the compiler and - run-time system.</p> - <p> - Own Id: OTP-14683</p> - </item> - <item> - <p>There is a new syntax in '<c>try/catch</c>' for - retrieving the stacktrace without calling - '<c>erlang:get_stacktrace/0</c>'. See the reference - manual for a description of the new syntax. The - '<c>erlang:get_stacktrace/0</c>' BIF is now - deprecated.</p> - <p> - Own Id: OTP-14692</p> - </item> - <item> - <p>The following is an internal change in the compiler, - that is not noticeable for normal use of the compiler: - The module <c>v3_life</c> has been removed. Its - functionality has been simplified and integrated into - <c>v3_codegen</c>.</p> - <p> - Own Id: OTP-14712</p> - </item> - <item> - <p>The optimization of binary matching that delays - creation of sub binaries (see the Efficiency Guide) could - be thwarted by the argument order and could be necessary - to change the argument order. The compiler has now become - smarter and can handle any argument order.</p> - <p> - Own Id: OTP-14774</p> - </item> - <item> - <p>When the compiler was faced with complex case - expressions it would unnecessarily allocate stack - elements and shuffle data between x and y registers. - Improved code generation to only allocate a stack frame - when strictly necessary.</p> - <p> - Own Id: OTP-14808 Aux Id: ERL-514 </p> - </item> - <item> - <p>There is a new option '<c>makedep_side_effect</c>' for - the compiler and <c>-MMD</c> for '<c>erlc</c>' that - generates dependencies and continues to compile as - normal.</p> - <p> - Own Id: OTP-14830</p> - </item> - <item> - <p>When compiling modules with huge functions, the - compiler would generate a lot of atoms for its internal, - sometimes so many that the atom table would overflow. The - compiler has been rewritten to generate far less internal - atoms to avoid filling the atom table.</p> - <p> - Own Id: OTP-14968 Aux Id: ERL-563 </p> - </item> - <item> - <p>External funs with literal values for module, name, - and arity (e.g. <c>erlang:abs/1</c>) are now treated as - literals. That means more efficient code that produces - less garbage on the heap.</p> - <p> - Own Id: OTP-15003</p> - </item> - <item> - <p>Two new guards BIFs operating on maps have been added: - <c>map_get/2</c> and <c>is_map_key/2</c>. They do the - same as <c>maps:get/2</c> and <c>maps:is_key/2</c>, - respectively, except that they are allowed to be used in - guards.</p> - <p> - Own Id: OTP-15037 Aux Id: PR-1784, PR-1802 </p> - </item> - <item> - <p>A call or apply of a literal external fun will be - replaced with a direct call.</p> - <p> - Own Id: OTP-15044 Aux Id: ERL-614 </p> - </item> - <item> - <p>Part of EEP-44 has been implemented.</p> - <p>There is a new predefined macro called - <c>OTP_RELEASE</c> which is an integer indicating the OTP - release number (its value is <c>21</c> in this - release).</p> - <p>There are new preprocessor directives - <c>-if(Condition).</c> and <c>-elif(Condition).</c>. The - <c>if/elif</c> supports the builtin function - <c>defined(Symbol)</c>.</p> - <p> - Own Id: OTP-15087 Aux Id: PR-1810 </p> - </item> - </list> - </section> - -</section> - <section><title>Compiler 7.1.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl index 5ef340c831..df0321e85a 100644 --- a/lib/compiler/src/beam_asm.erl +++ b/lib/compiler/src/beam_asm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2017. All Rights Reserved. +%% Copyright Ericsson AB 1996-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -475,7 +475,7 @@ encode_alloc_list_1([{floats,Floats}|T], Dict, Acc0) -> encode_alloc_list_1([], Dict, Acc) -> {iolist_to_binary(Acc),Dict}. --spec encode(non_neg_integer(), integer()) -> iodata(). +-spec encode(non_neg_integer(), integer()) -> iolist() | integer(). encode(Tag, N) when N < 0 -> encode1(Tag, negative_to_bytes(N)); diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl index c33de217bd..576d20505d 100644 --- a/lib/compiler/src/beam_jump.erl +++ b/lib/compiler/src/beam_jump.erl @@ -156,46 +156,41 @@ function({function,Name,Arity,CLabel,Asm0}) -> %%% share(Is0) -> - Is1 = eliminate_fallthroughs(Is0, []), - Is2 = find_fixpoint(fun(Is) -> - share_1(Is, #{}, #{}, [], []) - end, Is1), - reverse(Is2). + %% We will get more sharing if we never fall through to a label. + Is = eliminate_fallthroughs(Is0, []), + share_1(Is, #{}, [], []). -share_1([{label,L}=Lbl|Is], Dict0, Lbls0, [_|_]=Seq, Acc) -> +share_1([{label,L}=Lbl|Is], Dict0, [_|_]=Seq, Acc) -> case maps:find(Seq, Dict0) of error -> Dict = maps:put(Seq, L, Dict0), - share_1(Is, Dict, Lbls0, [], [Lbl|Seq ++ Acc]); + share_1(Is, Dict, [], [Lbl|Seq ++ Acc]); {ok,Label} -> - Lbls = maps:put(L, Label, Lbls0), - share_1(Is, Dict0, Lbls, [], [Lbl,{jump,{f,Label}}|Acc]) + share_1(Is, Dict0, [], [Lbl,{jump,{f,Label}}|Acc]) end; -share_1([{func_info,_,_,_}|_]=Is, _, Lbls, [], Acc) when Lbls =/= #{} -> - beam_utils:replace_labels(Acc, Is, Lbls, fun(Old) -> Old end); -share_1([{func_info,_,_,_}|_]=Is, _, Lbls, [], Acc) when Lbls =:= #{} -> - reverse(Acc, Is); -share_1([{'catch',_,_}=I|Is], Dict0, Lbls0, Seq, Acc) -> - {Dict,Lbls} = clean_non_sharable(Dict0, Lbls0), - share_1(Is, Dict, Lbls, [I|Seq], Acc); -share_1([{'try',_,_}=I|Is], Dict0, Lbls0, Seq, Acc) -> - {Dict,Lbls} = clean_non_sharable(Dict0, Lbls0), - share_1(Is, Dict, Lbls, [I|Seq], Acc); -share_1([{try_case,_}=I|Is], Dict0, Lbls0, Seq, Acc) -> - {Dict,Lbls} = clean_non_sharable(Dict0, Lbls0), - share_1(Is, Dict, Lbls, [I|Seq], Acc); -share_1([{catch_end,_}=I|Is], Dict0, Lbls0, Seq, Acc) -> - {Dict,Lbls} = clean_non_sharable(Dict0, Lbls0), - share_1(Is, Dict, Lbls, [I|Seq], Acc); -share_1([I|Is], Dict, Lbls, Seq, Acc) -> +share_1([{func_info,_,_,_}=I|Is], _, [], Acc) -> + reverse(Is, [I|Acc]); +share_1([{'catch',_,_}=I|Is], Dict0, Seq, Acc) -> + Dict = clean_non_sharable(Dict0), + share_1(Is, Dict, [I|Seq], Acc); +share_1([{'try',_,_}=I|Is], Dict0, Seq, Acc) -> + Dict = clean_non_sharable(Dict0), + share_1(Is, Dict, [I|Seq], Acc); +share_1([{try_case,_}=I|Is], Dict0, Seq, Acc) -> + Dict = clean_non_sharable(Dict0), + share_1(Is, Dict, [I|Seq], Acc); +share_1([{catch_end,_}=I|Is], Dict0, Seq, Acc) -> + Dict = clean_non_sharable(Dict0), + share_1(Is, Dict, [I|Seq], Acc); +share_1([I|Is], Dict, Seq, Acc) -> case is_unreachable_after(I) of false -> - share_1(Is, Dict, Lbls, [I|Seq], Acc); + share_1(Is, Dict, [I|Seq], Acc); true -> - share_1(Is, Dict, Lbls, [I], Acc) + share_1(Is, Dict, [I], Acc) end. -clean_non_sharable(Dict0, Lbls0) -> +clean_non_sharable(Dict) -> %% We are passing in or out of a 'catch' or 'try' block. Remove %% sequences that should not be shared over the boundaries of the %% block. Since the end of the sequence must match, the only @@ -203,17 +198,7 @@ clean_non_sharable(Dict0, Lbls0) -> %% the 'catch'/'try' block is a sequence that ends with an %% instruction that causes an exception. Any sequence that causes %% an exception must contain a line/1 instruction. - Dict1 = maps:to_list(Dict0), - Lbls1 = maps:to_list(Lbls0), - {Dict2,Lbls2} = foldl(fun({K, V}, {Dict,Lbls}) -> - case sharable_with_try(K) of - true -> - {[{K,V}|Dict],lists:keydelete(V, 2, Lbls)}; - false -> - {Dict,Lbls} - end - end, {[],Lbls1}, Dict1), - {maps:from_list(Dict2),maps:from_list(Lbls2)}. + maps:filter(fun(K, _V) -> sharable_with_try(K) end, Dict). sharable_with_try([{line,_}|_]) -> %% This sequence may cause an exception and may potentially diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index a13bdedaf9..47042c2393 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -1275,13 +1275,18 @@ let_subst_list([], [], _) -> {[],[],[]}. %%pattern(Pat, Sub) -> pattern(Pat, Sub, Sub). pattern(#c_var{}=Pat, Isub, Osub) -> - case sub_is_val(Pat, Isub) of + case sub_is_in_scope(Pat, Isub) of true -> + %% This variable either has a substitution or is used in + %% the variable list of an enclosing `let`. In either + %% case, it must be renamed to an unused name to avoid + %% name capture problems. V1 = make_var_name(), Pat1 = #c_var{name=V1}, {Pat1,sub_set_var(Pat, Pat1, sub_add_scope([V1], Osub))}; false -> - {Pat,sub_del_var(Pat, Osub)} + %% This variable has never been used. Add it to the scope. + {Pat,sub_add_scope([Pat#c_var.name], Osub)} end; pattern(#c_literal{}=Pat, _, Osub) -> {Pat,Osub}; pattern(#c_cons{anno=Anno,hd=H0,tl=T0}, Isub, Osub0) -> @@ -1460,8 +1465,8 @@ is_subst(_) -> false. %% sub_set_name(Name, Value, #sub{}) -> #sub{}. %% sub_del_var(Var, #sub{}) -> #sub{}. %% sub_subst_var(Var, Value, #sub{}) -> [{Name,Value}]. -%% sub_is_val(Var, #sub{}) -> boolean(). -%% sub_add_scope(#sub{}) -> #sub{} +%% sub_is_in_scope(Var, #sub{}) -> boolean(). +%% sub_add_scope([Var], #sub{}) -> #sub{} %% sub_subst_scope(#sub{}) -> #sub{} %% %% We use the variable name as key so as not have problems with @@ -1496,18 +1501,6 @@ sub_set_name(V, Val, #sub{v=S,s=Scope,t=Tdb0}=Sub) -> Tdb = copy_type(V, Val, Tdb1), Sub#sub{v=orddict:store(V, Val, S),s=cerl_sets:add_element(V, Scope),t=Tdb}. -sub_del_var(#c_var{name=V}, #sub{v=S,s=Scope,t=Tdb}=Sub) -> - %% Profiling shows that for programs with many record operations, - %% sub_del_var/2 is a bottleneck. Since the scope contains all - %% variables that are live, we know that V cannot be present in S - %% if it is not in the scope. - case cerl_sets:is_element(V, Scope) of - false -> - Sub#sub{s=cerl_sets:add_element(V, Scope)}; - true -> - Sub#sub{v=orddict:erase(V, S),t=kill_types(V, Tdb)} - end. - sub_subst_var(#c_var{name=V}, Val, #sub{v=S0}) -> %% Fold chained substitutions. [{V,Val}] ++ [ {K,Val} || {K,#c_var{name=V1}} <- S0, V1 =:= V]. @@ -1533,16 +1526,8 @@ sub_subst_scope_1([H|T], Key, Acc) -> sub_subst_scope_1(T, Key-1, [{Key,#c_var{name=H}}|Acc]); sub_subst_scope_1([], _, Acc) -> Acc. -sub_is_val(#c_var{name=V}, #sub{v=S,s=Scope}) -> - %% When the bottleneck in sub_del_var/2 was eliminated, this - %% became the new bottleneck. Since the scope contains all - %% live variables, a variable V can only be the target for - %% a substitution if it is in the scope. - cerl_sets:is_element(V, Scope) andalso v_is_value(V, S). - -v_is_value(Var, [{_,#c_var{name=Var}}|_]) -> true; -v_is_value(Var, [_|T]) -> v_is_value(Var, T); -v_is_value(_, []) -> false. +sub_is_in_scope(#c_var{name=V}, #sub{s=Scope}) -> + cerl_sets:is_element(V, Scope). %% warn_no_clause_match(CaseOrig, CaseOpt) -> ok %% Generate a warning if none of the user-specified clauses diff --git a/lib/compiler/src/sys_core_inline.erl b/lib/compiler/src/sys_core_inline.erl index 8c1f69d5de..eee3594922 100644 --- a/lib/compiler/src/sys_core_inline.erl +++ b/lib/compiler/src/sys_core_inline.erl @@ -143,7 +143,7 @@ inline_inline(#ifun{body=B,weight=Iw}=If, Is) -> case find_inl(F, A, Is) of #ifun{vars=Vs,body=B2,weight=W} when W < Iw -> #c_let{vars=Vs, - arg=core_lib:make_values(As), + arg=kill_id_anns(core_lib:make_values(As)), body=kill_id_anns(B2)}; _Other -> Call end; @@ -160,7 +160,7 @@ inline_func(#fstat{def={Name,F0}}=Fstat, Is) -> case find_inl(F, A, Is) of #ifun{vars=Vs,body=B} -> {#c_let{vars=Vs, - arg=core_lib:make_values(As), + arg=kill_id_anns(core_lib:make_values(As)), body=kill_id_anns(B)}, true}; %Have modified _Other -> {Call,Mod} diff --git a/lib/compiler/test/core_SUITE.erl b/lib/compiler/test/core_SUITE.erl index 0e07e8dd2e..d07cd3b8b7 100644 --- a/lib/compiler/test/core_SUITE.erl +++ b/lib/compiler/test/core_SUITE.erl @@ -29,7 +29,7 @@ bs_shadowed_size_var/1, cover_v3_kernel_1/1,cover_v3_kernel_2/1,cover_v3_kernel_3/1, cover_v3_kernel_4/1,cover_v3_kernel_5/1, - non_variable_apply/1]). + non_variable_apply/1,name_capture/1]). -include_lib("common_test/include/ct.hrl"). @@ -58,7 +58,7 @@ groups() -> bs_shadowed_size_var, cover_v3_kernel_1,cover_v3_kernel_2,cover_v3_kernel_3, cover_v3_kernel_4,cover_v3_kernel_5, - non_variable_apply + non_variable_apply,name_capture ]}]. @@ -93,6 +93,7 @@ end_per_group(_GroupName, Config) -> ?comp(cover_v3_kernel_4). ?comp(cover_v3_kernel_5). ?comp(non_variable_apply). +?comp(name_capture). try_it(Mod, Conf) -> Src = filename:join(proplists:get_value(data_dir, Conf), diff --git a/lib/compiler/test/core_SUITE_data/name_capture.core b/lib/compiler/test/core_SUITE_data/name_capture.core new file mode 100644 index 0000000000..0969f95b72 --- /dev/null +++ b/lib/compiler/test/core_SUITE_data/name_capture.core @@ -0,0 +1,110 @@ +module 'name_capture' ['module_info'/0, + 'module_info'/1, + 'name_capture'/0] + attributes ['compile' = + [{'inline',[{'badarg_exit',2}]}]] +'name_capture'/0 = + fun () -> + case <> of + <> when 'true' -> + let <_0> = + catch + apply 'first'/1 + ('badarg') + in case _0 of + <{'EXIT',{'badarg',_7}}> when 'true' -> + let <Seq> = + call 'lists':'seq' + (7, 17) + in case apply 'first'/1 + ({'ok',Seq}) of + <_8> + when call 'erlang':'=:=' + (_8, + Seq) -> + let <SomeOtherTerm> = + {'some','other','term'} + in let <_5> = + catch + apply 'first'/1 + (SomeOtherTerm) + in case _5 of + <{'EXIT',_9}> + when call 'erlang':'=:=' + (_9, + SomeOtherTerm) -> + 'ok' + <_6> when 'true' -> + primop 'match_fail' + ({'badmatch',_6}) + end + <_3> when 'true' -> + primop 'match_fail' + ({'badmatch',_3}) + end + <_1> when 'true' -> + primop 'match_fail' + ({'badmatch',_1}) + end + <> when 'true' -> + primop 'match_fail' + ({'function_clause'}) + end +'first'/1 = + fun (_0) -> + case _0 of + <Tab> when 'true' -> + let <_1> = + apply 'treq'/2 + (Tab, 'first') + %% The _1 variable in the `let` must be renamed + %% to avoid a name capture problem. + in let <_0,_1> = + <_1,[Tab|[]]> + in case <_0,_1> of + <'badarg',A> when 'true' -> + call 'erlang':'error' + ('badarg', A) + <{'ok',Reply},_X_A> when 'true' -> + Reply + <Reply,_X_A> when 'true' -> + call 'erlang':'exit' + (Reply) + <_3,_2> when 'true' -> + primop 'match_fail' + ({'function_clause',_3,_2}) + end + <_2> when 'true' -> + primop 'match_fail' + ({'function_clause',_2}) + end +'treq'/2 = + fun (_0,_1) -> + case <_0,_1> of + <Action,_4> when 'true' -> + Action + <_3,_2> when 'true' -> + primop 'match_fail' + ({'function_clause',_3,_2}) + end +'module_info'/0 = + fun () -> + case <> of + <> when 'true' -> + call 'erlang':'get_module_info' + ('name_capture') + <> when 'true' -> + primop 'match_fail' + ({'function_clause'}) + end +'module_info'/1 = + fun (_0) -> + case _0 of + <X> when 'true' -> + call 'erlang':'get_module_info' + ('name_capture', X) + <_1> when 'true' -> + primop 'match_fail' + ({'function_clause',_1}) + end +end diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk index a26cb09dff..ee75ee27fd 100644 --- a/lib/compiler/vsn.mk +++ b/lib/compiler/vsn.mk @@ -1 +1 @@ -COMPILER_VSN = 7.2 +COMPILER_VSN = 7.1.5 diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 6e113ef39e..e4eb2bc3b6 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -155,6 +155,14 @@ # define HAVE_EC #endif +// (test for == 1.1.1pre8) +#if OPENSSL_VERSION_NUMBER == (PACKED_OPENSSL_VERSION_PLAIN(1,1,1) - 7) \ + && !defined(HAS_LIBRESSL) \ + && defined(HAVE_EC) +// EXPERIMENTAL: +# define HAVE_EDDH +#endif + #if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION(0,9,8,'c') # define HAVE_AES_IGE #endif @@ -501,6 +509,9 @@ static ERL_NIF_TERM srp_host_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_ static ERL_NIF_TERM ec_key_generate(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM evp_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM evp_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); + static ERL_NIF_TERM rand_seed_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM aes_gcm_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); @@ -581,6 +592,10 @@ static ErlNifFunc nif_funcs[] = { {"rsa_generate_key_nif", 2, rsa_generate_key_nif}, {"dh_generate_key_nif", 4, dh_generate_key_nif}, {"dh_compute_key_nif", 3, dh_compute_key_nif}, + + {"evp_compute_key_nif", 3, evp_compute_key_nif}, + {"evp_generate_key_nif", 1, evp_generate_key_nif}, + {"privkey_to_pubkey_nif", 2, privkey_to_pubkey_nif}, {"srp_value_B_nif", 5, srp_value_B_nif}, {"srp_user_secret_nif", 7, srp_user_secret_nif}, @@ -668,6 +683,13 @@ static ERL_NIF_TERM atom_blowfish_ecb; static ERL_NIF_TERM atom_rsa; static ERL_NIF_TERM atom_dss; static ERL_NIF_TERM atom_ecdsa; + +#ifdef HAVE_EDDH +static ERL_NIF_TERM atom_eddh; +static ERL_NIF_TERM atom_x25519; +static ERL_NIF_TERM atom_x448; +#endif + static ERL_NIF_TERM atom_rsa_mgf1_md; static ERL_NIF_TERM atom_rsa_oaep_label; static ERL_NIF_TERM atom_rsa_oaep_md; @@ -1075,6 +1097,11 @@ static int initialize(ErlNifEnv* env, ERL_NIF_TERM load_info) atom_rsa = enif_make_atom(env,"rsa"); atom_dss = enif_make_atom(env,"dss"); atom_ecdsa = enif_make_atom(env,"ecdsa"); +#ifdef HAVE_EDDH + atom_eddh = enif_make_atom(env,"eddh"); + atom_x25519 = enif_make_atom(env,"x25519"); + atom_x448 = enif_make_atom(env,"x448"); +#endif atom_rsa_mgf1_md = enif_make_atom(env,"rsa_mgf1_md"); atom_rsa_oaep_label = enif_make_atom(env,"rsa_oaep_label"); atom_rsa_oaep_md = enif_make_atom(env,"rsa_oaep_md"); @@ -1120,6 +1147,7 @@ static int initialize(ErlNifEnv* env, ERL_NIF_TERM load_info) atom_password = enif_make_atom(env,"password"); #endif + #ifdef HAVE_DYNAMIC_CRYPTO_LIB { void* handle; @@ -1211,11 +1239,13 @@ static void unload(ErlNifEnv* env, void* priv_data) static int algo_hash_cnt, algo_hash_fips_cnt; static ERL_NIF_TERM algo_hash[8]; /* increase when extending the list */ static int algo_pubkey_cnt, algo_pubkey_fips_cnt; -static ERL_NIF_TERM algo_pubkey[7]; /* increase when extending the list */ +static ERL_NIF_TERM algo_pubkey[11]; /* increase when extending the list */ static int algo_cipher_cnt, algo_cipher_fips_cnt; static ERL_NIF_TERM algo_cipher[24]; /* increase when extending the list */ static int algo_mac_cnt, algo_mac_fips_cnt; static ERL_NIF_TERM algo_mac[2]; /* increase when extending the list */ +static int algo_curve_cnt, algo_curve_fips_cnt; +static ERL_NIF_TERM algo_curve[87]; /* increase when extending the list */ static void init_algorithms_types(ErlNifEnv* env) { @@ -1253,6 +1283,9 @@ static void init_algorithms_types(ErlNifEnv* env) #endif // Non-validated algorithms follow algo_pubkey_fips_cnt = algo_pubkey_cnt; +#ifdef HAVE_EDDH + algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env, "eddh"); +#endif algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env, "srp"); // Validated algorithms first @@ -1308,10 +1341,23 @@ static void init_algorithms_types(ErlNifEnv* env) // Non-validated algorithms follow algo_mac_fips_cnt = algo_mac_cnt; + + // Validated algorithms first + algo_curve_cnt = 0; + // Non-validated algorithms follow + algo_curve_fips_cnt = algo_curve_cnt; + //-- +#ifdef HAVE_EDDH + algo_curve[algo_curve_cnt++] = enif_make_atom(env,"x25519"); + algo_curve[algo_curve_cnt++] = enif_make_atom(env,"x448"); +#endif + + // Check that the max number of algos is updated ASSERT(algo_hash_cnt <= sizeof(algo_hash)/sizeof(ERL_NIF_TERM)); ASSERT(algo_pubkey_cnt <= sizeof(algo_pubkey)/sizeof(ERL_NIF_TERM)); ASSERT(algo_cipher_cnt <= sizeof(algo_cipher)/sizeof(ERL_NIF_TERM)); ASSERT(algo_mac_cnt <= sizeof(algo_mac)/sizeof(ERL_NIF_TERM)); + ASSERT(algo_curve_cnt <= sizeof(algo_curve)/sizeof(ERL_NIF_TERM)); } static ERL_NIF_TERM algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) @@ -1322,17 +1368,20 @@ static ERL_NIF_TERM algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv int pubkey_cnt = fips_mode ? algo_pubkey_fips_cnt : algo_pubkey_cnt; int cipher_cnt = fips_mode ? algo_cipher_fips_cnt : algo_cipher_cnt; int mac_cnt = fips_mode ? algo_mac_fips_cnt : algo_mac_cnt; + int curve_cnt = fips_mode ? algo_curve_fips_cnt : algo_curve_cnt; #else int hash_cnt = algo_hash_cnt; int pubkey_cnt = algo_pubkey_cnt; int cipher_cnt = algo_cipher_cnt; int mac_cnt = algo_mac_cnt; + int curve_cnt = algo_curve_cnt; #endif - return enif_make_tuple4(env, - enif_make_list_from_array(env, algo_hash, hash_cnt), + return enif_make_tuple5(env, + enif_make_list_from_array(env, algo_hash, hash_cnt), enif_make_list_from_array(env, algo_pubkey, pubkey_cnt), enif_make_list_from_array(env, algo_cipher, cipher_cnt), - enif_make_list_from_array(env, algo_mac, mac_cnt) + enif_make_list_from_array(env, algo_mac, mac_cnt), + enif_make_list_from_array(env, algo_curve, curve_cnt) ); } @@ -1753,6 +1802,7 @@ static ERL_NIF_TERM hash_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM } #endif /* OPENSSL_VERSION_NUMBER < 1.0 */ + static ERL_NIF_TERM hmac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Type, Key, Data) or (Type, Key, Data, MacSize) */ struct digest_type_t *digp = NULL; @@ -3071,10 +3121,11 @@ static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_ if ((dhkey = EVP_PKEY_new()) && (params = EVP_PKEY_new()) && EVP_PKEY_set1_DH(params, dh_params) /* set the key referenced by params to dh_params. - dh_params (and params) must be freed by us*/ + dh_params (and params) must be freed */ && (ctx = EVP_PKEY_CTX_new(params, NULL)) && EVP_PKEY_keygen_init(ctx) - && EVP_PKEY_keygen(ctx, &dhkey) + && EVP_PKEY_keygen(ctx, &dhkey) /* "performs a key generation operation, the + generated key is written to ppkey." (=last arg) */ && (dh_params = EVP_PKEY_get1_DH(dhkey)) /* return the referenced key. dh_params and dhkey must be freed */ ) { #else @@ -3108,8 +3159,8 @@ static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_ DH_free(dh_params); #ifdef HAS_EVP_PKEY_CTX if (ctx) EVP_PKEY_CTX_free(ctx); - /* if (dhkey) EVP_PKEY_free(dhkey); */ - /* if (params) EVP_PKEY_free(params); */ + if (dhkey) EVP_PKEY_free(dhkey); + if (params) EVP_PKEY_free(params); #endif return ret; } @@ -3207,7 +3258,7 @@ static ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_T if (dh_pub) DH_free(dh_pub); #ifdef HAS_EVP_PKEY_CTX if (ctx) EVP_PKEY_CTX_free(ctx); - /* if (my_priv_key) EVP_PKEY_free(my_priv_key); */ + if (my_priv_key) EVP_PKEY_free(my_priv_key); /* if (peer_pub_key) EVP_PKEY_free(peer_pub_key); */ #endif return ret; @@ -3817,6 +3868,123 @@ out_err: #endif } +// EXPERIMENTAL! +static ERL_NIF_TERM evp_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) + /* (Curve, PeerBin, MyBin) */ +{ +#ifdef HAVE_EDDH + int type; + EVP_PKEY_CTX *ctx; + ErlNifBinary peer_bin, my_bin, key_bin; + EVP_PKEY *peer_key, *my_key; + size_t max_size; + + if (argv[0] == atom_x25519) type = EVP_PKEY_X25519; + else if (argv[0] == atom_x448) type = EVP_PKEY_X448; + else return enif_make_badarg(env); + + if (!enif_inspect_binary(env, argv[1], &peer_bin) || + !enif_inspect_binary(env, argv[2], &my_bin)) { + return enif_make_badarg(env); + } + + if (!(my_key = EVP_PKEY_new_raw_private_key(type, NULL, my_bin.data, my_bin.size)) || + !(ctx = EVP_PKEY_CTX_new(my_key, NULL))) { + return enif_make_badarg(env); + } + + if (!EVP_PKEY_derive_init(ctx)) { + return enif_make_badarg(env); + } + + if (!(peer_key = EVP_PKEY_new_raw_public_key(type, NULL, peer_bin.data, peer_bin.size)) || + !EVP_PKEY_derive_set_peer(ctx, peer_key)) { + return enif_make_badarg(env); + } + + if (!EVP_PKEY_derive(ctx, NULL, &max_size)) { + return enif_make_badarg(env); + } + + if (!enif_alloc_binary(max_size, &key_bin) || + !EVP_PKEY_derive(ctx, key_bin.data, &key_bin.size)) { + return enif_make_badarg(env); + } + + if (key_bin.size < max_size) { + size_t actual_size = key_bin.size; + if (!enif_realloc_binary(&key_bin, actual_size)) { + return enif_make_badarg(env); + } + } + + return enif_make_binary(env, &key_bin); + +/* Importing the other side's public key from raw binary format can be done with the EVP_PKEY_new_raw_public_key() function. Man page here: */ +/* https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_new_raw_public_key.html */ + + +/* You need two EVP_PKEY objects. One containing your private/public key pair (i.e. the one you generated in the EVP_PKEY_keygen() call in your question), and one containing the public key of the peer (e.g. created using EVP_PKEY_new_raw_public_key()). To generate the X25519 shared secret you then call EVP_PKEY_derive(). See the example on the man page: openssl.org/docs/man1.1.1/man3/EVP_PKEY_derive.html – Matt Caswell May 15 at 20:39 */ + +#else + return atom_notsup; +#endif +} + +// EXPERIMENTAL! +static ERL_NIF_TERM evp_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +/* (Curve) */ +{ +#ifdef HAVE_EDDH + int type; + EVP_PKEY_CTX *ctx; + EVP_PKEY *pkey = NULL; + ERL_NIF_TERM ret_pub, ret_prv; + size_t key_len; + + if (argv[0] == atom_x25519) type = EVP_PKEY_X25519; + else if (argv[0] == atom_x448) type = EVP_PKEY_X448; + else return enif_make_badarg(env); + + if (!(ctx = EVP_PKEY_CTX_new_id(type, NULL))) return enif_make_badarg(env); + + if (!EVP_PKEY_keygen_init(ctx)) return enif_make_atom(env,"EVP_PKEY_keygen_init failed"); + if (!EVP_PKEY_keygen(ctx, &pkey)) return enif_make_atom(env,"EVP_PKEY_keygen failed"); + + /* + int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, size_t *len) + int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, size_t *len) + + +EVP_PKEY_get_raw_private_key() fills the buffer provided by B<priv> with raw + +private key data. The number of bytes written is populated in B<*len>. If the + +buffer B<priv> is NULL then B<*len> is populated with the number of bytes + +required in the buffer. The calling application is responsible for ensuring that + +the buffer is large enough to receive the private key data. This function only + +works for algorithms that support raw private keys. Currently this is: + +B<EVP_PKEY_HMAC>, B<EVP_PKEY_POLY1305>, B<EVP_PKEY_SIPHASH>, B<EVP_PKEY_X25519>, + +B<EVP_PKEY_ED25519>, B<EVP_PKEY_X448> or B<EVP_PKEY_ED448>. + */ + + if (!EVP_PKEY_get_raw_public_key(pkey, NULL, &key_len)) + return enif_make_atom(env,"EVP_PKEY_get_raw_public_key 1 failed"); + if (!EVP_PKEY_get_raw_public_key(pkey, + enif_make_new_binary(env, key_len, &ret_pub), + &key_len)) + return enif_make_atom(env,"EVP_PKEY_get_raw_public_key 2 failed"); + + if (!EVP_PKEY_get_raw_private_key(pkey, NULL, &key_len)) + return enif_make_atom(env,"EVP_PKEY_get_raw_private_key 1 failed"); + if (!EVP_PKEY_get_raw_private_key(pkey, + enif_make_new_binary(env, key_len, &ret_prv), + &key_len)) + return enif_make_atom(env,"EVP_PKEY_get_raw_private_key 2 failed"); + + return enif_make_tuple2(env, ret_pub, ret_prv); +#else + return atom_notsup; +#endif +} + /*================================================================*/ #define PKEY_BADARG -1 #define PKEY_NOTSUP 0 diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index a6a1287a85..66619c9e11 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -31,53 +31,6 @@ </header> <p>This document describes the changes made to the Crypto application.</p> -<section><title>Crypto 4.3</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Removed two undocumented and erroneous functions - (<c>crypto:dh_generate_parameters/2</c> and - <c>crypto:dh_check/1</c>).</p> - <p> - Own Id: OTP-14956 Aux Id: ERL-579 </p> - </item> - <item> - <p> - Fixed bug causing VM crash if doing runtime upgrade of a - crypto module built against OpenSSL older than 0.9.8h. - Bug exists since OTP-20.2.</p> - <p> - Own Id: OTP-15088</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - A new <c>rand</c> plugin algorithm has been implemented - in <c>crypto</c>, that is: <c>crypto_cache</c>. It uses - strong random bytes as randomness source and caches them - to get good speed. See <c>crypto:rand_seed_alg/1</c>.</p> - <p> - Own Id: OTP-13370 Aux Id: PR-1573 </p> - </item> - <item> - <p> - Diffie-Hellman key functions are re-written with the - EVP_PKEY api.</p> - <p> - Own Id: OTP-14864</p> - </item> - </list> - </section> - -</section> - <section><title>Crypto 4.2.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 46775989ae..85b484011c 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -107,12 +107,18 @@ stop() -> application:stop(crypto). supports()-> - {Hashs, PubKeys, Ciphers, Macs} = algorithms(), + {Hashs, PubKeys, Ciphers, Macs, Curves} = algorithms(), [{hashs, Hashs}, {ciphers, Ciphers}, {public_keys, PubKeys}, {macs, Macs} + | case Curves of + [] -> []; + _ -> [{curves, Curves}] % Only show this experimental feature + % if OpenSSL 1.1.1 beta4 or higher (where + % eddsa and eddh is enabled) + end ]. info_lib() -> ?nif_stub. @@ -586,9 +592,18 @@ generate_key(rsa, {ModulusSize, PublicExponent}, undefined) -> {lists:sublist(Private, 2), Private} end; + +generate_key(ecdh, Curve, undefined) when Curve == x448 ; + Curve == x25519 -> + evp_generate_key_nif(Curve); generate_key(ecdh, Curve, PrivKey) -> ec_key_generate(nif_curve_params(Curve), ensure_int_as_bin(PrivKey)). + +evp_generate_key_nif(_Curve) -> ?nif_stub. + + + compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) -> case dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey), ensure_int_as_bin(MyPrivateKey), @@ -628,11 +643,18 @@ compute_key(srp, UserPublic, {HostPublic, HostPrivate}, srp_host_secret_nif(Verifier, ensure_int_as_bin(HostPrivate), Scrambler, UserPubBin, Prime)); +compute_key(ecdh, Others, My, Curve) when Curve == x448 ; + Curve == x25519 -> + evp_compute_key_nif(Curve, ensure_int_as_bin(Others), ensure_int_as_bin(My)); + compute_key(ecdh, Others, My, Curve) -> ecdh_compute_key_nif(ensure_int_as_bin(Others), nif_curve_params(Curve), ensure_int_as_bin(My)). + +evp_compute_key_nif(_Curve, _OthersBin, _MyBin) -> ?nif_stub. + %%====================================================================== %% Engine functions %%====================================================================== @@ -1144,7 +1166,11 @@ nif_curve_params({PrimeField, Curve, BasePoint, Order, CoFactor}) -> {term_to_nif_prime(PrimeField), term_to_nif_curve(Curve), ensure_int_as_bin(BasePoint), ensure_int_as_bin(Order), ensure_int_as_bin(CoFactor)}; nif_curve_params(Curve) when is_atom(Curve) -> %% named curve - crypto_ec_curves:curve(Curve). + case Curve of + x448 -> {evp,Curve}; + x25519 -> {evp,Curve}; + _ -> crypto_ec_curves:curve(Curve) + end. %% MISC -------------------------------------------------------------------- diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index cc34c20ac6..778aff9d13 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 4.3 +CRYPTO_VSN = 4.2.2 diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml index c77607f01c..e71746e30d 100644 --- a/lib/debugger/doc/src/notes.xml +++ b/lib/debugger/doc/src/notes.xml @@ -33,21 +33,6 @@ <p>This document describes the changes made to the Debugger application.</p> -<section><title>Debugger 4.2.5</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> Fix a bug where calling a fun inside a binary would - crash the Debugger. </p> - <p> - Own Id: OTP-14957 Aux Id: PR-1741 </p> - </item> - </list> - </section> - -</section> - <section><title>Debugger 4.2.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/debugger/src/dbg_wx_trace.erl b/lib/debugger/src/dbg_wx_trace.erl index 505d53005f..25f32ca7e7 100644 --- a/lib/debugger/src/dbg_wx_trace.erl +++ b/lib/debugger/src/dbg_wx_trace.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2017. All Rights Reserved. +%% Copyright Ericsson AB 2008-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -518,8 +518,8 @@ gui_cmd({user_command, Cmd}, State) -> gui_cmd({edit, {Var, Value}}, State) -> Window = dbg_wx_trace_win:get_window(State#state.win), Val = case State#state.strings of - [] -> dbg_wx_win:to_string("~999999lp",[Value]); - [str_on] -> dbg_wx_win:to_string("~999999tp",[Value]) + [] -> dbg_wx_win:to_string("~0lp",[Value]); + [str_on] -> dbg_wx_win:to_string("~0tp",[Value]) end, case dbg_wx_win:entry(Window, "Edit variable", Var, {term, Val}) of cancel -> diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk index d62e5915a7..57da7e5618 100644 --- a/lib/debugger/vsn.mk +++ b/lib/debugger/vsn.mk @@ -1 +1 @@ -DEBUGGER_VSN = 4.2.5 +DEBUGGER_VSN = 4.2.4 diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml index 3330ca05e0..8d11252bff 100644 --- a/lib/dialyzer/doc/src/notes.xml +++ b/lib/dialyzer/doc/src/notes.xml @@ -32,53 +32,6 @@ <p>This document describes the changes made to the Dialyzer application.</p> -<section><title>Dialyzer 3.3</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>Changed the default behaviour of <c>.erlang</c> - loading: <c>.erlang</c> is no longer loaded from the - current directory. <c>c:erlangrc(PathList)</c> can be - used to search and load an <c>.erlang</c> file from user - specified directories.</p> <p><c>escript</c>, - <c>erlc</c>, <c>dialyzer</c> and <c>typer</c> no longer - load an <c>.erlang</c> at all.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14439</p> - </item> - <item> - <p> Dialyzer can no longer read BEAM files created with - OTP 19 or earlier. </p> - <p> - Own Id: OTP-14493 Aux Id: PR-1434 </p> - </item> - <item> - <p> Speed up the computation of MD5 sums. </p> - <p> - Own Id: OTP-14937 Aux Id: PR-1719 </p> - </item> - <item> - <p> Fix a situation where Dialyzer unnecessarily - discarded contract information, resulting in missed - warnings. </p> - <p> - Own Id: OTP-14970 Aux Id: PR-1722 </p> - </item> - <item> - <p> Do not emit warnings for fun expressions residing in - code that cannot be run. This is consistent with how - Dialyzer treats other code that cannot be run. </p> - <p> - Own Id: OTP-15079 Aux Id: ERL-593 </p> - </item> - </list> - </section> - -</section> - <section><title>Dialyzer 3.2.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl index 1538174d4a..185c8c9ae6 100644 --- a/lib/dialyzer/src/dialyzer.erl +++ b/lib/dialyzer/src/dialyzer.erl @@ -409,6 +409,10 @@ message_to_string({extra_range, [M, F, A, ExtraRanges, SigRange]}) -> io_lib:format("The specification for ~w:~tw/~w states that the function" " might also return ~ts but the inferred return is ~ts\n", [M, F, A, ExtraRanges, SigRange]); +message_to_string({missing_range, [M, F, A, ExtraRanges, ContrRange]}) -> + io_lib:format("The success typing for ~w:~tw/~w implies that the function" + " might also return ~ts but the specification return is ~ts\n", + [M, F, A, ExtraRanges, ContrRange]); message_to_string({overlapping_contract, [M, F, A]}) -> io_lib:format("Overloaded contract for ~w:~tw/~w has overlapping domains;" " such contracts are currently unsupported and are simply ignored\n", diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl index 0df15e55f9..af7f4385ad 100644 --- a/lib/dialyzer/src/dialyzer_contracts.erl +++ b/lib/dialyzer/src/dialyzer_contracts.erl @@ -197,9 +197,11 @@ check_contracts(Contracts, Callgraph, FunTypes, ModOpaques) -> false -> [{MFA, Contract}|NewContracts] end; - {error, {extra_range, _, _}} -> - %% do not treat extra range as an error in this check - %% since that prevents discovering other actual errors + {range_warnings, _} -> + %% do not treat extra range, either in contract or + %% in success typing, as an error in this check + %% since that prevents discovering other actual + %% errors [{MFA, Contract}|NewContracts]; {error, _Error} -> NewContracts end; @@ -210,14 +212,26 @@ check_contracts(Contracts, Callgraph, FunTypes, ModOpaques) -> end, orddict:from_list(lists:foldl(FoldFun, [], orddict:to_list(FunTypes))). +-type check_contract_return() :: + 'ok' + | {'error', + 'invalid_contract' + | {'opaque_mismatch', erl_types:erl_type()} + | {'overlapping_contract', [module() | atom() | byte()]} + | string()} + | {'range_warnings', + [{'error', {'extra_range' | 'missing_range', + erl_types:erl_type(), + erl_types:erl_type()}}]}. + %% Checks all components of a contract --spec check_contract(#contract{}, erl_types:erl_type()) -> 'ok' | {'error', term()}. +-spec check_contract(#contract{}, erl_types:erl_type()) -> check_contract_return(). check_contract(Contract, SuccType) -> check_contract(Contract, SuccType, 'universe'). -spec check_contract(#contract{}, erl_types:erl_type(), erl_types:opaques()) -> - 'ok' | {'error', term()}. + check_contract_return(). check_contract(#contract{contracts = Contracts}, SuccType, Opaques) -> try @@ -290,15 +304,23 @@ check_contract_inf_list([], _SuccType, _Opaques, OM) -> check_extraneous([], _SuccType) -> ok; check_extraneous([C|Cs], SuccType) -> case check_extraneous_1(C, SuccType) of - ok -> check_extraneous(Cs, SuccType); - Error -> Error + {error, invalid_contract} = Error -> + Error; + {error, {extra_range, _, _}} = Error -> + {range_warnings, [Error | check_missing(C, SuccType)]}; + ok -> + case check_missing(C, SuccType) of + [] -> check_extraneous(Cs, SuccType); + ErrorL -> {range_warnings, ErrorL} + end end. check_extraneous_1(Contract, SuccType) -> CRng = erl_types:t_fun_range(Contract), CRngs = erl_types:t_elements(CRng), STRng = erl_types:t_fun_range(SuccType), - ?debug("CR = ~tp\nSR = ~tp\n", [CRngs, STRng]), + ?debug("\nCR = ~ts\nSR = ~ts\n", [erl_types:t_to_string(CRng), + erl_types:t_to_string(STRng)]), case [CR || CR <- CRngs, erl_types:t_is_none(erl_types:t_inf(CR, STRng))] of [] -> @@ -341,6 +363,18 @@ map_part(Type) -> is_empty_map(Type) -> erl_types:t_is_equal(Type, erl_types:t_from_term(#{})). +check_missing(Contract, SuccType) -> + CRng = erl_types:t_fun_range(Contract), + STRng = erl_types:t_fun_range(SuccType), + STRngs = erl_types:t_elements(STRng), + ?debug("\nCR = ~ts\nSR = ~ts\n", [erl_types:t_to_string(CRng), + erl_types:t_to_string(STRng)]), + case [STR || STR <- STRngs, + erl_types:t_is_none(erl_types:t_inf(STR, CRng))] of + [] -> []; + STRs -> [{error, {missing_range, erl_types:t_sup(STRs), CRng}}] + end. + %% This is the heart of the "range function" -spec process_contracts([contract_pair()], [erl_types:erl_type()]) -> erl_types:erl_type(). @@ -712,22 +746,30 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract, _Xtra}}|Left], [W|Acc]; {error, {overlapping_contract, []}} -> [overlapping_contract_warning(MFA, WarningInfo)|Acc]; - {error, {extra_range, ExtraRanges, STRange}} -> - Warn = - case t_from_forms_without_remote(Contract#contract.forms, - MFA, RecDict) of - {ok, NoRemoteType} -> - CRet = erl_types:t_fun_range(NoRemoteType), - erl_types:t_is_subtype(ExtraRanges, CRet); - unsupported -> - true - end, - case Warn of - true -> - [extra_range_warning(MFA, WarningInfo, ExtraRanges, STRange)|Acc]; - false -> - Acc - end; + {range_warnings, Errors} -> + Fun = + fun({error, {extra_range, ExtraRanges, STRange}}, Acc0) -> + Warn = + case t_from_forms_without_remote(Contract#contract.forms, + MFA, RecDict) of + {ok, NoRemoteType} -> + CRet = erl_types:t_fun_range(NoRemoteType), + erl_types:t_is_subtype(ExtraRanges, CRet); + unsupported -> + true + end, + case Warn of + true -> + [extra_range_warning(MFA, WarningInfo, + ExtraRanges, STRange)|Acc0]; + false -> + Acc0 + end; + ({error, {missing_range, ExtraRanges, CRange}}, Acc0) -> + [missing_range_warning(MFA, WarningInfo, + ExtraRanges, CRange)|Acc0] + end, + lists:foldl(Fun, Acc, Errors); {error, Msg} -> [{?WARN_CONTRACT_SYNTAX, WarningInfo, Msg}|Acc]; ok -> @@ -745,6 +787,9 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract, _Xtra}}|Left], {error, _} -> [invalid_contract_warning(MFA, WarningInfo, BifSig, RecDict) |Acc]; + {range_warnings, _} -> + picky_contract_check(CSig, BifSig, MFA, WarningInfo, + Contract, RecDict, Acc); ok -> picky_contract_check(CSig, BifSig, MFA, WarningInfo, Contract, RecDict, Acc) @@ -778,6 +823,12 @@ extra_range_warning({M, F, A}, WarningInfo, ExtraRanges, STRange) -> {?WARN_CONTRACT_SUPERTYPE, WarningInfo, {extra_range, [M, F, A, ERangesStr, STRangeStr]}}. +missing_range_warning({M, F, A}, WarningInfo, ExtraRanges, CRange) -> + ERangesStr = erl_types:t_to_string(ExtraRanges), + CRangeStr = erl_types:t_to_string(CRange), + {?WARN_CONTRACT_SUBTYPE, WarningInfo, + {missing_range, [M, F, A, ERangesStr, CRangeStr]}}. + picky_contract_check(CSig0, Sig0, MFA, WarningInfo, Contract, RecDict, Acc) -> CSig = erl_types:t_abstract_records(CSig0, RecDict), Sig = erl_types:t_abstract_records(Sig0, RecDict), diff --git a/lib/dialyzer/src/typer.erl b/lib/dialyzer/src/typer.erl index 9d3d9ce438..4b99f5f72e 100644 --- a/lib/dialyzer/src/typer.erl +++ b/lib/dialyzer/src/typer.erl @@ -401,7 +401,7 @@ get_type({{M, F, A} = MFA, Range, Arg}, CodeServer, Records) -> Sig = erl_types:t_fun(Arg, Range), case dialyzer_contracts:check_contract(Contract, Sig) of ok -> {{F, A}, {contract, Contract}}; - {error, {extra_range, _, _}} -> + {range_warnings, _} -> {{F, A}, {contract, Contract}}; {error, {overlapping_contract, []}} -> {{F, A}, {contract, Contract}}; diff --git a/lib/dialyzer/test/overspecs_SUITE_data/dialyzer_options b/lib/dialyzer/test/overspecs_SUITE_data/dialyzer_options new file mode 100644 index 0000000000..ff4517e59d --- /dev/null +++ b/lib/dialyzer/test/overspecs_SUITE_data/dialyzer_options @@ -0,0 +1 @@ +{dialyzer_options, [{warnings, [overspecs]}]}. diff --git a/lib/dialyzer/test/overspecs_SUITE_data/results/iodata b/lib/dialyzer/test/overspecs_SUITE_data/results/iodata new file mode 100644 index 0000000000..d9c70330ec --- /dev/null +++ b/lib/dialyzer/test/overspecs_SUITE_data/results/iodata @@ -0,0 +1,2 @@ + +iodata.erl:7: The success typing for iodata:encode/2 implies that the function might also return integer() but the specification return is binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) diff --git a/lib/dialyzer/test/overspecs_SUITE_data/results/iolist b/lib/dialyzer/test/overspecs_SUITE_data/results/iolist new file mode 100644 index 0000000000..ca556f017c --- /dev/null +++ b/lib/dialyzer/test/overspecs_SUITE_data/results/iolist @@ -0,0 +1,2 @@ + +iolist.erl:7: The success typing for iolist:encode/2 implies that the function might also return integer() but the specification return is maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) diff --git a/lib/dialyzer/test/overspecs_SUITE_data/src/iodata.erl b/lib/dialyzer/test/overspecs_SUITE_data/src/iodata.erl new file mode 100644 index 0000000000..caa44f6c91 --- /dev/null +++ b/lib/dialyzer/test/overspecs_SUITE_data/src/iodata.erl @@ -0,0 +1,41 @@ +-module(iodata). + +%% A small part of beam_asm. + +-export([encode/2]). + +-spec encode(non_neg_integer(), integer()) -> iodata(). % extra range binary() + +encode(Tag, N) when Tag >= 0, N < 0 -> + encode1(Tag, negative_to_bytes(N)); +encode(Tag, N) when Tag >= 0, N < 16 -> + (N bsl 4) bor Tag; % not in the specification +encode(Tag, N) when Tag >= 0, N < 16#800 -> + [((N bsr 3) band 2#11100000) bor Tag bor 2#00001000, N band 16#ff]; +encode(Tag, N) when Tag >= 0 -> + encode1(Tag, to_bytes(N)). + +encode1(Tag, Bytes) -> + case iolist_size(Bytes) of + Num when 2 =< Num, Num =< 8 -> + [((Num-2) bsl 5) bor 2#00011000 bor Tag| Bytes]; + Num when 8 < Num -> + [2#11111000 bor Tag, encode(0, Num-9)| Bytes] + end. + +to_bytes(N) -> + Bin = binary:encode_unsigned(N), + case Bin of + <<0:1,_/bits>> -> Bin; + <<1:1,_/bits>> -> [0,Bin] + end. + +negative_to_bytes(N) when N >= -16#8000 -> + <<N:16>>; +negative_to_bytes(N) -> + Bytes = byte_size(binary:encode_unsigned(-N)), + Bin = <<N:Bytes/unit:8>>, + case Bin of + <<0:1,_/bits>> -> [16#ff,Bin]; + <<1:1,_/bits>> -> Bin + end. diff --git a/lib/dialyzer/test/overspecs_SUITE_data/src/iolist.erl b/lib/dialyzer/test/overspecs_SUITE_data/src/iolist.erl new file mode 100644 index 0000000000..7cceeda24e --- /dev/null +++ b/lib/dialyzer/test/overspecs_SUITE_data/src/iolist.erl @@ -0,0 +1,41 @@ +-module(iolist). + +%% A small part of beam_asm. + +-export([encode/2]). + +-spec encode(non_neg_integer(), integer()) -> iolist(). + +encode(Tag, N) when Tag >= 0, N < 0 -> + encode1(Tag, negative_to_bytes(N)); +encode(Tag, N) when Tag >= 0, N < 16 -> + (N bsl 4) bor Tag; % not in the specification +encode(Tag, N) when Tag >= 0, N < 16#800 -> + [((N bsr 3) band 2#11100000) bor Tag bor 2#00001000, N band 16#ff]; +encode(Tag, N) when Tag >= 0 -> + encode1(Tag, to_bytes(N)). + +encode1(Tag, Bytes) -> + case iolist_size(Bytes) of + Num when 2 =< Num, Num =< 8 -> + [((Num-2) bsl 5) bor 2#00011000 bor Tag| Bytes]; + Num when 8 < Num -> + [2#11111000 bor Tag, encode(0, Num-9)| Bytes] + end. + +to_bytes(N) -> + Bin = binary:encode_unsigned(N), + case Bin of + <<0:1,_/bits>> -> Bin; + <<1:1,_/bits>> -> [0,Bin] + end. + +negative_to_bytes(N) when N >= -16#8000 -> + <<N:16>>; +negative_to_bytes(N) -> + Bytes = byte_size(binary:encode_unsigned(-N)), + Bin = <<N:Bytes/unit:8>>, + case Bin of + <<0:1,_/bits>> -> [16#ff,Bin]; + <<1:1,_/bits>> -> Bin + end. diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl index ce144e061f..52db2d9096 100644 --- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl +++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl @@ -285,7 +285,7 @@ eval(Info,"GET",CGIBody,Modules) -> "~n Modules: ~p",[Modules]), case auth(CGIBody,Modules) of true -> - case eval_str(string:concat(CGIBody,". ")) of + case erl_eval:eval_str(string:concat(CGIBody,". ")) of {error,Reason} -> ?vlog("eval -> error:" "~n Reason: ~p",[Reason]), @@ -318,48 +318,6 @@ auth(CGIBody,Modules) -> false end. -%% eval_str(InStr) -> {ok, OutStr} | {error, ErrStr'} -%% InStr must represent a body -%% Note: If InStr is a binary it has to be a Latin-1 string. -%% If you have a UTF-8 encoded binary you have to call -%% unicode:characters_to_list/1 before the call to eval_str(). - --define(result(F,D), lists:flatten(io_lib:format(F, D))). - --spec eval_str(string() | unicode:latin1_binary()) -> - {'ok', string()} | {'error', string()}. - -eval_str(Str) when is_list(Str) -> - case erl_scan:tokens([], Str, 0) of - {more, _} -> - {error, "Incomplete form (missing .<cr>)??"}; - {done, {ok, Toks, _}, Rest} -> - case all_white(Rest) of - true -> - case erl_parse:parse_exprs(Toks) of - {ok, Exprs} -> - case catch erl_eval:exprs(Exprs, erl_eval:new_bindings()) of - {value, Val, _} -> - {ok, Val}; - Other -> - {error, ?result("*** eval: ~p", [Other])} - end; - {error, {_Line, Mod, Args}} -> - Msg = ?result("*** ~ts",[Mod:format_error(Args)]), - {error, Msg} - end; - false -> - {error, ?result("Non-white space found after " - "end-of-form :~ts", [Rest])} - end - end. - -all_white([$\s|T]) -> all_white(T); -all_white([$\n|T]) -> all_white(T); -all_white([$\t|T]) -> all_white(T); -all_white([]) -> true; -all_white(_) -> false. - %%---------------------------------------------------------------------- %%Creates the environment list that will be the first arg to the %%Functions that is called through the ErlScript Schema diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/dialyzer_options b/lib/dialyzer/test/specdiffs_SUITE_data/dialyzer_options new file mode 100644 index 0000000000..56b36f2ed4 --- /dev/null +++ b/lib/dialyzer/test/specdiffs_SUITE_data/dialyzer_options @@ -0,0 +1 @@ +{dialyzer_options, [{warnings, [specdiffs]}]}. diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/results/iodata b/lib/dialyzer/test/specdiffs_SUITE_data/results/iodata new file mode 100644 index 0000000000..3fb12fe000 --- /dev/null +++ b/lib/dialyzer/test/specdiffs_SUITE_data/results/iodata @@ -0,0 +1,3 @@ + +iodata.erl:7: The specification for iodata:encode/2 states that the function might also return binary() but the inferred return is nonempty_maybe_improper_list(<<_:8,_:_*8>> | nonempty_maybe_improper_list(<<_:8,_:_*8>> | nonempty_maybe_improper_list(any(),<<_:8,_:_*8>> | []) | byte(),<<_:8,_:_*8>> | []) | integer(),<<_:8,_:_*8>> | []) | integer() +iodata.erl:7: The success typing for iodata:encode/2 implies that the function might also return integer() but the specification return is binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/results/iolist b/lib/dialyzer/test/specdiffs_SUITE_data/results/iolist new file mode 100644 index 0000000000..ca556f017c --- /dev/null +++ b/lib/dialyzer/test/specdiffs_SUITE_data/results/iolist @@ -0,0 +1,2 @@ + +iolist.erl:7: The success typing for iolist:encode/2 implies that the function might also return integer() but the specification return is maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/src/iodata.erl b/lib/dialyzer/test/specdiffs_SUITE_data/src/iodata.erl new file mode 100644 index 0000000000..caa44f6c91 --- /dev/null +++ b/lib/dialyzer/test/specdiffs_SUITE_data/src/iodata.erl @@ -0,0 +1,41 @@ +-module(iodata). + +%% A small part of beam_asm. + +-export([encode/2]). + +-spec encode(non_neg_integer(), integer()) -> iodata(). % extra range binary() + +encode(Tag, N) when Tag >= 0, N < 0 -> + encode1(Tag, negative_to_bytes(N)); +encode(Tag, N) when Tag >= 0, N < 16 -> + (N bsl 4) bor Tag; % not in the specification +encode(Tag, N) when Tag >= 0, N < 16#800 -> + [((N bsr 3) band 2#11100000) bor Tag bor 2#00001000, N band 16#ff]; +encode(Tag, N) when Tag >= 0 -> + encode1(Tag, to_bytes(N)). + +encode1(Tag, Bytes) -> + case iolist_size(Bytes) of + Num when 2 =< Num, Num =< 8 -> + [((Num-2) bsl 5) bor 2#00011000 bor Tag| Bytes]; + Num when 8 < Num -> + [2#11111000 bor Tag, encode(0, Num-9)| Bytes] + end. + +to_bytes(N) -> + Bin = binary:encode_unsigned(N), + case Bin of + <<0:1,_/bits>> -> Bin; + <<1:1,_/bits>> -> [0,Bin] + end. + +negative_to_bytes(N) when N >= -16#8000 -> + <<N:16>>; +negative_to_bytes(N) -> + Bytes = byte_size(binary:encode_unsigned(-N)), + Bin = <<N:Bytes/unit:8>>, + case Bin of + <<0:1,_/bits>> -> [16#ff,Bin]; + <<1:1,_/bits>> -> Bin + end. diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/src/iolist.erl b/lib/dialyzer/test/specdiffs_SUITE_data/src/iolist.erl new file mode 100644 index 0000000000..7cceeda24e --- /dev/null +++ b/lib/dialyzer/test/specdiffs_SUITE_data/src/iolist.erl @@ -0,0 +1,41 @@ +-module(iolist). + +%% A small part of beam_asm. + +-export([encode/2]). + +-spec encode(non_neg_integer(), integer()) -> iolist(). + +encode(Tag, N) when Tag >= 0, N < 0 -> + encode1(Tag, negative_to_bytes(N)); +encode(Tag, N) when Tag >= 0, N < 16 -> + (N bsl 4) bor Tag; % not in the specification +encode(Tag, N) when Tag >= 0, N < 16#800 -> + [((N bsr 3) band 2#11100000) bor Tag bor 2#00001000, N band 16#ff]; +encode(Tag, N) when Tag >= 0 -> + encode1(Tag, to_bytes(N)). + +encode1(Tag, Bytes) -> + case iolist_size(Bytes) of + Num when 2 =< Num, Num =< 8 -> + [((Num-2) bsl 5) bor 2#00011000 bor Tag| Bytes]; + Num when 8 < Num -> + [2#11111000 bor Tag, encode(0, Num-9)| Bytes] + end. + +to_bytes(N) -> + Bin = binary:encode_unsigned(N), + case Bin of + <<0:1,_/bits>> -> Bin; + <<1:1,_/bits>> -> [0,Bin] + end. + +negative_to_bytes(N) when N >= -16#8000 -> + <<N:16>>; +negative_to_bytes(N) -> + Bytes = byte_size(binary:encode_unsigned(-N)), + Bin = <<N:Bytes/unit:8>>, + case Bin of + <<0:1,_/bits>> -> [16#ff,Bin]; + <<1:1,_/bits>> -> Bin + end. diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk index 7240b66fb5..fa58adc2db 100644 --- a/lib/dialyzer/vsn.mk +++ b/lib/dialyzer/vsn.mk @@ -1 +1 @@ -DIALYZER_VSN = 3.3 +DIALYZER_VSN = 3.2.4 diff --git a/lib/diameter/bin/diameterc b/lib/diameter/bin/diameterc index 3dbd238c19..4d415ece78 100755 --- a/lib/diameter/bin/diameterc +++ b/lib/diameter/bin/diameterc @@ -4,7 +4,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -78,8 +78,8 @@ compile(#argv{file = File, options = Opts, output = Out}) -> error_msg(diameter_make:format_error(Reason), []), 1 catch - error: Reason -> - error_msg("ERROR: ~p~n ~p", [Reason, erlang:get_stacktrace()]), + error: Reason: Stack -> + error_msg("ERROR: ~p~n ~p", [Reason, Stack]), 2 end. diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml index 3aaf17bc60..f74a4ca2a2 100644 --- a/lib/diameter/doc/src/notes.xml +++ b/lib/diameter/doc/src/notes.xml @@ -43,21 +43,6 @@ first.</p> <!-- ===================================================================== --> -<section><title>diameter 2.1.5</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Fix documentation typos.</p> - <p> - Own Id: OTP-15045</p> - </item> - </list> - </section> - -</section> - <section><title>diameter 2.1.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/diameter/src/Makefile b/lib/diameter/src/Makefile index 3af856f63e..f78a163591 100644 --- a/lib/diameter/src/Makefile +++ b/lib/diameter/src/Makefile @@ -149,7 +149,7 @@ gen/$(DICT_YRL).erl: compiler/$(DICT_YRL).yrl $(ERLC) -Werror -o $(@D) $< # Generate the app file. -$(APP_TARGET): $(APP_SRC) ../vsn.mk modules.mk app.sed +$(APP_TARGET): $(APP_SRC) ../vsn.mk modules.mk $(gen_verbose) \ M=`echo $(notdir $(APP_MODULES)) | tr ' ' ,`; \ C=`echo $(COMPILER_MODULES) | tr ' ' ,`; \ @@ -160,8 +160,7 @@ $(APP_TARGET): $(APP_SRC) ../vsn.mk modules.mk app.sed -e "s;%COMPILER%;$$C;" \ -e "s;%INFO%;$$I;" \ -e "s;%REGISTERED%;$$R;" \ - $< \ - | sed -f app.sed > $@ + $< > $@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk $(vsn_verbose) \ diff --git a/lib/diameter/src/app.sed b/lib/diameter/src/app.sed deleted file mode 100644 index dd3806f5f1..0000000000 --- a/lib/diameter/src/app.sed +++ /dev/null @@ -1,41 +0,0 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 2014-2016. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# %CopyrightEnd% - -# -# Generate runtime_dependencies from applications to avoid having to -# specify the same application more than once. -# - -/{runtime_dependencies,/b v -/{[-a-z]*, "[0-9.]*"}/!b -/{vsn,/b - -/%%/!H -s/{\([^,]*\)[^}]*}/\1/g -s/%%/%,/ -b - -:v - -p -x -s/\n// -s/%//g -s/\n */ /g -s/{\([^,]*\), "\([^"]*"\)}/"\1-\2/g diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl index 2dd2c906a2..5c0a24cdf6 100644 --- a/lib/diameter/src/base/diameter_codec.erl +++ b/lib/diameter/src/base/diameter_codec.erl @@ -92,8 +92,8 @@ encode(Mod, Opts, #diameter_packet{} = Pkt) -> %% count encode errors. ?LOG(encode_error, {Reason, Stack, H}), exit({?MODULE, encode, T}); - error: Reason -> - T = {Reason, diameter_lib:get_stacktrace()}, + error: Reason: Stack -> + T = {Reason, diameter_lib:stacktrace(Stack)}, ?LOG(encode_error, T), exit({?MODULE, encode, T}) end; @@ -134,8 +134,8 @@ enc(_, Opts, #diameter_packet{msg = [#diameter_header{} = Hdr | As]} Eid:32, Bin/binary>>} catch - error: Reason -> - exit({Reason, diameter_lib:get_stacktrace(), Hdr}) + error: Reason: Stack -> + exit({Reason, diameter_lib:stacktrace(Stack), Hdr}) end; enc(Mod, Opts, #diameter_packet{header = Hdr0, msg = Msg} = Pkt) -> @@ -179,14 +179,14 @@ enc(Mod, Opts, #diameter_packet{header = Hdr0, msg = Msg} = Pkt) -> Eid:32, Bin/binary>>} catch - error: Reason -> + error: Reason: Stack -> Hdr = Hdr0#diameter_header{cmd_code = Code, application_id = Aid, is_request = RB, is_proxiable = PB, is_error = EB, is_retransmitted = TB}, - exit({Reason, diameter_lib:get_stacktrace(), Hdr}) + exit({Reason, diameter_lib:stacktrace(Stack), Hdr}) end. %% values/1 diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl index 90a9282349..36ae4c2276 100644 --- a/lib/diameter/src/base/diameter_config.erl +++ b/lib/diameter/src/base/diameter_config.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -633,8 +633,8 @@ opt(service, {K, F}) Nodes -> is_list(Nodes) orelse {error, Nodes} catch - E:R -> - {error, {E, R, ?STACK}} + E:R:Stack -> + {error, {E, R, Stack}} end; opt(service, {sequence, {H,N}}) -> @@ -651,8 +651,8 @@ opt(service = S, {sequence = K, F}) -> V -> {error, V} catch - E:R -> - {error, {E, R, ?STACK}} + E:R:Stack -> + {error, {E, R, Stack}} end; opt(transport, {transport_module, M}) -> @@ -932,8 +932,8 @@ cb(M,F) -> try M:F() of V -> V catch - E: Reason -> - ?THROW({callback, E, Reason, ?STACK}) + E: Reason: Stack -> + ?THROW({callback, E, Reason, Stack}) end. %% call/1 diff --git a/lib/diameter/src/base/diameter_gen.erl b/lib/diameter/src/base/diameter_gen.erl index 93ebe57685..d110a3015e 100644 --- a/lib/diameter/src/base/diameter_gen.erl +++ b/lib/diameter/src/base/diameter_gen.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -76,8 +76,7 @@ encode_avps(Name, Vals, #{module := Mod} = Opts) -> ?LINE, {Reason, Name, Vals, Mod}), erlang:error(list_to_tuple(Reason ++ [Name])); - error: Reason -> - Stack = erlang:get_stacktrace(), + error: Reason: Stack -> diameter_lib:log({encode, failure}, ?MODULE, ?LINE, @@ -555,8 +554,8 @@ dec(Data, Name, AvpName, Type, Mod, Dict, Fmt, Failed, Opts, Avp) -> catch throw: {?MODULE, T} -> decode_error(Failed, Fmt, T, Avp); - error: Reason -> - decode_error(Failed, Reason, Name, Mod, Opts, Avp) + error: Reason: Stack -> + decode_error(Failed, Reason, Stack, Name, Mod, Opts, Avp) end. %% dec_AVP/7 @@ -623,19 +622,19 @@ set(none, Avp, _Name) -> set(_, Avp, Rec) -> Avp#diameter_avp{value = Rec}. -%% decode_error/6 +%% decode_error/7 %% %% Error when decoding a non-grouped AVP. -decode_error(true, _, _, _, _, Avp) -> +decode_error(true, _, _, _, _, _, Avp) -> Avp; -decode_error(false, Reason, Name, Mod, Opts, Avp) -> - Stack = diameter_lib:get_stacktrace(), +decode_error(false, Reason, Stack, Name, Mod, Opts, Avp) -> + Z = diameter_lib:stacktrace(Stack), diameter_lib:log(decode_error, ?MODULE, ?LINE, - {Reason, Name, Avp#diameter_avp.name, Mod, Stack}), + {Reason, Name, Avp#diameter_avp.name, Mod, Z}), case Reason of {'DIAMETER', 5014 = RC, _} -> %% Length error communicated from diameter_types or a diff --git a/lib/diameter/src/base/diameter_internal.hrl b/lib/diameter/src/base/diameter_internal.hrl index a0f4a8567d..4a678643c2 100644 --- a/lib/diameter/src/base/diameter_internal.hrl +++ b/lib/diameter/src/base/diameter_internal.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -35,9 +35,6 @@ %% A corresponding error when failure is the best option. -define(ERROR(T), erlang:error({T, ?MODULE, ?LINE})). -%% Failure reports always get a stack trace. --define(STACK, erlang:get_stacktrace()). - %% Warning report for unexpected messages in various processes. -define(UNEXPECTED(F,A), diameter_lib:warning_report(unexpected, {?MODULE, F, A})). diff --git a/lib/diameter/src/base/diameter_lib.erl b/lib/diameter/src/base/diameter_lib.erl index 1c1ea42cb5..edd9d5a4ce 100644 --- a/lib/diameter/src/base/diameter_lib.erl +++ b/lib/diameter/src/base/diameter_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ time/1, eval/1, eval_name/1, - get_stacktrace/0, + stacktrace/1, ipaddr/1, spawn_opts/2, wait/1, @@ -42,16 +42,13 @@ log/4]). %% --------------------------------------------------------------------------- -%% # get_stacktrace/0 +%% # stacktrace/1 %% --------------------------------------------------------------------------- %% Return a stacktrace with a leading, potentially large, argument -%% list replaced by an arity. Trace on stacktrace/0 to see the +%% list replaced by an arity. Trace on stacktrace/1 to see the %% original. -get_stacktrace() -> - stacktrace(erlang:get_stacktrace()). - stacktrace([{M,F,A,L} | T]) when is_list(A) -> [{M, F, length(A), L} | T]; stacktrace(L) -> @@ -268,8 +265,8 @@ ipaddr(Addr) -> try ip(Addr) catch - error: _ -> - erlang:error({invalid_address, erlang:get_stacktrace()}) + error: _: Stack -> + erlang:error({invalid_address, Stack}) end. %% Already a tuple: ensure non-negative integers of the right size. diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl index cbe66ef27a..77d184cfc7 100644 --- a/lib/diameter/src/base/diameter_service.erl +++ b/lib/diameter/src/base/diameter_service.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -808,8 +808,8 @@ remotes(F) -> error_report(invalid_return, share_peers, F), [] catch - E:R -> - ?LOG(failure, {E, R, F, diameter_lib:get_stacktrace()}), + E:R:S -> + ?LOG(failure, {E, R, F, diameter_lib:stacktrace(S)}), error_report(failure, share_peers, F), [] end. @@ -1146,11 +1146,11 @@ peer_cb(App, F, A) -> mod_state(App#diameter_app.alias, ModS), true catch - E:R -> + E:R:S -> %% Don't include arguments since a #diameter_caps{} strings %% from the peer, which could be anything (especially, large). [Mod|X] = App#diameter_app.module, - ?LOG(failure, {E, R, Mod, F, diameter_lib:get_stacktrace()}), + ?LOG(failure, {E, R, Mod, F, diameter_lib:stacktrace(S)}), error_report(failure, F, {Mod, F, A ++ X}), false end. @@ -1376,9 +1376,9 @@ cm([#diameter_app{alias = Alias} = App], Req, From, Svc) -> ?LOG(invalid_return, {ModX, handle_call, Args, T}), invalid catch - E: Reason -> + E: Reason: S -> ModX = App#diameter_app.module, - Stack = diameter_lib:get_stacktrace(), + Stack = diameter_lib:stacktrace(S), ?LOG(failure, {E, Reason, ModX, handle_call, Stack}), failure end; @@ -1585,10 +1585,10 @@ pick_peer(Local, ?LOG(invalid_return, {ModX, pick_peer, T}), false catch - E: Reason when M -> + E: Reason: Stack when M -> ModX = App#diameter_app.module, - Stack = diameter_lib:get_stacktrace(), - ?LOG(failure, {E, Reason, ModX, pick_peer, Stack}), + Z = diameter_lib:stacktrace(Stack), + ?LOG(failure, {E, Reason, ModX, pick_peer, Z}), false end. diff --git a/lib/diameter/src/compiler/diameter_make.erl b/lib/diameter/src/compiler/diameter_make.erl index eae40dbafd..03cfc03edc 100644 --- a/lib/diameter/src/compiler/diameter_make.erl +++ b/lib/diameter/src/compiler/diameter_make.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -271,6 +271,6 @@ make(File, Opts, Dict, Mode) -> try diameter_codegen:from_dict(File, Dict, Opts, Mode) catch - error: Reason -> - erlang:error({Reason, Mode, erlang:get_stacktrace()}) + error: Reason: Stack -> + erlang:error({Reason, Mode, Stack}) end. diff --git a/lib/diameter/src/diameter.app.src b/lib/diameter/src/diameter.app.src index 9a6e47006b..18202f033e 100644 --- a/lib/diameter/src/diameter.app.src +++ b/lib/diameter/src/diameter.app.src @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -28,14 +28,21 @@ ]}, {registered, [%REGISTERED%]}, {applications, [ - {stdlib, "2.4"}, {kernel, "3.2"}%, {erts, "6.4"} - %% {syntax-tools, "1.6,18"} - %% {runtime-tools, "1.8.16"} - %, {ssl, "6.0"} + stdlib, + kernel + %, ssl + %, syntax-tools + %, runtime-tools ]}, {env, []}, {mod, {diameter_app, []}}, {runtime_dependencies, [ + "erts-10.0", + "stdlib-2.4", + "kernel-3.2", + "ssl-9.0" + %, "syntax-tools-1.6.18" + %, "runtime-tools-1.8.16" ]} %% %% Note that ssl is only required if configured on TCP transports, diff --git a/lib/diameter/src/transport/diameter_tcp.erl b/lib/diameter/src/transport/diameter_tcp.erl index a8639baa11..681d273d07 100644 --- a/lib/diameter/src/transport/diameter_tcp.erl +++ b/lib/diameter/src/transport/diameter_tcp.erl @@ -716,7 +716,7 @@ tls_handshake(_, false, S) -> tls(connect, Sock, Opts) -> ssl:connect(Sock, Opts); tls(accept, Sock, Opts) -> - ssl:ssl_accept(Sock, Opts). + ssl:handshake(Sock, Opts). %% assume no handshake option %% recv/2 %% @@ -839,7 +839,7 @@ start_fragment_timer(#transport{timeout = Tmo} = S) -> accept(ssl, LSock) -> case ssl:transport_accept(LSock) of {ok, Sock} -> - {ssl:ssl_accept(Sock), Sock}; + ssl:handshake(Sock); {error, _} = No -> No end; diff --git a/lib/diameter/test/diameter_app_SUITE.erl b/lib/diameter/test/diameter_app_SUITE.erl index 71256020f5..ef4a28d3f4 100644 --- a/lib/diameter/test/diameter_app_SUITE.erl +++ b/lib/diameter/test/diameter_app_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2015. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -208,9 +208,9 @@ xref(Config) -> CTmods = CTmods -- Mods, %% Ensure that runtime modules only call other runtime modules, or - %% applications declared as in runtime_dependencies in the app - %% file. Note that the declared application versions are ignored - %% since we only know what we can see now. + %% applications declared in runtime_dependencies in the app file. + %% The declared application versions are ignored since we only + %% know what we see now. [] = lists:filter(fun(M) -> not lists:member(app(M), Deps) end, RTdeps -- Mods). @@ -261,8 +261,12 @@ app(Mod) -> case code:which(Mod) of preloaded -> "erts"; + Reason when is_atom(Reason) -> + error({Reason, Mod}); Path -> - unversion(lists:nth(3, lists:reverse(filename:split(Path)))) + %% match to identify an unexpectedly short path + {_, _, [_,_,_|_] = Split} = {Mod, Path, filename:split(Path)}, + unversion(lists:nth(3, lists:reverse(Split))) end. add_application(XRef, App) -> diff --git a/lib/diameter/test/diameter_traffic_SUITE.erl b/lib/diameter/test/diameter_traffic_SUITE.erl index c224f9a27e..434aef01dd 100644 --- a/lib/diameter/test/diameter_traffic_SUITE.erl +++ b/lib/diameter/test/diameter_traffic_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -1924,8 +1924,8 @@ compile_and_load() -> {module, nas4005} = code:load_binary(nas4005, "nas4005", Bin), true catch - E:R -> - {E, R, erlang:get_stacktrace()} + E:R:Stack -> + {E, R, Stack} end. here() -> diff --git a/lib/diameter/test/diameter_watchdog_SUITE.erl b/lib/diameter/test/diameter_watchdog_SUITE.erl index 39c4f051a5..f3f168e671 100644 --- a/lib/diameter/test/diameter_watchdog_SUITE.erl +++ b/lib/diameter/test/diameter_watchdog_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -638,10 +638,9 @@ run1([F|A]) -> apply(?MODULE, F, A), ok catch - E:R -> - S = erlang:get_stacktrace(), - ?WARN("~p", [{A, E, R, S}]), - S + E:R:Stack -> + ?WARN("~p", [{A, E, R, Stack}]), + Stack end. %% jitter/2 diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml index 853cc792e0..240789e876 100644 --- a/lib/edoc/doc/src/notes.xml +++ b/lib/edoc/doc/src/notes.xml @@ -32,21 +32,6 @@ <p>This document describes the changes made to the EDoc application.</p> -<section><title>Edoc 0.9.3</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Update to use the new string api instead of the old.</p> - <p> - Own Id: OTP-15036</p> - </item> - </list> - </section> - -</section> - <section><title>Edoc 0.9.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/edoc/src/edoc_layout.erl b/lib/edoc/src/edoc_layout.erl index baa147410b..47ff7b21fc 100644 --- a/lib/edoc/src/edoc_layout.erl +++ b/lib/edoc/src/edoc_layout.erl @@ -1193,6 +1193,8 @@ ot_name(Es, T) -> {atom,0,list_to_atom(Atom)},T]}; "tuple" when T =:= [] -> {type,0,tuple,any}; + "map" when T =:= [] -> + {type,0,map,any}; Atom -> {type,0,list_to_atom(Atom),T} end. diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk index bea9277e1f..2f6d469536 100644 --- a/lib/edoc/vsn.mk +++ b/lib/edoc/vsn.mk @@ -1 +1 @@ -EDOC_VSN = 0.9.3 +EDOC_VSN = 0.9.2 diff --git a/lib/eldap/doc/src/notes.xml b/lib/eldap/doc/src/notes.xml index 3007068eeb..8b066671ee 100644 --- a/lib/eldap/doc/src/notes.xml +++ b/lib/eldap/doc/src/notes.xml @@ -31,21 +31,6 @@ </header> <p>This document describes the changes made to the Eldap application.</p> -<section><title>Eldap 1.2.4</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Update to use the new string api instead of the old.</p> - <p> - Own Id: OTP-15036</p> - </item> - </list> - </section> - -</section> - <section><title>Eldap 1.2.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/eldap/vsn.mk b/lib/eldap/vsn.mk index f2b3cd47f2..1636b6bb6d 100644 --- a/lib/eldap/vsn.mk +++ b/lib/eldap/vsn.mk @@ -1 +1 @@ -ELDAP_VSN = 1.2.4 +ELDAP_VSN = 1.2.3 diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml index e87a1ae102..f75d2af5c4 100644 --- a/lib/erl_docgen/doc/src/notes.xml +++ b/lib/erl_docgen/doc/src/notes.xml @@ -31,7 +31,7 @@ </header> <p>This document describes the changes made to the <em>erl_docgen</em> application.</p> - <section><title>Erl_Docgen 0.8</title> + <section><title>Erl_Docgen 0.7.3</title> <section><title>Fixed Bugs and Malfunctions</title> <list> @@ -44,24 +44,6 @@ </list> </section> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Add a hoverable element to the titles in the html - documentation with a link to github where the - documentation can be edited.</p> - <p> - Make the anchors in the html User's Guide and system - documentation use the title of the sections instead of a - generated id.</p> - <p> - Own Id: OTP-14979</p> - </item> - </list> - </section> - </section> <section><title>Erl_Docgen 0.7.2</title> diff --git a/lib/erl_docgen/src/docgen_otp_specs.erl b/lib/erl_docgen/src/docgen_otp_specs.erl index 9f2b401f93..311ec1471a 100644 --- a/lib/erl_docgen/src/docgen_otp_specs.erl +++ b/lib/erl_docgen/src/docgen_otp_specs.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2017. All Rights Reserved. +%% Copyright Ericsson AB 1996-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -658,6 +658,8 @@ ot_name(Es, T) -> {atom,0,list_to_atom(Atom)},T]}; "tuple" when T =:= [] -> {type,0,tuple,any}; + "map" when T =:= [] -> + {type,0,map,any}; Atom -> {type,0,list_to_atom(Atom),T} end. diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk index 0b24604daa..a556b73103 100644 --- a/lib/erl_docgen/vsn.mk +++ b/lib/erl_docgen/vsn.mk @@ -1 +1 @@ -ERL_DOCGEN_VSN = 0.8 +ERL_DOCGEN_VSN = 0.7.3 diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index 34c72e7d5f..f165dde259 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -31,22 +31,6 @@ </header> <p>This document describes the changes made to the Erl_interface application.</p> -<section><title>Erl_Interface 3.10.3</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Fix bug where calling erl_init on certain platforms could - result in a buffer overflow bug.</p> - <p> - Own Id: OTP-15033</p> - </item> - </list> - </section> - -</section> - <section><title>Erl_Interface 3.10.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c index 7577a07a3e..52ad6885e8 100644 --- a/lib/erl_interface/src/prog/erl_call.c +++ b/lib/erl_interface/src/prog/erl_call.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2017. All Rights Reserved. + * Copyright Ericsson AB 1996-2018. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -517,6 +517,15 @@ int erl_call(int argc, char **argv) } } + + /* + * If we loaded any module source code, we can free the buffer + * now. This buffer was allocated in read_stdin(). + */ + if (module != NULL) { + free(module); + } + /* * Eval the Erlang functions read from stdin/ */ @@ -545,7 +554,7 @@ int erl_call(int argc, char **argv) /* erl_format("[~w]", erl_mk_binary(evalbuf,len))) */ - if (ei_rpc(&ec, fd, "lib", "eval_str", p, i, &reply) < 0) { + if (ei_rpc(&ec, fd, "erl_eval", "eval_str", p, i, &reply) < 0) { fprintf(stderr,"erl_call: evaluating input failed: %s\n", evalbuf); free(p); @@ -795,8 +804,6 @@ static int get_module(char **mbuf, char **mname) *mname = (char *) ei_chk_calloc(i+1, sizeof(char)); memcpy(*mname, start, i); } - if (*mbuf) - free(*mbuf); /* Allocated in read_stdin() */ return len; diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index 586b23c5b3..8b6e91757d 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1,2 +1,2 @@ -EI_VSN = 3.10.3 +EI_VSN = 3.10.2 ERL_INTERFACE_VSN = $(EI_VSN) diff --git a/lib/et/doc/src/notes.xml b/lib/et/doc/src/notes.xml index 14e674c7c9..f0995b7c19 100644 --- a/lib/et/doc/src/notes.xml +++ b/lib/et/doc/src/notes.xml @@ -37,21 +37,6 @@ one section in this document. The title of each section is the version number of <c>Event Tracer (ET)</c>.</p> -<section><title>ET 1.6.2</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> Calls to <c>erlang:get_stacktrace()</c> are removed. - </p> - <p> - Own Id: OTP-14861</p> - </item> - </list> - </section> - -</section> - <section><title>ET 1.6.1</title> <section><title>Improvements and New Features</title> diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk index 08ded8b6f1..aab63a402e 100644 --- a/lib/et/vsn.mk +++ b/lib/et/vsn.mk @@ -1 +1 @@ -ET_VSN = 1.6.2 +ET_VSN = 1.6.1 diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml index 037586b9d1..b38cb2e70e 100644 --- a/lib/eunit/doc/src/notes.xml +++ b/lib/eunit/doc/src/notes.xml @@ -33,21 +33,6 @@ </header> <p>This document describes the changes made to the EUnit application.</p> -<section><title>Eunit 2.3.6</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> Calls to <c>erlang:get_stacktrace()</c> are removed. - </p> - <p> - Own Id: OTP-14861</p> - </item> - </list> - </section> - -</section> - <section><title>Eunit 2.3.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk index 054e21f6ad..2ed9eaac16 100644 --- a/lib/eunit/vsn.mk +++ b/lib/eunit/vsn.mk @@ -1 +1 @@ -EUNIT_VSN = 2.3.6 +EUNIT_VSN = 2.3.5 diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml index b6801b6302..c190a89260 100644 --- a/lib/hipe/doc/src/notes.xml +++ b/lib/hipe/doc/src/notes.xml @@ -31,51 +31,6 @@ </header> <p>This document describes the changes made to HiPE.</p> -<section><title>Hipe 3.18</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Optimize <c>receive</c> statements that are only waiting - for messages containing a reference created before the - receive. All messages that existed in the queue when the - reference was created will be bypassed, as they cannot - possibly contain the reference. This optimization has - existed for vanilla BEAM since OTP R14.</p> - <p> - Own Id: OTP-14785 Aux Id: PR-1632 </p> - </item> - <item> - <p> - Add validation pass to hipe compiler to detect internal - errors causing primop calls that may trigger an unsafe GC - at run-time. The pass can be disabled with option - <c>no_verify_gcsafe</c>.</p> - <p> - Own Id: OTP-14900 Aux Id: PR-1685, PR-1621 </p> - </item> - <item> - <p> - Make hipe compiled code work on x86_64 (amd64) with OS - security feature PIE, where executable code can be loaded - into a random location. Old behavior, if hipe was - enabled, was to disable PIE build options for the VM.</p> - <p> - Own Id: OTP-14903</p> - </item> - <item> - <p> - Inline more type test BIFs; <c>is_number</c>, - <c>is_bitstring</c>, <c>is_map</c>.</p> - <p> - Own Id: OTP-14941 Aux Id: PR-1718 </p> - </item> - </list> - </section> - -</section> - <section><title>Hipe 3.17.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk index b081cb0c26..0c517f9a7a 100644 --- a/lib/hipe/vsn.mk +++ b/lib/hipe/vsn.mk @@ -1 +1 @@ -HIPE_VSN = 3.18 +HIPE_VSN = 3.17.1 diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 9357207867..1e22809b3a 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -33,60 +33,19 @@ <file>notes.xml</file> </header> - <section><title>Inets 7.0</title> + <section><title>Inets 6.5.2</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> <p> - Fixed HTTP content injection bug in httpc (ERL-456).</p> + inets: httpd - Gracefully handle bad headers</p> <p> - Own Id: OTP-14726</p> - </item> - <item> - <p> - Fixed support for URI-references in HTTP 'Location' - header (ERL-333).</p> - <p> - Own Id: OTP-14729</p> - </item> - <item> - <p> - Fix broken 'Content-Type' handling in httpc (ERL-536).</p> - <p> - Own Id: OTP-15006</p> - </item> - <item> - <p> - Fix handling of relative paths in the script_alias - property of httpd (ERL-574).</p> - <p> - Own Id: OTP-15021</p> - </item> - <item> - <p> - Fix httpd:reload_config/2 with path() as the first - argument (ERL-578).</p> - <p> - Own Id: OTP-15025</p> - </item> - <item> - <p> - Improved gracefulness.</p> - <p> - Own Id: OTP-15042</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Split inets and create separate ftp and tftp apps.</p> + The option max_headers operated on the individual header + length instead of the total length of all headers. Also + headers with empty keys are now discarded.</p> <p> - Own Id: OTP-14113</p> + Own Id: OTP-15092</p> </item> </list> </section> diff --git a/lib/inets/src/http_lib/http_request.erl b/lib/inets/src/http_lib/http_request.erl index f68b233e10..8ca1542164 100644 --- a/lib/inets/src/http_lib/http_request.erl +++ b/lib/inets/src/http_lib/http_request.erl @@ -27,10 +27,12 @@ key_value(KeyValueStr) -> case lists:splitwith(fun($:) -> false; (_) -> true end, KeyValueStr) of - {Key, [$: | Value]} -> + {Key, [$: | Value]} when Key =/= [] -> {http_util:to_lower(string:strip(Key)), string:strip(Value)}; {_, []} -> - undefined + undefined; + _ -> + undefined end. %%------------------------------------------------------------------------- %% headers(HeaderList, #http_request_h{}) -> #http_request_h{} diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl index 007d272323..e513eb8a3a 100644 --- a/lib/inets/src/http_server/httpd_request.erl +++ b/lib/inets/src/http_server/httpd_request.erl @@ -259,17 +259,17 @@ parse_headers(<<?LF, Octet, Rest/binary>>, Header, Headers, Current, Max, %% If ?CR is is missing RFC2616 section-19.3 parse_headers(<<?CR,?LF, Octet, Rest/binary>>, Header, Headers, Current, Max, Options, Result); -parse_headers(<<?CR,?LF, Octet, Rest/binary>>, Header, Headers, _, Max, +parse_headers(<<?CR,?LF, Octet, Rest/binary>>, Header, Headers, Current, Max, Options, Result) -> case http_request:key_value(lists:reverse(Header)) of undefined -> %% Skip headers with missing : parse_headers(Rest, [Octet], Headers, - 0, Max, Options, Result); + Current, Max, Options, Result); NewHeader -> case check_header(NewHeader, Options) of ok -> parse_headers(Rest, [Octet], [NewHeader | Headers], - 0, Max, Options, Result); + Current, Max, Options, Result); {error, Reason} -> HttpVersion = lists:nth(3, lists:reverse(Result)), {error, Reason, HttpVersion} diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl index b49b3a7093..21aafa7f7b 100644 --- a/lib/inets/src/http_server/mod_esi.erl +++ b/lib/inets/src/http_server/mod_esi.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2016. All Rights Reserved. +%% Copyright Ericsson AB 1997-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -561,7 +561,7 @@ eval(#mod{method = Method} = ModData, ESIBody, Modules) end. generate_webpage(ESIBody) -> - (catch eval_str(string:concat(ESIBody,". "))). + (catch erl_eval:eval_str(string:concat(ESIBody,". "))). is_authorized(_ESIBody, [all]) -> true; @@ -573,45 +573,3 @@ is_authorized(ESIBody, Modules) -> nomatch -> false end. - -%% eval_str(InStr) -> {ok, OutStr} | {error, ErrStr'} -%% InStr must represent a body -%% Note: If InStr is a binary it has to be a Latin-1 string. -%% If you have a UTF-8 encoded binary you have to call -%% unicode:characters_to_list/1 before the call to eval_str(). - --define(result(F,D), lists:flatten(io_lib:format(F, D))). - --spec eval_str(string()) -> - {'ok', string()} | {'error', string()}. - -eval_str(Str) when is_list(Str) -> - case erl_scan:tokens([], Str, 0) of - {more, _} -> - {error, "Incomplete form (missing .<cr>)??"}; - {done, {ok, Toks, _}, Rest} -> - case all_white(Rest) of - true -> - case erl_parse:parse_exprs(Toks) of - {ok, Exprs} -> - case catch erl_eval:exprs(Exprs, erl_eval:new_bindings()) of - {value, Val, _} -> - {ok, Val}; - Other -> - {error, ?result("*** eval: ~p", [Other])} - end; - {error, {_Line, Mod, Args}} -> - Msg = ?result("*** ~ts",[Mod:format_error(Args)]), - {error, Msg} - end; - false -> - {error, ?result("Non-white space found after " - "end-of-form :~ts", [Rest])} - end - end. - -all_white([$\s|T]) -> all_white(T); -all_white([$\n|T]) -> all_white(T); -all_white([$\t|T]) -> all_white(T); -all_white([]) -> true; -all_white(_) -> false. diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index c86b5c0b48..9bbcd06914 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 7.0 +INETS_VSN = 6.5.2 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml index 7f85517ca4..346d467c2d 100644 --- a/lib/jinterface/doc/src/notes.xml +++ b/lib/jinterface/doc/src/notes.xml @@ -31,21 +31,6 @@ </header> <p>This document describes the changes made to the Jinterface application.</p> -<section><title>Jinterface 1.9</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Add module package name for Java 9</p> - <p> - Own Id: OTP-14844</p> - </item> - </list> - </section> - -</section> - <section><title>Jinterface 1.8.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk index f527a83092..0a8a1190ec 100644 --- a/lib/jinterface/vsn.mk +++ b/lib/jinterface/vsn.mk @@ -1 +1 @@ -JINTERFACE_VSN = 1.9 +JINTERFACE_VSN = 1.8.1 diff --git a/lib/kernel/doc/src/error_logger.xml b/lib/kernel/doc/src/error_logger.xml index f418aa5bbe..27fb1488c7 100644 --- a/lib/kernel/doc/src/error_logger.xml +++ b/lib/kernel/doc/src/error_logger.xml @@ -305,14 +305,22 @@ ok</pre> <type name="open_error"/> <desc> <p>Enables or disables printout of standard events to a file.</p> - <p>This is done by adding or deleting the standard event handler - for output to file. Thus, calling this function overrides - the value of the Kernel <c>error_logger</c> configuration - parameter.</p> - <p>Enabling file logging can be used together with calling - <c>tty(false)</c>, to have a silent system where - all standard events are logged to a file only. - Only one log file can be active at a time.</p> + <p>This is done by adding or deleting + the <c>error_logger_file_h</c> event handler, and thus + indirectly adding <c>error_logger</c> as a Logger + handler.</p> + <p>Notice that this function does not manipulate the Logger + configuration directly, meaning that if the default Logger + handler is already logging to a file, this function can + potentially cause logging to a second file.</p> + <p>This function is useful as a shortcut during development + and testing, but must not be used in a production + system. See + section <seealso marker="logger_chapter">Logging</seealso> + in the Kernel User's Guide, and + the <seealso marker="logger"><c>logger(3)</c></seealso> + manual page for information about how to configure Logger + for live systems.</p> <p><c>Request</c> is one of the following:</p> <taglist> <tag><c>{open, <anno>Filename</anno>}</c></tag> @@ -344,9 +352,14 @@ ok</pre> <p>Enables (<c><anno>Flag</anno> == true</c>) or disables (<c><anno>Flag</anno> == false</c>) printout of standard events to the terminal.</p> - <p>This is done by adding or deleting the standard event handler - for output to the terminal. Thus, calling this function overrides - the value of the Kernel <c>error_logger</c> configuration parameter.</p> + <p>This is done by manipulating the Logger configuration. The + function is useful as a shortcut during development and + testing, but must not be used in a production system. See + section <seealso marker="logger_chapter">Logging</seealso> + in the Kernel User's Guide, and + the <seealso marker="logger"><c>logger(3)</c></seealso> + manual page for information about how to configure Logger + for live systems.</p> </desc> </func> <func> diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index 9552332948..e6a7962c5a 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -1149,7 +1149,7 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp</code> <seealso marker="gen_tcp#recv/2"><c>gen_tcp:recv/2</c></seealso> gets <c>{error, closed}</c>. In active mode, the controlling process receives a - <c>{tcp_close, Socket}</c> message, indicating that the + <c>{tcp_closed, Socket}</c> message, indicating that the peer has closed the connection.</p> <p>Setting this option to <c>true</c> allows you to distinguish between a connection that was closed normally, diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml index e2a6d30249..3914226a3e 100644 --- a/lib/kernel/doc/src/kernel_app.xml +++ b/lib/kernel/doc/src/kernel_app.xml @@ -54,9 +54,9 @@ <p>Two standard logger handlers are defined in the Kernel application. These are described in the <seealso marker="logger_chapter">Kernel User's Guide</seealso>, - and in <seealso marker="logger_std_h"><c>logger_std_h(3)</c></seealso> + and in the <seealso marker="logger_std_h"><c>logger_std_h(3)</c></seealso> and <seealso marker="logger_disk_log_h"><c>logger_disk_log_h(3)</c> - </seealso>.</p> + </seealso> manual pages.</p> </section> <section> @@ -166,57 +166,71 @@ </item> <tag><marker id="logger"/><c>logger = [Config]</c></tag> <item> - <p>Specifies how <seealso marker="logger"><c>logger</c></seealso> should be - configured.</p> - <p>For more details and examples, see the <seealso marker="logger_chapter#logger"> - Configuration</seealso> section in the <seealso marker="logger_chapter"> - Logger User's Guide</seealso>. - </p> + <p>Specifies the configuration + for <seealso marker="logger">Logger</seealso>, except the + primary log level, which is specified + with <seealso marker="#logger_level"><c>logger_level</c></seealso>, + and the compatibility + with <seealso marker="sasl:error_logging">SASL Error + Logging</seealso>, which is specified + with <seealso marker="#logger_sasl_compatible"> + <c>logger_sasl_compatible</c></seealso>.</p> + <p>The <c>logger </c> parameter is described in + section <seealso marker="logger_chapter#logger_parameter"> + Logging</seealso> in the Kernel User's Guide.</p> </item> <tag><marker id="logger_level"/><c>logger_level = Level</c></tag> <item> - <p><c>Level = emergency | alert | critical | error | warning | - notice | info | debug</c></p> - <p>This parameter specifies which log levels to log. The - specified level, and all levels that are more severe, will - be logged.</p> - <p>The default value is <c>info</c>.</p> - <p>To change the global log level at run-time, use - <seealso marker="logger#set_logger_config/2"> - <c>logger:set_logger_config(level, error)</c></seealso>.</p> + <p>Specifies the primary log level for Logger. Log events with + the same, or a more severe level, pass through the primary + log level check. See + section <seealso marker="logger_chapter">Logging</seealso> + in the Kernel User's Guide for more information about Logger + and log levels.</p> + <p><c>Level = emergency | alert | critical | error | warning | + notice | info | debug | all | none</c></p> + <p>To change the primary log level at runtime, use + <seealso marker="logger#set_primary_config/2"> + <c>logger:set_primary_config(level, Level)</c></seealso>.</p> + <p>Defaults to <c>info</c>.</p> </item> <tag><marker id="logger_sasl_compatible"/> - <c>logger_sasl_compatible = boolean()</c></tag> - <item> - <p>If this parameter is set to true, then the <c>default</c> logger handler - will not log any progress-, crash-, or supervisor reports. - If the SASL application is started, - these log events will be sent to a second handler instance - named <c>sasl</c>, according to values of the SASL - configuration parameter <c>sasl_error_logger</c> - and <c>sasl_errlog_type</c>, see - <seealso marker="sasl:sasl_app#deprecated_error_logger_config">sasl(6) - </seealso></p> - <p>The default value is <c>false</c>.</p> - <p>See chapter <seealso marker="logger_chapter#compatibility">Backwards - compatibility with error_logger</seealso> for more - information about handling of the so called SASL reports.</p> - <note><p>This configuration option only effects the <c>default</c> - and <c>sasl</c> handler. Any other handlers are uneffected.</p></note> - </item> - <tag><marker id="logger_progress_reports"/> - <c>logger_progress_reports = stop | log</c></tag> - <item> - <p>If <c>logger_sasl_compatible = false</c>, - then <c>logger_progress_reports</c> specifies if progress - reports from <c>supervisor</c> - and <c>application_controller</c> shall be logged by the - default logger.</p> - <p>If <c>logger_sasl_compatible = true</c>, - then <c>logger_progress_reports</c> is ignored.</p> - <p>The default value is <c>stop</c></p> - <note><p>This configuration option only effects the <c>default</c> - and <c>sasl</c> handler. Any other handlers are uneffected.</p></note> + <c>logger_sasl_compatible = true | false</c></tag> + <item> + <p>Specifies if Logger behaves backwards compatible with the + SASL error logging functionality from releases prior to + Erlang/OTP 21.0.</p> + <p>If this parameter is set to <c>true</c>, the default Logger + handler does not log any progress-, crash-, or supervisor + reports. If the SASL application is then started, it adds a + Logger handler named <c>sasl</c>, which logs these events + according to values of the SASL configuration + parameter <c>sasl_error_logger</c> + and <c>sasl_errlog_type</c>.</p> + <p>See section + <seealso marker="sasl:sasl_app#deprecated_error_logger_config"> + Deprecated Error Logger Event Handlers and + Configuration</seealso> in the sasl(6) manual page for + information about the SASL configuration parameters.</p> + <p>See section <seealso marker="sasl:error_logging">SASL Error + Logging</seealso> in the SASL User's Guide, and + section <seealso marker="logger_chapter#compatibility">Backwards + Compatibility with error_logger</seealso> in the Kernel + User's Guide for information about the SASL error logging + functionality, and how Logger can be backwards compatible + with this.</p> + <p>Defaults to <c>false</c>.</p> + <note> + <p>If this parameter is set to <c>true</c>, + <c>sasl_errlog_type</c> indicates that progress reports + shall be logged, and the configured primary log level + is <c>notice</c> or more severe, then SASL automatically + sets the primary log level to <c>info</c>. That is, this + setting can potentially overwrite the value of the Kernel + configuration parameter <c>logger_level</c>. This is to + allow progress reports, which have log level <c>info</c>, + to be forwarded to the handlers.</p> + </note> </item> <tag><c>global_groups = [GroupTuple]</c></tag> <item> @@ -269,9 +283,8 @@ </item> <tag><c>inet_parse_error_log = silent</c></tag> <item> - <p>If set, no - <c>logger</c> messages are generated when erroneous - lines are found and skipped in the various Inet configuration + <p>If set, no log events are issued when erroneous lines are + found and skipped in the various Inet configuration files.</p> </item> <tag><c>inetrc = Filename</c></tag> @@ -494,7 +507,7 @@ MaxT = TickTime + TickTime / 4</code> <seealso marker="logger_std_h#type"><c>logger_std_h</c></seealso> to the same value. Example: <code type="none"> -erl -kernel logger '[{handler,default,logger_std_h,#{logger_std_h=>#{type=>{file,"/tmp/erlang.log"}}}}]' +erl -kernel logger '[{handler,default,logger_std_h,#{config=>#{type=>{file,"/tmp/erlang.log"}}}}]' </code> </item> <tag><c>error_logger_format_depth</c></tag> diff --git a/lib/kernel/doc/src/logger.xml b/lib/kernel/doc/src/logger.xml index 911eb158da..7f35a5d752 100644 --- a/lib/kernel/doc/src/logger.xml +++ b/lib/kernel/doc/src/logger.xml @@ -33,73 +33,150 @@ <file>logger.xml</file> </header> <module>logger</module> - <modulesummary>API module for logging in Erlang/OTP.</modulesummary> + <modulesummary>API module for Logger, the standard logging facility + in Erlang/OTP.</modulesummary> <description> - <p> - This module is the main API for logging in Erlang/OTP. It - contains functions that allow applications to use a single log - API and the system to manage those log events independently. Use - the <seealso marker="#emergency-1">API functions</seealso> or the log - <seealso marker="#macros">macros</seealso> to log events. For instance, - to log a new error event:</p> - <code> -?LOG_ERROR("error happened because: ~p",[Reason]). %% With macro -logger:error("error happened because: ~p",[Reason]). %% Without macro - </code> - <p>This log event is then sent to the configured log handlers which - by default means that it is be printed to the console. If you want - your systems logs to be printed to a file instead of the console you - must configure the default handler to do so. The simplest way is - to include the following in your <seealso marker="config"><c>sys.config</c></seealso>.</p> + <p>This module implements the main API for logging in + Erlang/OTP. To create a log event, use the + <seealso marker="#logging_API">API functions</seealso> or the + log + <seealso marker="#macros">macros</seealso>, for example:</p> + <code> +?LOG_ERROR("error happened because: ~p", [Reason]). % With macro +logger:error("error happened because: ~p", [Reason]). % Without macro + </code> + <p>To configure the Logger backend, + use <seealso marker="kernel_app#logger">Kernel configuration + parameters</seealso> + or <seealso marker="#configuration_API">configuration + functions</seealso> in the Logger API.</p> + + <p>By default, the Kernel application installs one log handler at + system start. This handler is named <c>default</c>. It receives + and processes standard log events produced by the Erlang runtime + system, standard behaviours and different Erlang/OTP + applications. The log events are by default printed to the + terminal.</p> + <p>If you want your systems logs to be printed to a file instead, + you must configure the default handler to do so. The simplest + way is to include the following in + your <seealso marker="config"><c>sys.config</c></seealso>:</p> <code> [{kernel, [{logger, - [{handler,default,logger_std_h, - #{logger_std_h=>#{type=>{file,"path/to/file.log"}}}}]}]}]. + [{handler, default, logger_std_h, + #{config => #{type => {file, "path/to/file.log"}}}}]}]}]. </code> <p> For more information about: </p> <list type="bulleted"> - <item>how to use the API, - see <seealso marker="logger_chapter">the User's Guide</seealso>.</item> - <item>how to configure Logger, - see the <seealso marker="logger_chapter#configuration">Configuration</seealso> + <item>the Logger facility in general, see + the <seealso marker="logger_chapter">User's + Guide</seealso>.</item> + <item>how to configure Logger, see + the <seealso marker="logger_chapter#configuration">Configuration</seealso> section in the User's Guide.</item> - <item>the convinience macros in logger.hrl, - see <seealso marker="#macros">the macro section</seealso>.</item> - <item>what the builtin formatter can do, - see <seealso marker="logger_formatter">logger_formatter</seealso>.</item> - <item>what the builtin handlers can do, + <item>the built-in handlers, see <seealso marker="logger_std_h">logger_std_h</seealso> and <seealso marker="logger_disk_log_h">logger_disk_log_h</seealso>.</item> - <item>what builtin filters are available, + <item>the built-in formatter, + see <seealso marker="logger_formatter">logger_formatter</seealso>.</item> + <item>built-in filters, see <seealso marker="logger_filters">logger_filters</seealso>.</item> </list> </description> <datatypes> <datatype> - <name name="level"/> + <name name="primary_config"/> <desc> - <p>The severity level for the message to be logged.</p> + <p>Primary configuration data for Logger. The following + default values apply:</p> + <list> + <item><c>level => info</c></item> + <item><c>filter_default => log</c></item> + <item><c>filters => []</c></item> + </list> </desc> </datatype> <datatype> - <name name="log_event"/> + <name name="handler_config"/> <desc> - <p></p> + <p>Handler configuration data for Logger. The following + default values apply:</p> + <list> + <item><c>level => all</c></item> + <item><c>filter_default => log</c></item> + <item><c>filters => []</c></item> + <item><c>formatter => {logger_formatter, DefaultFormatterConfig</c>}</item> + </list> + <p>In addition to these, the following fields are + automatically inserted by Logger, values taken from the + two first parameters + to <seealso marker="#add_handler-3"><c>add_handler/3</c></seealso>:</p> + <list> + <item><c>id => HandlerId</c></item> + <item><c>module => Module</c></item> + </list> + <p>Handler specific configuration data is inserted by the + handler callback itself, in a sub structure associated with + the field named <c>config</c>.</p> + <p>See the <seealso marker="logger_formatter#type-config"> + <c>logger_formatter(3)</c></seealso> manual page for + information about the default configuration for this + formatter.</p> </desc> </datatype> <datatype> - <name name="report"/> + <name name="filter"/> <desc> - <p></p> + <p>A filter which can be installed as a handler filter, or as + a primary filter in Logger.</p> </desc> </datatype> <datatype> - <name name="msg_fun"/> + <name name="filter_arg"/> + <desc> + <p>The second argument to the filter fun.</p> + </desc> + </datatype> + <datatype> + <name name="filter_id"/> + <desc> + <p>A unique identifier for a filter.</p> + </desc> + </datatype> + <datatype> + <name name="filter_return"/> + <desc> + <p>The return value from the filter fun.</p> + </desc> + </datatype> + <datatype> + <name name="formatter_config"/> + <desc> + <p>Configuration data for the + formatter. See <seealso marker="logger_formatter"> + <c>logger_formatter(3)</c></seealso> + for an example of a formatter implementation.</p> + </desc> + </datatype> + <datatype> + <name name="handler_id"/> + <desc> + <p>A unique identifier for a handler instance.</p> + </desc> + </datatype> + <datatype> + <name name="level"/> + <desc> + <p>The severity level for the message to be logged.</p> + </desc> + </datatype> + <datatype> + <name name="log_event"/> <desc> <p></p> </desc> @@ -117,7 +194,7 @@ logger:error("error happened because: ~p",[Reason]). %% Without macro <p>When a log macro is used, Logger also inserts location information:</p> <list> - <item><c>mfa => {?MODULE,?FUNCTION_NAME,?FUNCTION_ARITY}</c></item> + <item><c>mfa => {?MODULE, ?FUNCTION_NAME, ?FUNCTION_ARITY}</c></item> <item><c>file => ?FILE</c></item> <item><c>line => ?LINE</c></item> </list> @@ -158,51 +235,15 @@ logger:error("error happened because: ~p",[Reason]). %% Without macro </desc> </datatype> <datatype> - <name name="config"/> - <desc> - <p>Configuration data for the logger part of Logger, or for a handler.</p> - <p>The following default values apply:</p> - <list> - <item><c>level => info</c></item> - <item><c>filter_default => log</c></item> - <item><c>filters => []</c></item> - <item><c>formatter => {logger_formatter,DefaultFormatterConfig</c>}</item> - </list> - <p>See the <seealso marker="logger_formatter#type-config"> - <c>logger_formatter(3)</c></seealso> manual page for - information about the default configuration for this - formatter.</p> - </desc> - </datatype> - <datatype> - <name name="handler_id"/> - <desc> - <p>A unique identifier for a handler instance.</p> - </desc> - </datatype> - <datatype> - <name name="filter_id"/> - <desc> - <p>A unique identifier for a filter.</p> - </desc> - </datatype> - <datatype> - <name name="filter"/> - <desc> - <p>A filter which can be installed for the logger part of - Logger, or for a handler.</p> - </desc> - </datatype> - <datatype> - <name name="filter_arg"/> + <name name="msg_fun"/> <desc> - <p>The second argument to the filter fun.</p> + <p></p> </desc> </datatype> <datatype> - <name name="filter_return"/> + <name name="report"/> <desc> - <p>The return value from the filter fun.</p> + <p></p> </desc> </datatype> <datatype> @@ -213,15 +254,6 @@ logger:error("error happened because: ~p",[Reason]). %% Without macro <c>erlang:system_time(microsecond)</c></seealso>.</p> </desc> </datatype> - <datatype> - <name name="formatter_config"/> - <desc> - <p>Configuration data for the - formatter. See <seealso marker="logger_formatter"> - <c>logger_formatter(3)</c></seealso> - for an example of a formatter implementation.</p> - </desc> - </datatype> </datatypes> <section> @@ -258,6 +290,10 @@ logger:error("error happened because: ~p",[Reason]). %% Without macro level.</p> </section> + <section> + <marker id="logging_API"/> + <title>Logging API functions</title> + </section> <funcs> <func> <name>emergency(StringOrReport[,Metadata])</name> @@ -317,7 +353,7 @@ logger:error("error happened because: ~p",[Reason]). %% Without macro <func> <name>notice(StringOrReport[,Metadata])</name> <name>notice(Format,Args[,Metadata])</name> - <name>notice(Fun,FunArgs[,Metadata])</name> + <name>notice(Fun,FunArgs[,Metadata])</name> <fsummary>Logs the given message as level <c>notice</c>.</fsummary> <desc> <p>Equivalent to @@ -366,136 +402,21 @@ logger:error("error happened because: ~p",[Reason]). %% Without macro <p>Log the given message.</p> </desc> </func> + </funcs> + <section> + <marker id="configuration_API"/> + <title>Configuration API functions</title> + </section> + <funcs> <func> - <name name="get_logger_config" arity="0"/> - <fsummary>Look up the current configuration for the logger part - of Logger.</fsummary> - <desc> - <p>Look up the current configuration for the logger part of - Logger.</p> - </desc> - </func> - - <func> - <name name="get_handler_config" arity="1"/> - <fsummary>Look up the current configuration for the given - handler.</fsummary> - <desc> - <p>Look up the current configuration for the given handler.</p> - </desc> - </func> - - <func> - <name name="i" arity="0"/> - <fsummary>Get all Logger configurations</fsummary> - <desc> - <p>Same as <seealso marker="#i/1"><c>logger:i(term)</c></seealso></p> - </desc> - </func> - - <func> - <name name="i" arity="1" clause_i="1"/> - <name name="i" arity="1" clause_i="2"/> - <name name="i" arity="1" clause_i="3"/> - <fsummary>Get all Logger configurations</fsummary> - <desc> - <p>Display or return all current Logger configurations.</p> - <taglist> - <tag><c><anno>Action</anno> = string</c></tag> - <item> - <p>Return the pretty printed current Logger configuration - as iodata.</p> - </item> - <tag><c><anno>Action</anno> = term</c></tag> - <item> - <p>Return the current Logger configuration as a term. The - format of this term may change between releases. For a - stable format use <seealso marker="#get_handler_config/1"> - <c>logger:get_handler_config/1</c></seealso> - and <seealso marker="#get_logger_config/0"> - <c>logger:get_logger_config/0</c></seealso>.</p> - <p>The same as calling <c>logger:i()</c>.</p> - </item> - <tag><c><anno>Action</anno> = print</c></tag> - <item> - <p>Pretty print all the current Logger configuration to - standard out. Example:</p> - <code><![CDATA[1> logger:i(print). -Current logger configuration: - Level: info - Filter Default: log - Filters: - Handlers: - Id: default - Module: logger_std_h - Level: info - Formatter: - Module: logger_formatter - Config: #{legacy_header => true,single_line => false, - template => [{logger_formatter,header},"\n",msg,"\n"]} - Filter Default: stop - Filters: - Id: stop_progress - Fun: fun logger_filters:progress/2 - Config: stop - Id: remote_gl - Fun: fun logger_filters:remote_gl/2 - Config: stop - Id: domain - Fun: fun logger_filters:domain/2 - Config: {log,super,[beam,erlang,otp,sasl]} - Id: no_domain - Fun: fun logger_filters:domain/2 - Config: {log,undefined,[]} - Handler Config: - logger_std_h: #{type => standard_io} - Level set per module: - Module: my_module - Level: debug]]></code> - </item> - </taglist> - </desc> - </func> - - <func> - <name name="add_logger_filter" arity="2"/> - <fsummary>Add a filter to the logger part of Logger.</fsummary> + <name name="add_handler" arity="3"/> + <fsummary>Add a handler with the given configuration.</fsummary> <desc> - <p>Add a filter to the logger part of Logger.</p> - <p>The filter fun is called with the log event as the first - parameter, and the specified <c>filter_args()</c> as the - second parameter.</p> - <p>The return value of the fun specifies if a log event is to - be discarded or forwarded to the handlers:</p> - <taglist> - <tag><c>log_event()</c></tag> - <item> - <p>The filter <em>passed</em>. The next logger filter, if - any, is applied. If no more logger filters exist, the - log event is forwarded to the handler part of Logger, - where handler filters are applied.</p> - </item> - <tag><c>stop</c></tag> - <item> - <p>The filter <em>did not pass</em>, and the log event is - immediately discarded.</p> - </item> - <tag><c>ignore</c></tag> - <item> - <p>The filter has no knowledge of the log event. The next - logger filter, if any, is applied. If no more logger - filters exist, the value of the <c>filter_default</c> - configuration parameter for the logger part specifies if - the log event shall be discarded or forwarded to the - handler part.</p> - </item> - </taglist> - <p>See section <seealso marker="logger_chapter#filters"> - Filters</seealso> in the User's Guide for more information - about filters.</p> - <p>Some built-in filters exist. These are defined - in <seealso marker="logger_filters"><c>logger_filters</c></seealso>.</p> + <p>Add a handler with the given configuration.</p> + <p><c><anno>HandlerId</anno></c> is a unique identifier which + must be used in all subsequent calls referring to this + handler.</p> </desc> </func> @@ -541,98 +462,12 @@ Current logger configuration: </func> <func> - <name name="remove_logger_filter" arity="1"/> - <fsummary>Remove a filter from the logger part of Logger.</fsummary> - <desc> - <p>Remove the filter identified - by <c><anno>FilterId</anno></c> from the logger part of Logger.</p> - </desc> - </func> - - <func> - <name name="remove_handler_filter" arity="2"/> - <fsummary>Remove a filter from the specified handler.</fsummary> - <desc> - <p>Remove the filter identified - by <c><anno>FilterId</anno></c> from the handler identified - by <c><anno>HandlerId</anno></c>.</p> - </desc> - </func> - - <func> - <name name="add_handler" arity="3"/> - <fsummary>Add a handler with the given configuration.</fsummary> - <desc> - <p>Add a handler with the given configuration.</p> - <p><c><anno>HandlerId</anno></c> is a unique identifier which - must be used in all subsequent calls referring to this - handler.</p> - </desc> - </func> - - <func> - <name name="remove_handler" arity="1"/> - <fsummary>Remove the handler with the specified identity.</fsummary> - <desc> - <p>Remove the handler identified by <c><anno>HandlerId</anno></c>.</p> - </desc> - </func> - - <func> - <name name="set_module_level" arity="2"/> - <fsummary>Set the log level for the specified module.</fsummary> - <desc> - <p>Set the log level for the - specified <c><anno>Module</anno></c>.</p> - <p>The log level for a module overrides the global log level - of Logger for log events originating from the module in - question. Notice, however, that it does not override the - level configuration for any handler.</p> - <p>For example: Assume that the global log level for Logger - is <c>info</c>, and there is one handler, <c>h1</c>, with - level <c>info</c> and one handler, <c>h2</c>, with - level <c>debug</c>.</p> - <p>With this configuration, no debug messages will be logged, - since they are all stopped by the global log level.</p> - <p>If the level for <c>mymodule</c> is now set - to <c>debug</c>, then debug events from this module will be - logged by the handler <c>h2</c>, but not by - handler <c>h1</c>.</p> - <p>Debug events from other modules are still not logged.</p> - <p>To change the global log level for Logger, use - <seealso marker="#set_logger_config/2"> - <c>logger:set_logger_config(level,Level)</c></seealso>.</p> - <p>To change the log level for a handler, use - <seealso marker="#set_handler_config/3"> - <c>logger:set_handler_config(HandlerId,level,Level)</c></seealso>.</p> - <note> - <p>The originating module for a log event is only detected - if <c>mfa=>{Module,Function,Arity}</c> exists in the - metadata. When log macros are used, this association is - automatically added to all log events. If an API function - is called directly, without using a macro, the logging - client must explicitly add this information if module - levels shall have any effect.</p> - </note> - </desc> - </func> - - <func> - <name name="unset_module_level" arity="1"/> - <fsummary>Remove a module specific log setting.</fsummary> - <desc> - <p>Remove a module specific log setting. After this, the - global log level is used for the specified module.</p> - </desc> - </func> - - <func> <name name="add_handlers" arity="1" clause_i="1"/> <fsummary>Set up log handlers from the application's configuration parameters.</fsummary> <desc> <p>Reads the application configuration parameter <c>logger</c> and - calls <c>logger:add_handlers/1</c> with its contents.</p> + calls <c>add_handlers/1</c> with its contents.</p> </desc> </func> @@ -670,61 +505,158 @@ start(_, []) -> [{kernel, [{logger, %% Disable the default Kernel handler - [{handler,default,undefined}]}]}, + [{handler, default, undefined}]}]}, {my_app, [{logger, %% Enable this handler as the default - [{handler,default,my_handler,#{}}]}]}]. + [{handler, default, my_handler, #{}}]}]}]. </code> </desc> </func> <func> - <name name="set_logger_config" arity="1"/> - <fsummary>Set configuration data for the logger part of Logger.</fsummary> + <name name="add_primary_filter" arity="2"/> + <fsummary>Add a primary filter to Logger.</fsummary> <desc> - <p>Set configuration data for the logger part of Logger. This - overwrites the current logger configuration.</p> - <p>To modify the existing configuration, - use <seealso marker="#update_logger_config-1"> - <c>update_logger_config/1</c></seealso>, or, if a more - complex merge is needed, read the current configuration - with <seealso marker="#get_logger_config-0"><c>get_logger_config/0</c> - </seealso>, then do the merge before writing the new - configuration back with this function.</p> - <p>If a key is removed compared to the current configuration, - the default value is used.</p> + <p>Add a primary filter to Logger.</p> + <p>The filter fun is called with the log event as the first + parameter, and the specified <c>filter_args()</c> as the + second parameter.</p> + <p>The return value of the fun specifies if a log event is to + be discarded or forwarded to the handlers:</p> + <taglist> + <tag><c>log_event()</c></tag> + <item> + <p>The filter <em>passed</em>. The next primary filter, if + any, is applied. If no more primary filters exist, the + log event is forwarded to the handler part of Logger, + where handler filters are applied.</p> + </item> + <tag><c>stop</c></tag> + <item> + <p>The filter <em>did not pass</em>, and the log event is + immediately discarded.</p> + </item> + <tag><c>ignore</c></tag> + <item> + <p>The filter has no knowledge of the log event. The next + primary filter, if any, is applied. If no more primary + filters exist, the value of the + primary <c>filter_default</c> configuration parameter + specifies if the log event shall be discarded or + forwarded to the handler part.</p> + </item> + </taglist> + <p>See section <seealso marker="logger_chapter#filters"> + Filters</seealso> in the User's Guide for more information + about filters.</p> + <p>Some built-in filters exist. These are defined + in <seealso marker="logger_filters"><c>logger_filters</c></seealso>.</p> </desc> </func> <func> - <name name="set_logger_config" arity="2"/> - <fsummary>Add or update configuration data for the logger part - of Logger.</fsummary> + <name name="get_config" arity="0"/> + <fsummary>Look up the current Logger configuration</fsummary> <desc> - <p>Add or update configuration data for the logger part of - Logger. If the given <c><anno>Key</anno></c> already exists, - its associated value will be changed - to <c><anno>Value</anno></c>. If it does not exist, it will - be added.</p> + <p>Look up all current Logger configuration, including primary + and handler configuration, and module level settings.</p> </desc> </func> <func> - <name name="update_logger_config" arity="1"/> - <fsummary>Update configuration data for the logger part of - Logger.</fsummary> + <name name="get_handler_config" arity="0"/> + <fsummary>Look up the current configuration for all handlers.</fsummary> <desc> - <p>Update configuration data for the logger part of - Logger. This function behaves as if it was implemented as - follows:</p> - <code type="erl"> -{ok,Old} = logger:get_logger_config(), -logger:set_logger_config(maps:merge(Old,Config)). - </code> - <p>To overwrite the existing configuration without any merge, - use <seealso marker="#set_logger_config-1"><c>set_logger_config/1</c> - </seealso>.</p> + <p>Look up the current configuration for all handlers.</p> + </desc> + </func> + + <func> + <name name="get_handler_config" arity="1"/> + <fsummary>Look up the current configuration for the given + handler.</fsummary> + <desc> + <p>Look up the current configuration for the given handler.</p> + </desc> + </func> + + <func> + <name name="get_handler_ids" arity="0"/> + <fsummary>Look up the identities for all installed handlers.</fsummary> + <desc> + <p>Look up the identities for all installed handlers.</p> + </desc> + </func> + + <func> + <name name="get_primary_config" arity="0"/> + <fsummary>Look up the current primary configuration for Logger.</fsummary> + <desc> + <p>Look up the current primary configuration for Logger.</p> + </desc> + </func> + + <func> + <name name="get_module_level" arity="0"/> + <fsummary>Look up all current module levels.</fsummary> + <desc> + <p>Look up all current module levels. Returns a list + containing one <c>{Module,Level}</c> element for each module + for which the module level was previously set + with <seealso marker="#set_module_level-2"> + <c>set_module_level/2</c></seealso>.</p> + </desc> + </func> + + <func> + <name name="get_module_level" arity="1"/> + <fsummary>Look up the current level for the given modules.</fsummary> + <desc> + <p>Look up the current level for the given modules. Returns a + list containing one <c>{Module,Level}</c> element for each + of the given modules for which the module level was + previously set with <seealso marker="#set_module_level-2"> + <c>set_module_level/2</c></seealso>.</p> + </desc> + </func> + + <func> + <name name="get_process_metadata" arity="0"/> + <fsummary>Retrieve data set with set_process_metadata/1.</fsummary> + <desc> + <p>Retrieve data set + with <seealso marker="#set_process_metadata-1"> + <c>set_process_metadata/1</c></seealso> or + <seealso marker="#update_process_metadata-1"> + <c>update_process_metadata/1</c></seealso>.</p> + </desc> + </func> + + <func> + <name name="remove_handler" arity="1"/> + <fsummary>Remove the handler with the specified identity.</fsummary> + <desc> + <p>Remove the handler identified by <c><anno>HandlerId</anno></c>.</p> + </desc> + </func> + + <func> + <name name="remove_handler_filter" arity="2"/> + <fsummary>Remove a filter from the specified handler.</fsummary> + <desc> + <p>Remove the filter identified + by <c><anno>FilterId</anno></c> from the handler identified + by <c><anno>HandlerId</anno></c>.</p> + </desc> + </func> + + <func> + <name name="remove_primary_filter" arity="1"/> + <fsummary>Remove a primary filter from Logger.</fsummary> + <desc> + <p>Remove the primary filter identified + by <c><anno>FilterId</anno></c> from Logger.</p> </desc> </func> @@ -763,18 +695,122 @@ logger:set_logger_config(maps:merge(Old,Config)). </func> <func> - <name name="update_handler_config" arity="2"/> - <fsummary>Update configuration data for the specified handler.</fsummary> + <name name="set_primary_config" arity="1"/> + <fsummary>Set primary configuration data for Logger.</fsummary> <desc> - <p>Update configuration data for the specified handler. This function - behaves as if it was implemented as follows:</p> - <code type="erl"> -{ok,{_,Old}} = logger:get_handler_config(HandlerId), -logger:set_handler_config(HandlerId,maps:merge(Old,Config)). - </code> - <p>To overwrite the existing configuration without any merge, - use <seealso marker="#set_handler_config-2"><c>set_handler_config/2</c> + <p>Set primary configuration data for Logger. This + overwrites the current configuration.</p> + <p>To modify the existing configuration, + use <seealso marker="#update_primary_config-1"> + <c>update_primary_config/1</c></seealso>, or, if a more + complex merge is needed, read the current configuration + with <seealso marker="#get_primary_config-0"><c>get_primary_config/0</c> + </seealso>, then do the merge before writing the new + configuration back with this function.</p> + <p>If a key is removed compared to the current configuration, + the default value is used.</p> + </desc> + </func> + + <func> + <name name="set_primary_config" arity="2"/> + <fsummary>Add or update primary configuration data for Logger.</fsummary> + <desc> + <p>Add or update primary configuration data for Logger. If the + given <c><anno>Key</anno></c> already exists, its associated + value will be changed to <c><anno>Value</anno></c>. If it + does not exist, it will be added.</p> + </desc> + </func> + + <func> + <name name="set_module_level" arity="2"/> + <fsummary>Set the log level for the specified modules.</fsummary> + <desc> + <p>Set the log level for the + specified modules.</p> + <p>The log level for a module overrides the primary log level + of Logger for log events originating from the module in + question. Notice, however, that it does not override the + level configuration for any handler.</p> + <p>For example: Assume that the primary log level for Logger + is <c>info</c>, and there is one handler, <c>h1</c>, with + level <c>info</c> and one handler, <c>h2</c>, with + level <c>debug</c>.</p> + <p>With this configuration, no debug messages will be logged, + since they are all stopped by the primary log level.</p> + <p>If the level for <c>mymodule</c> is now set + to <c>debug</c>, then debug events from this module will be + logged by the handler <c>h2</c>, but not by + handler <c>h1</c>.</p> + <p>Debug events from other modules are still not logged.</p> + <p>To change the primary log level for Logger, use + <seealso marker="#set_primary_config/2"> + <c>set_primary_config(level, Level)</c></seealso>.</p> + <p>To change the log level for a handler, use + <seealso marker="#set_handler_config/3"> + <c>set_handler_config(HandlerId, level, Level)</c> </seealso>.</p> + <note> + <p>The originating module for a log event is only detected + if the key <c>mfa</c> exists in the metadata, and is + associated with <c>{Module, Function, Arity}</c>. When log + macros are used, this association is automatically added + to all log events. If an API function is called directly, + without using a macro, the logging client must explicitly + add this information if module levels shall have any + effect.</p> + </note> + </desc> + </func> + + <func> + <name name="set_process_metadata" arity="1"/> + <fsummary>Set metadata to use when logging from current process.</fsummary> + <desc> + <p>Set metadata which Logger shall automatically insert in + all log events produced on the current process.</p> + <p>Location data produced by the log macros, and/or metadata + given as argument to the log call (API function or macro), + are merged with the process metadata. If the same keys + occur, values from the metadata argument to the log call + overwrite values from the process metadata, which in turn + overwrite values from the location data.</p> + <p>Subsequent calls to this function overwrites previous data + set. To update existing data instead of overwriting it, + see <seealso marker="#update_process_metadata-1"> + <c>update_process_metadata/1</c></seealso>.</p> + </desc> + </func> + + <func> + <name name="unset_module_level" arity="0"/> + <fsummary>Remove module specific log settings for all modules.</fsummary> + <desc> + <p>Remove module specific log settings. After this, the + primary log level is used for all modules.</p> + </desc> + </func> + + <func> + <name name="unset_module_level" arity="1"/> + <fsummary>Remove module specific log settings for the given + modules.</fsummary> + <desc> + <p>Remove module specific log settings. After this, the + primary log level is used for the specified modules.</p> + </desc> + </func> + + <func> + <name name="unset_process_metadata" arity="0"/> + <fsummary>Delete data set with set_process_metadata/1.</fsummary> + <desc> + <p>Delete data set + with <seealso marker="#set_process_metadata-1"> + <c>set_process_metadata/1</c></seealso> or + <seealso marker="#update_process_metadata-1"> + <c>update_process_metadata/1</c></seealso>.</p> </desc> </func> @@ -786,9 +822,10 @@ logger:set_handler_config(HandlerId,maps:merge(Old,Config)). <p>The new configuration is merged with the existing formatter configuration.</p> <p>To overwrite the existing configuration without any merge, - use <seealso marker="#set_handler_config-3"> - <c>set_handler_config(HandlerId,formatter, - {FormatterModule,FormatterConfig})</c></seealso>.</p> + use</p> + <pre> +<seealso marker="#set_handler_config-3">set_handler_config(HandlerId, formatter, + {FormatterModule, FormatterConfig})</seealso>.</pre> </desc> </func> @@ -797,39 +834,41 @@ logger:set_handler_config(HandlerId,maps:merge(Old,Config)). <fsummary>Update the formatter configuration for the specified handler.</fsummary> <desc> <p>Update the formatter configuration for the specified handler.</p> - <p>This is equivalent - to <br/><seealso marker="#update_formatter_config-2"> - <c>update_formatter_config(<anno>HandlerId</anno>,#{<anno>Key</anno>=><anno>Value</anno>})</c></seealso></p> + <p>This is equivalent to</p> + <pre> +<seealso marker="#update_formatter_config-2">update_formatter_config(<anno>HandlerId</anno>, #{<anno>Key</anno> => <anno>Value</anno>})</seealso></pre> </desc> </func> <func> - <name name="compare_levels" arity="2"/> - <fsummary>Compare the severity of two log levels.</fsummary> + <name name="update_handler_config" arity="2"/> + <fsummary>Update configuration data for the specified handler.</fsummary> <desc> - <p>Compare the severity of two log levels. Returns <c>gt</c> - if <c>Level1</c> is more severe than - <c>Level2</c>, <c>lt</c> if <c>Level1</c> is less severe, - and <c>eq</c> if the levels are equal.</p> + <p>Update configuration data for the specified handler. This function + behaves as if it was implemented as follows:</p> + <code type="erl"> +{ok, {_, Old}} = logger:get_handler_config(HandlerId), +logger:set_handler_config(HandlerId, maps:merge(Old, Config)). + </code> + <p>To overwrite the existing configuration without any merge, + use <seealso marker="#set_handler_config-2"><c>set_handler_config/2</c> + </seealso>.</p> </desc> </func> <func> - <name name="set_process_metadata" arity="1"/> - <fsummary>Set metadata to use when logging from current process.</fsummary> + <name name="update_primary_config" arity="1"/> + <fsummary>Update primary configuration data for Logger.</fsummary> <desc> - <p>Set metadata which Logger shall automatically insert in - all log events produced on the current process.</p> - <p>Location data produced by the log macros, and/or metadata - given as argument to the log call (API function or macro), - are merged with the process metadata. If the same keys - occur, values from the metadata argument to the log call - overwrite values from the process metadata, which in turn - overwrite values from the location data.</p> - <p>Subsequent calls to this function overwrites previous data - set. To update existing data instead of overwriting it, - see <seealso marker="#update_process_metadata-1"> - <c>update_process_metadata/1</c></seealso>.</p> + <p>Update primary configuration data for Logger. This function + behaves as if it was implemented as follows:</p> + <code type="erl"> +Old = logger:get_primary_config(), +logger:set_primary_config(maps:merge(Old, Config)). + </code> + <p>To overwrite the existing configuration without any merge, + use <seealso marker="#set_primary_config-1"><c>set_primary_config/1</c> + </seealso>.</p> </desc> </func> @@ -843,7 +882,7 @@ logger:set_handler_config(HandlerId,maps:merge(Old,Config)). <p>If process metadata exists for the current process, this function behaves as if it was implemented as follows:</p> <code type="erl"> -logger:set_process_metadata(maps:merge(logger:get_process_metadata(),Meta)). +logger:set_process_metadata(maps:merge(logger:get_process_metadata(), Meta)). </code> <p>If no process metadata exists, the function behaves as <seealso marker="#set_process_metadata-1"> @@ -851,48 +890,44 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(),Meta)). </seealso>.</p> </desc> </func> + </funcs> + <section> + <marker id="misc_API"/> + <title>Miscellaneous API functions</title> + </section> + <funcs> <func> - <name name="get_process_metadata" arity="0"/> - <fsummary>Retrieve data set with set_process_metadata/1.</fsummary> - <desc> - <p>Retrieve data set - with <seealso marker="#set_process_metadata-1"> - <c>set_process_metadata/1</c></seealso> or - <seealso marker="#update_process_metadata-1"> - <c>update_process_metadata/1</c></seealso>.</p> - </desc> - </func> - - <func> - <name name="unset_process_metadata" arity="0"/> - <fsummary>Delete data set with set_process_metadata/1.</fsummary> + <name name="compare_levels" arity="2"/> + <fsummary>Compare the severity of two log levels.</fsummary> <desc> - <p>Delete data set - with <seealso marker="#set_process_metadata-1"> - <c>set_process_metadata/1</c></seealso> or - <seealso marker="#update_process_metadata-1"> - <c>update_process_metadata/1</c></seealso>.</p> + <p>Compare the severity of two log levels. Returns <c>gt</c> + if <c>Level1</c> is more severe than + <c>Level2</c>, <c>lt</c> if <c>Level1</c> is less severe, + and <c>eq</c> if the levels are equal.</p> </desc> </func> <func> <name name="format_report" arity="1"/> - <fsummary>Convert a log message on report form to {Format,Args}.</fsummary> + <fsummary>Convert a log message on report form to {Format, Args}.</fsummary> <desc> - <p>Convert a log message on report form to <c>{Format,Args}</c>.</p> - <p>This is the default report callback used + <p>Convert a log message on report form to <c>{Format, + Args}</c>. This is the default report callback used by <seealso marker="logger_formatter"> <c>logger_formatter</c></seealso> when no custom report - callback is found.</p> + callback is found. See + section <seealso marker="logger_chapter#log_message">Log + Message</seealso> in the Kernel User's Guide for + information about report callbacks and valid forms of log + messages.</p> <p>The function produces lines of <c>Key: Value</c> from key-value lists. Strings are printed with <c>~ts</c> and other terms with <c>~tp</c>.</p> - <p>If the <c><anno>Report</anno></c> is a map, it is - converted to a key-value list before formatting as such.</p> + <p>If <c><anno>Report</anno></c> is a map, it is converted to + a key-value list before formatting as such.</p> </desc> </func> - </funcs> <section> @@ -904,11 +939,11 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(),Meta)). <funcs> <func> - <name>HModule:adding_handler(Config1) -> {ok,Config2} | {error,Reason}</name> + <name>HModule:adding_handler(Config1) -> {ok, Config2} | {error, Reason}</name> <fsummary>An instance of this handler is about to be added.</fsummary> <type> <v>Config1 = Config2 = - <seealso marker="#type-config">config()</seealso></v> + <seealso marker="#type-handler_config">handler_config()</seealso></v> <v>Reason = term()</v> </type> <desc> @@ -928,11 +963,11 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(),Meta)). </func> <func> - <name>HModule:changing_config(Config1,Config2) -> {ok,Config3} | {error,Reason}</name> + <name>HModule:changing_config(Config1, Config2) -> {ok, Config3} | {error, Reason}</name> <fsummary>The configuration for this handler is about to change.</fsummary> <type> <v>Config1 = Config2 = Config3 = - <seealso marker="#type-config">config()</seealso></v> + <seealso marker="#type-handler_config">handler_config()</seealso></v> <v>Reason = term()</v> </type> <desc> @@ -952,17 +987,17 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(),Meta)). </func> <func> - <name>HModule:log(LogEvent,Config) -> void()</name> + <name>HModule:log(LogEvent, Config) -> void()</name> <fsummary>Log the given log event.</fsummary> <type> <v>LogEvent = <seealso marker="#type-log_event">log_event()</seealso></v> <v>Config = - <seealso marker="#type-config">config()</seealso></v> + <seealso marker="#type-handler_config">handler_config()</seealso></v> </type> <desc> <p>This callback function is mandatory.</p> - <p>The function is called when all global filters and all + <p>The function is called when all primary filters and all handler filters for the handler in question have passed for the given log event.</p> <p>The handler identity is associated with the <c>id</c> key @@ -978,7 +1013,7 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(),Meta)). <fsummary>The given handler is about to be removed.</fsummary> <type> <v>Config = - <seealso marker="#type-config">config()</seealso></v> + <seealso marker="#type-handler_config">handler_config()</seealso></v> </type> <desc> <p>This callback function is optional.</p> @@ -1002,18 +1037,30 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(),Meta)). <funcs> <func> - <name>FModule:check_config(FConfig) -> ok | {error,term()}</name> + <name>FModule:check_config(FConfig) -> ok | {error, Reason}</name> <fsummary>Validate the given formatter configuration.</fsummary> <type> <v>FConfig = <seealso marker="#type-formatter_config">formatter_config()</seealso></v> + <v>Reason = term()</v> </type> <desc> <p>This callback function is optional.</p> <p>The function is called by a Logger when formatter configuration is set or modified. The formatter must validate the given configuration and return <c>ok</c> if it - is correct, and <c>{error,term()}</c> if it is faulty.</p> + is correct, and <c>{error,Reason}</c> if it is faulty.</p> + <p>The following Logger API functions can trigger this callback:</p> + <list> + <item><seealso marker="logger#add_handler-3"> + <c>logger:add_handler/3</c></seealso></item> + <item><seealso marker="logger#set_handler_config-2"> + <c>logger:set_handler_config/2,3</c></seealso></item> + <item><seealso marker="logger#update_handler_config-2"> + <c>logger:updata_handler_config/2</c></seealso></item> + <item><seealso marker="logger#update_formatter_config-2"> + <c>logger:update_formatter_config/2</c></seealso></item> + </list> <p>See <seealso marker="logger_formatter"> <c>logger_formatter(3)</c></seealso> for an example implementation. <c>logger_formatter</c> is the @@ -1021,7 +1068,7 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(),Meta)). </desc> </func> <func> - <name>FModule:format(LogEvent,FConfig) -> FormattedLogEntry</name> + <name>FModule:format(LogEvent, FConfig) -> FormattedLogEntry</name> <fsummary>Format the given log event.</fsummary> <type> <v>LogEvent = @@ -1045,6 +1092,20 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(),Meta)). </desc> </func> </funcs> + + <section> + <title>See Also</title> + <p> + <seealso marker="config"><c>config(4)</c></seealso>, + <seealso marker="erts:erlang"><c>erlang(3)</c></seealso>, + <seealso marker="stdlib:io"><c>io(3)</c></seealso>, + <seealso marker="logger_disk_log_h"><c>logger_disk_log_h(3)</c></seealso>, + <seealso marker="logger_filters"><c>logger_filters(3)</c></seealso>, + <seealso marker="logger_formatter"><c>logger_formatter(3)</c></seealso>, + <seealso marker="logger_std_h"><c>logger_std_h(3)</c></seealso>, + <seealso marker="stdlib:unicode"><c>unicode(3)</c></seealso> + </p> + </section> </erlref> diff --git a/lib/kernel/doc/src/logger_arch.png b/lib/kernel/doc/src/logger_arch.png Binary files differindex 901122193a..a9b9a658b4 100644 --- a/lib/kernel/doc/src/logger_arch.png +++ b/lib/kernel/doc/src/logger_arch.png diff --git a/lib/kernel/doc/src/logger_chapter.xml b/lib/kernel/doc/src/logger_chapter.xml index a3eec7bd4b..f7df0a3e6e 100644 --- a/lib/kernel/doc/src/logger_chapter.xml +++ b/lib/kernel/doc/src/logger_chapter.xml @@ -30,7 +30,7 @@ <file>logger_chapter.xml</file> </header> - <p>Erlang/OTP 21.0 provides a new standard API for logging + <p>Erlang/OTP 21.0 provides a standard API for logging through <c>Logger</c>, which is part of the Kernel application. Logger consists of the API for issuing log events, and a customizable backend where log handlers, filters and @@ -44,7 +44,7 @@ <p>You can also configure the system so that the default handler prints log events to a single file, or to a set of wrap logs via <seealso marker="disk_log"><c>disk_log</c></seealso>.</p> - <p>By confiugration, you can aslo modify or disable the default + <p>By configuration, you can also modify or disable the default handler, replace it by a custom handler, and install additional handlers.</p> @@ -53,11 +53,12 @@ <p>A <em>log event</em> consists of a <em>log level</em>, the <em>message</em> to be logged, and <em>metadata</em>.</p> <p>The Logger backend forwards log events from the API, first - through a set of <em>global filters</em>, then through a set - of <em>handler filters</em> for each log handler.</p> + through a set of <em>primary filters</em>, then through a set of + secondary filters attached to each log handler. The secondary + filters are in the following named <em>handler filters</em>.</p> <p>Each filter set consists of a <em>log level check</em>, followed by zero or more <em>filter functions</em>.</p> - <p>The following figure show a conseptual overview of Logger. The + <p>The following figure shows a conceptual overview of Logger. The figure shows two log handlers, but any number of handlers can be installed.</p> @@ -69,11 +70,11 @@ atoms are mapped to integer values, and a log event passes the log level check if the integer value of its log level is less than or equal to the currently configured log level. That is, - the check pases if the event is equally or more severe than the + the check passes if the event is equally or more severe than the configured level. See section <seealso marker="#log_level">Log Level</seealso> for a listing and description of all log levels.</p> - <p>The global log level can be overridden by a log level + <p>The primary log level can be overridden by a log level configured per module. This is to, for instance, allow more verbose logging from a specific part of the system.</p> <p>Filter functions can be used for more sophisticated filtering @@ -82,7 +83,7 @@ also modify all parts of the log event. See see section <seealso marker="#filters">Filters</seealso> for more details.</p> - <p>If a log event passes through all global filters and all + <p>If a log event passes through all primary filters and all handler filters for a specific handler, Logger forwards the event to the handler callback. The handler formats and prints the event to its destination. See @@ -107,7 +108,7 @@ functions is that macros add location (originator) information to the metadata, and performs lazy evaluation by wrapping the logger call in a case statement, so it is only evaluated if the - log level of the event passes the global log level check.</p> + log level of the event passes the primary log level check.</p> <section> <marker id="log_level"/> <title>Log Level</title> @@ -136,7 +137,7 @@ <row> <cell>critical</cell> <cell align="center">2</cell> - <cell>critical contidions</cell> + <cell>critical conditions</cell> </row> <row> <cell>error</cell> @@ -178,9 +179,9 @@ message can consist of a format string and arguments (given as two separate parameters in the Logger API), a string or a report. The latter, which is either a map or a key-value list, - can be accompanied by a report callback specified in the log - event's <seealso marker="#metadata">metadata</seealso>. The - report callback is a convenience function that + can be accompanied by a <em>report callback</em> specified in + the log event's <seealso marker="#metadata">metadata</seealso>. + The report callback is a convenience function that the <seealso marker="#formatters">formatter</seealso> can use to convert the report to a format string and arguments. The formatter can also use its own conversion function, if no @@ -195,7 +196,7 @@ logger:debug(#{got => connection_request, id => Id, state => State}, #{report_cb => fun(R) -> {"~p",[R]} end})</code> <p>The log message can also be provided through a fun for lazy - evaluation. The fun is only evaluated if the global log level + evaluation. The fun is only evaluated if the primary log level check passes, and is therefore recommended if it is expensive to generate the message. The lazy fun must return a string, a report, or a tuple with format string and arguments.</p> @@ -217,9 +218,9 @@ logger:debug(#{got => connection_request, id => Id, state => State}, which these calls are made, and Logger adds the metadata to all log events issued on that process.</p> </item> - <tag>Add metadata to a specifc log event</tag> + <tag>Add metadata to a specific log event</tag> <item> - <p>Metadata associated with one specifc log event is given + <p>Metadata associated with one specific log event is given as the last parameter to the log macro or Logger API function when the event is issued. For example:</p> <code>?LOG_ERROR("Connection closed",#{context => server})</code> @@ -235,8 +236,8 @@ logger:debug(#{got => connection_request, id => Id, state => State}, <section> <marker id="filter"/> <title>Filters</title> - <p>Filters can be global, or attached to a specific - handler. Logger calls the global filters first, and if they all + <p>Filters can be primary, or attached to a specific + handler. Logger calls the primary filters first, and if they all pass, it calls the handler filters for each handler. Logger calls the handler callback only if all filters attached to the handler in question also pass.</p> @@ -251,7 +252,7 @@ logger:debug(#{got => connection_request, id => Id, state => State}, <p>The filter function can return <c>stop</c>, <c>ignore</c> or the (possibly modified) log event.</p> <p>If <c>stop</c> is returned, the log event is immediately - discarded. If the filter is global, no handler filters or + discarded. If the filter is primary, no handler filters or callbacks are called. If it is a handler filter, the corresponding handler callback is not called, but the log event is forwarded to filters attached to the next handler, if @@ -265,23 +266,21 @@ logger:debug(#{got => connection_request, id => Id, state => State}, <p>If the filter function returns <c>ignore</c>, it means that it did not recognize the log event, and thus leaves to other filters to decide the event's destiny.</p> - <p>The configuration - option <seealso marker="#filter_default"><c>filter_default</c></seealso> - specifies the behaviour if all filter functions - return <c>ignore</c>, or if no filters - exist. <c>filter_default</c> is by default set to <c>log</c>, - meaning that if all existing filters ignore a log event, Logger - forwards the event to the handler + <p>The configuration option <c>filter_default</c> specifies the + behaviour if all filter functions return <c>ignore</c>, or if no + filters exist. <c>filter_default</c> is by default set + to <c>log</c>, meaning that if all existing filters ignore a log + event, Logger forwards the event to the handler callback. If <c>filter_default</c> is set to <c>stop</c>, Logger discards such events.</p> - <p>Global filters are added - with <seealso marker="logger#add_logger_filter-2"> - <c>logger:add_logger_filter/2</c></seealso> + <p>Primary filters are added + with <seealso marker="logger#add_primary_filter-2"> + <c>logger:add_primary_filter/2</c></seealso> and removed - with <seealso marker="logger#remove_logger_filter-1"> - <c>logger:remove_logger_filter/1</c></seealso>. They can also + with <seealso marker="logger#remove_primary_filter-1"> + <c>logger:remove_primary_filter/1</c></seealso>. They can also be added at system start via the Kernel configuration - parameter <seealso marker="#logger"><c>logger</c></seealso>.</p> + parameter <seealso marker="#logger_parameter"><c>logger</c></seealso>.</p> <p>Handler filters are added with <seealso marker="logger#add_handler_filter-3"> <c>logger:add_handler_filter/3</c></seealso> @@ -292,12 +291,13 @@ logger:debug(#{got => connection_request, id => Id, state => State}, with <seealso marker="logger#add_handler/3"> <c>logger:add_handler/3</c></seealso> or via the Kernel configuration - parameter <seealso marker="#logger"><c>logger</c></seealso>.</p> + parameter <seealso marker="#logger_parameter"><c>logger</c></seealso>.</p> <p>To see which filters are currently installed in the system, - use <seealso marker="logger#i-0"><c>logger:i/0</c></seealso>, - or <seealso marker="logger#get_logger_config-0"> - <c>logger:get_logger_config/0</c></seealso> + use <seealso marker="logger#get_config-0"> + <c>logger:get_config/0</c></seealso>, + or <seealso marker="logger#get_primary_config-0"> + <c>logger:get_primary_config/0</c></seealso> and <seealso marker="logger#get_handler_config-1"> <c>logger:get_handler_config/1</c></seealso>. Filters are listed in the order they are applied, that is, the first @@ -342,7 +342,7 @@ logger:debug(#{got => connection_request, id => Id, state => State}, <pre><seealso marker="logger#HModule:log-2">log(LogEvent, Config) -> void()</seealso></pre> <p>This function is called when a log event has passed through all - global filters, and all handler filters attached to the handler + primary filters, and all handler filters attached to the handler in question. The function call is executed on the client process, and it is up to the handler implementation if other processes are involved or not.</p> @@ -358,8 +358,8 @@ logger:debug(#{got => connection_request, id => Id, state => State}, functions <c>adding_handler/1</c>, <c>changing_config/2</c> and <c>removing_handler/1</c>. See section <seealso marker="logger#handler_callback_functions">Handler - Callback Functions</seealso> in the logger(3) manual for more - information about these function.</p> + Callback Functions</seealso> in the logger(3) manual page for + more information about these function.</p> <p>The following built-in handlers exist:</p> @@ -404,7 +404,7 @@ logger:debug(#{got => connection_request, id => Id, state => State}, which is passed as the second argument to <seealso marker="logger#HModule:log-2"> <c>HModule:log/2</c></seealso>.</p> - <p>The formatter information consits of a formatter + <p>The formatter information consist of a formatter module, <c>FModule</c> and its configuration, <c>FConfig</c>. <c>FModule</c> must export the following function, which can be called by the handler:</p> @@ -425,152 +425,92 @@ logger:debug(#{got => connection_request, id => Id, state => State}, function when the formatter information is set or modified, to verify the validity of the formatter configuration.</p> <p>If no formatter information is specified for a handler, Logger - uses <seealso marker="logger_formatter"> - <c>logger_formatter(3)</c></seealso> as default.</p> + uses <c>logger_formatter</c> as default. See + the <seealso marker="logger_formatter"><c>logger_formatter(3)</c></seealso> + manual page for more information about this module.</p> </section> <section> <title>Configuration</title> - <p>Logger can be configured either when the system starts through - <seealso marker="config">configuration parameters</seealso>, - or at run-time by using the <seealso marker="logger">logger(3)</seealso> - API. The recommended approach is to do the initial configuration in - the <c>sys.config</c> file and then use the API when some configuration - has to be changed at runtime, such as the log level.</p> + <p>At system start, Logger is configured through Kernel + configuration parameters. The parameters that apply to Logger + are described in + section <seealso marker="#kernel_config_params">Kernel + Configuration Parameters</seealso>. Examples are found in + section <seealso marker="#config_examples">Configuration + Examples</seealso>.</p> + <p>During runtime, Logger configuration is changed via API + functions. See + section <seealso marker="logger#configuration_API">Configuration + API Functions</seealso> in the <c>logger(3)</c> manual page.</p> <section> - <title>Kernel Configuration Parameters</title> - <p>Logger is best configured by using the configuration parameters - of Kernel. There are four possible configuration parameters: - <seealso marker="#logger"><c>logger</c></seealso>, - <seealso marker="kernel_app#logger_level"><c>logger_level</c></seealso>, - <seealso marker="kernel_app#logger_sasl_compatible"><c>logger_sasl_compatible</c></seealso> and - <seealso marker="kernel_app#logger_progress_reports"><c>logger_progress_reports</c></seealso>. - <c>logger_level</c>, <c>logger_sasl_compatible</c> and <c>logger_progress_reports</c> are described in the - <seealso marker="kernel_app#configuration">Kernel Configuration</seealso>, - while <c>logger</c> is described below.</p> - - <marker id="logger"/> - <p><em>logger</em></p> - <p>The application configuration parameter <c>logger</c> is used to configure - three different Logger aspects; handlers, logger filters and module levels. - The configuration is a list containing tagged tuples that look like this:</p> - <taglist> - <tag><c>DisableHandler = {handler,default,undefined}</c></tag> - <item> - <p>Disable the default handler. This allows another application - to add its own default handler. See <seealso marker="logger#add_handlers/1"> - <c>logger:add_handlers/1</c></seealso> for more details.</p> - <p>Only one entry of this option is allowed.</p></item> - <tag><c>AddHandler = {handler,HandlerId,Module,HandlerConfig}</c></tag> - <item> - <p>Add a handler as if <seealso marker="logger:add_handler/3"> - <c>logger:add_handler(HandlerId,Module,HandlerConfig)</c></seealso> is - called.</p> - <p>It is allowed to have multiple entries of this option.</p></item> - <tag><c>Filters = {filters, default, [Filter]}</c><br/> - <c>FilterDefault = log | stop</c><br/> - <c>Filter = {FilterId, {FilterFun, FilterConfig}}</c></tag> - <item> - <p>Add the specified <seealso marker="logger#add_logger_filter/2"> - logger filters</seealso>.</p> - <p>Only one entry of this option is allowed.</p></item> - <tag><c>ModuleLevel = {module_level, Level, [Module]}</c></tag> - <item> - <p>This option configures <seealso marker="logger#set_module_level/2"> - module log level</seealso>.</p> - <p>It is allowed to have multiple entries of this option.</p></item> - </taglist> - <p>Examples:</p> - <list> - <item> - <p>Output logs into the file "logs/erlang.log"</p> - <code> -[{kernel, - [{logger, - [{handler, default, logger_std_h, - #{ logger_std_h => #{ type => {file,"log/erlang.log"}}}}]}]}]. - </code> - </item> - <item> - <p>Output logs in single line format</p> - <code> -[{kernel, - [{logger, - [{handler, default, logger_std_h, - #{ formatter => { logger_formatter,#{ single_line => true}}}}]}]}]. - </code> - </item> - <item> - <p>Add the pid to each log event</p> - <code> -[{kernel, - [{logger, - [{handler, default, logger_std_h, - #{ formatter => { logger_formatter, - #{ template => [time," ",pid," ",msg,"\n"]}} - }}]}]}]. - </code> - </item> - <item> - <p>Use a different file for debug logging</p> - <code> -[{kernel, - [{logger, - [{handler, default, logger_std_h, - #{ level => error, - logger_std_h => #{ type => {file, "log/erlang.log"}}}}, - {handler, info, logger_std_h, - #{ level => debug, - logger_std_h => #{ type => {file, "log/debug.log"}}}} - ]}]}]. - </code> - </item> - </list> - </section> - - <section> - <title>Global Logger Configuration</title> - + <title>Primary Logger Configuration</title> + <p>Logger API functions that apply to the primary Logger + configuration are:</p> + <list> + <item><seealso marker="logger#get_primary_config-0"> + <c>get_primary_config/0</c></seealso></item> + <item><seealso marker="logger#set_primary_config-1"> + <c>set_primary_config/1,2</c></seealso></item> + <item><seealso marker="logger#update_primary_config-1"> + <c>update_primary_config/1</c></seealso></item> + <item><seealso marker="logger#add_primary_filter-2"> + <c>add_primary_filter/2</c></seealso></item> + <item><seealso marker="logger#remove_primary_filter-1"> + <c>remove_primary_filter/1</c></seealso></item> + </list> + <p>The primary Logger configuration is a map with the following + keys:</p> <taglist> - <tag><c>level = </c><seealso marker="logger#type-level"> - <c>logger:level()</c></seealso></tag> + <tag><marker id="primary_level"/> + <c>level = </c><seealso marker="logger#type-level"> + <c>logger:level()</c></seealso><c> | all | none</c></tag> <item> - <p>Specifies the global log level to log.</p> + <p>Specifies the primary log level, that is, log event that + are equally or more severe than this level, are forwarded + to the primary filters. Less severe log events are + immediately discarded.</p> <p>See section <seealso marker="#log_level">Log Level</seealso> for a listing and description of possible log levels.</p> <p>The initial value of this option is set by the Kernel - configuration - parameter <seealso marker="kernel_app#logger_level"> - <c>logger_level</c></seealso>. It can be changed during - runtime - with <seealso marker="logger#set_logger_config-2"> - <c>logger:set_logger_config(level,NewLevel)</c></seealso>.</p> + configuration parameter <seealso marker="#logger_level"> + <c>logger_level</c></seealso>. It is changed during + runtime with <seealso marker="logger#set_primary_config-2"> + <c>logger:set_primary_config(level,Level)</c></seealso>.</p> + <p>Defaults to <c>info</c>.</p> </item> - <tag><c>filters = [{</c><seealso marker="logger#type-filter_id"> - <c>logger:filter_id()</c></seealso><c>,</c> - <seealso marker="logger#type-filter"> - <c>logger:filter()</c></seealso><c>}]</c></tag> + <tag><c>filters = [{FilterId,Filter}]</c></tag> <item> - <p>Global filters are added and removed with - <seealso marker="logger#add_logger_filter-2"> - <c>logger:add_logger_filter/2</c></seealso> and - <seealso marker="logger#remove_logger_filter-1"> - <c>logger:remove_logger_filter/1</c></seealso>, + <p>Specifies the primary filters.</p> + <list> + <item><c>FilterId = </c><seealso marker="logger#type-filter_id"> + <c>logger:filter_id()</c></seealso></item> + <item><c>Filter = </c><seealso marker="logger#type-filter"> + <c>logger:filter()</c></seealso></item> + </list> + <p>The initial value of this option is set by the Kernel + configuration + parameter <seealso marker="#logger_parameter"><c>logger</c></seealso>. + During runtime, primary filters are added and removed with + <seealso marker="logger#add_primary_filter-2"> + <c>logger:add_primary_filter/2</c></seealso> and + <seealso marker="logger#remove_primary_filter-1"> + <c>logger:remove_primary_filter/1</c></seealso>, respectively.</p> <p>See section <seealso marker="#filters">Filters</seealso> - for more information.</p> - <p>Default is <c>[]</c>, that is, no filters exist.</p> + for more detailed information.</p> + <p>Defaults to <c>[]</c>.</p> </item> - <tag><marker id="filter_default"/><c>filter_default = log | stop</c></tag> + <tag><c>filter_default = log | stop</c></tag> <item> - <p>Specifies what to do with an event if all filters + <p>Specifies what happens to a log event if all filters return <c>ignore</c>, or if no filters exist.</p> <p>See section <seealso marker="#filters">Filters</seealso> for more information about how this option is used.</p> - <p>Default is <c>log</c>.</p> + <p>Defaults to <c>log</c>.</p> </item> </taglist> </section> @@ -578,26 +518,64 @@ logger:debug(#{got => connection_request, id => Id, state => State}, <section> <marker id="handler_configuration"/> <title>Handler Configuration</title> + <p>Logger API functions that apply to handler configuration + are:</p> + <list> + <item><seealso marker="logger#get_handler_config-0"> + <c>get_handler_config/0,1</c></seealso></item> + <item><seealso marker="logger#set_handler_config-2"> + <c>set_handler_config/2,3</c></seealso></item> + <item><seealso marker="logger#update_handler_config-2"> + <c>update_handler_config/2</c></seealso></item> + <item><seealso marker="logger#add_handler_filter-3"> + <c>add_handler_filter/3</c></seealso></item> + <item><seealso marker="logger#remove_handler_filter-2"> + <c>remove_handler_filter/2</c></seealso></item> + <item><seealso marker="logger#update_formatter_config-2"> + <c>update_formatter_config/2,3</c></seealso></item> + </list> + <p>The configuration for a handler is a map with the following keys:</p> <taglist> + <tag><c>id = </c><seealso marker="logger#type-handler_id"> + <c>logger:handler_id()</c></seealso></tag> + <item> + <p>Automatically inserted by Logger. The value is the same + as the <c>HandlerId</c> specified when adding the handler, + and it cannot be changed.</p> + </item> + <tag><c>module = module()</c></tag> + <item> + <p>Automatically inserted by Logger. The value is the same + as the <c>Module</c> specified when adding the handler, + and it cannot be changed.</p> + </item> <tag><c>level = </c><seealso marker="logger#type-level"> - <c>logger:level()</c></seealso></tag> + <c>logger:level()</c></seealso><c> | all | none</c></tag> <item> - <p>Specifies the log level which the handler logs.</p> + <p>Specifies the log level for the handler, that is, log + events that are equally or more severe than this level, + are forwarded to the handler filters for this + handler.</p> <p>See section <seealso marker="#log_level">Log Level</seealso> for a listing and description of possible log levels.</p> - <p>The log level can be specified when adding the handler, - or changed during runtime with, for + <p>The log level is specified when adding the handler, or + changed during runtime with, for instance, <seealso marker="logger#set_handler_config/3"> - <c>logger:set_handler_config/3</c></seealso>.</p> - <p>Default is <c>info</c>.</p> + <c>logger:set_handler_config(HandlerId,level,Level)</c></seealso>. + </p> + <p>Defaults to <c>all</c>.</p> </item> - <tag><c>filters = [{</c><seealso marker="logger#type-filter_id"> - <c>logger:filter_id()</c></seealso><c>,</c> - <seealso marker="logger#type-filter"> - <c>logger:filter()</c></seealso><c>}]</c></tag> + <tag><c>filters = [{FilterId,Filter}]</c></tag> <item> - <p>Handler filters can be specified when adding the handler, + <p>Specifies the handler filters.</p> + <list> + <item><c>FilterId = </c><seealso marker="logger#type-filter_id"> + <c>logger:filter_id()</c></seealso></item> + <item><c>Filter = </c><seealso marker="logger#type-filter"> + <c>logger:filter()</c></seealso></item> + </list> + <p>Handler filters are specified when adding the handler, or added or removed during runtime with <seealso marker="logger#add_handler_filter-3"> <c>logger:add_handler_filter/3</c></seealso> and @@ -605,49 +583,214 @@ logger:debug(#{got => connection_request, id => Id, state => State}, <c>logger:remove_handler_filter/2</c></seealso>, respectively.</p> <p>See <seealso marker="#filters">Filters</seealso> for more - information.</p> - <p>Default is <c>[]</c>, that is, no filters exist.</p> + detailed information.</p> + <p>Defaults to <c>[]</c>.</p> </item> - <tag><marker id="filter_default"/><c>filter_default = log | stop</c></tag> + <tag><c>filter_default = log | stop</c></tag> <item> - <p>Specifies what to do with an event if all filters + <p>Specifies what happens to a log event if all filters return <c>ignore</c>, or if no filters exist.</p> <p>See section <seealso marker="#filters">Filters</seealso> for more information about how this option is used.</p> - <p>Default is <c>log</c>.</p> + <p>Defaults to <c>log</c>.</p> </item> - <tag><c>formatter = {module(),</c><seealso marker="logger#type-formatter_config"> - <c>logger:formatter_config()</c></seealso><c>}</c></tag> + <tag><c>formatter = {FormatterModule,FormatterConfig}</c></tag> <item> - <p>The formatter which the handler can use for converting - the log event term to a printable string.</p> - <p>See <seealso marker="#formatters">Formatters</seealso> for more - information.</p> - <p>Default - is <c>{logger_formatter,DefaultFormatterConfig}</c>, see + <p>Specifies a formatter that the handler can use for + converting the log event term to a printable string.</p> + <list> + <item><c>FormatterModule = module()</c></item> + <item><c>FormatterConfig = </c> + <seealso marker="logger#type-formatter_config"> + <c>logger:formatter_config()</c></seealso></item> + </list> + <p>The formatter information is specified when adding the + handler. The formatter configuration can be changed during + runtime + with <seealso marker="logger#update_formatter_config-2"> + <c>logger:update_formatter_config/2,3</c></seealso>, + or the complete formatter information can be overwritten + with, for + instance, <seealso marker="logger#set_handler_config-3"> + <c>logger:set_handler_config/3</c></seealso>.</p> + <p>See + section <seealso marker="#formatters">Formatters</seealso> + for more detailed information.</p> + <p>Defaults + to <c>{logger_formatter,DefaultFormatterConfig}</c>. See the <seealso marker="logger_formatter"> - <c>logger_formatter(3)</c></seealso> - manual for information about this formatter and its - default configuration.</p> + <c>logger_formatter(3)</c></seealso> manual page for + information about this formatter and its default + configuration.</p> </item> - <tag><c>HandlerConfig, atom() = term()</c></tag> - <item> - <p>Any keys not listed above are considered to be handler - specific configuration. The configuration of the Kernel - handlers can be found in + <tag><c>config = term()</c></tag> + <item> + <p>Handler specific configuration, that is, configuration + data related to a specific handler implementation.</p> + <p>The configuration for the built-in handlers is described + in the <seealso marker="logger_std_h"><c>logger_std_h(3)</c></seealso> and <seealso marker="logger_disk_log_h"><c>logger_disk_log_h(3)</c> </seealso> manual pages.</p> - </item> + </item> </taglist> <p>Notice that <c>level</c> and <c>filters</c> are obeyed by Logger itself before forwarding the log events to each - handler, while <c>formatter</c> and all handle specific + handler, while <c>formatter</c> and all handler specific options are left to the handler implementation.</p> - <p>All Logger's built-in handlers will call the given formatter - before printing.</p> + </section> + + <section> + <marker id="kernel_config_params"/> + <title>Kernel Configuration Parameters</title> + + <p>The following Kernel configuration parameters apply to + Logger:</p> + <taglist> + <tag><marker id="logger_parameter"/><c>logger = [Config]</c></tag> + <item> + <p>Specifies the configuration + for <seealso marker="logger">Logger</seealso>, except the + primary log level, which is specified + with <seealso marker="#logger_level"><c>logger_level</c></seealso>, + and the compatibility + with <seealso marker="sasl:error_logging">SASL Error + Logging</seealso>, which is specified + with <seealso marker="#logger_sasl_compatible"> + <c>logger_sasl_compatible</c></seealso>.</p> + <p>With this parameter, you can modify or disable the default + handler, add custom handlers and primary logger filters, and + set log levels per module.</p> + <p><c>Config</c> is any (zero or more) of the following:</p> + <taglist> + <tag><c>{handler, default, undefined}</c></tag> + <item> + <p>Disables the default handler. This allows another + application to add its own default handler.</p> + <p>Only one entry of this type is allowed.</p> + </item> + <tag><c>{handler, HandlerId, Module, HandlerConfig}</c></tag> + <item> + <p>If <c>HandlerId</c> is <c>default</c>, then this entry + modifies the default handler, equivalent to calling</p> + <pre><seealso marker="logger#set_handler_config-2"> + logger:set_handler_config(default, Module, HandlerConfig) + </seealso></pre> + <p>For all other values of <c>HandlerId</c>, this entry + adds a new handler, equivalent to calling</p> + <pre><seealso marker="logger:add_handler/3"> + logger:add_handler(HandlerId, Module, HandlerConfig) + </seealso></pre> + <p>Multiple entries of this type are allowed.</p></item> + <tag><c>{filters, FilterDefault, [Filter]}</c></tag> + <item> + <p>Adds the specified primary filters.</p> + <list> + <item><c>FilterDefault = log | stop</c></item> + <item><c>Filter = {FilterId, {FilterFun, FilterConfig}}</c></item> + </list> + <p>Equivalent to calling</p> + <pre><seealso marker="logger#add_primary_filter/2"> + logger:add_primary_filter(FilterId, {FilterFun, FilterConfig}) + </seealso></pre> + <p>for each <c>Filter</c>.</p> + <p><c>FilterDefault</c> specifies the behaviour if all + primary filters return <c>ignore</c>, see + section <seealso marker="#filters">Filters</seealso>.</p> + <p>Only one entry of this type is allowed.</p> + </item> + <tag><c>{module_level, Level, [Module]}</c></tag> + <item> + <p>Sets module log level for the given modules. Equivalent + to calling</p> + <pre><seealso marker="logger#set_module_level/2"> + logger:set_module_level(Module, Level)</seealso></pre> + <p>for each <c>Module</c>.</p> + <p>Multiple entries of this type are allowed.</p> + </item> + </taglist> + <p>See + section <seealso marker="#config_examples">Configuration + Examples</seealso> for examples using the <c>logger</c> + parameter for system configuration.</p> + </item> + <tag><marker id="logger_level"/> + <c>logger_level = Level</c></tag> + <item> + <p>Specifies the primary log level. See + the <seealso marker="kernel_app#logger_level"><c>kernel(6)</c></seealso> + manual page for more information about this parameter.</p> + </item> + <tag><marker id="logger_sasl_compatible"/> + <c>logger_sasl_compatible = true | false</c></tag> + <item> + <p>Specifies Logger's compatibility + with <seealso marker="sasl:error_logging">SASL Error + Logging</seealso>. See + the <seealso marker="kernel_app#logger_sasl_compatible"> + <c>kernel(6)</c></seealso> manual page for more + information about this parameter.</p> + </item> + </taglist> + </section> + + <section> + <marker id="config_examples"/> + <title>Configuration Examples</title> + <p>The value of the Kernel configuration parameter <c>logger</c> + is a list of tuples. It is possible to write the term on the + command line when starting an erlang node, but as the term + grows, a better approach is to use the system configuration + file. See + the <seealso marker="config"><c>config(4)</c></seealso> manual + page for more information about this file.</p> + <p>Each of the following examples shows a simple system + configuration file that configures Logger according to the + description.</p> + <p>Modify the default handler to print to a file instead of + <c>standard_io</c>:</p> + <code> +[{kernel, + [{logger, + [{handler, default, logger_std_h, % {handler, HandlerId, Module, + #{config => #{type => {file,"log/erlang.log"}}}} % Config} + ]}]}]. + </code> + <p>Modify the default handler to print each log event as a + single line:</p> + <code> +[{kernel, + [{logger, + [{handler, default, logger_std_h, + #{formatter => {logger_formatter, #{single_line => true}}}} + ]}]}]. + </code> + <p>Modify the default handler to print the pid of the logging + process for each log event:</p> + <code> +[{kernel, + [{logger, + [{handler, default, logger_std_h, + #{formatter => {logger_formatter, + #{template => [time," ",pid," ",msg,"\n"]}}}} + ]}]}]. + </code> + <p>Modify the default handler to only print errors and more + severe log events to "log/erlang.log", and add another handler + to print all log events to "log/debug.log".</p> + <code> +[{kernel, + [{logger, + [{handler, default, logger_std_h, + #{level => error, + config => #{type => {file, "log/erlang.log"}}}}, + {handler, info, logger_std_h, + #{level => debug, + config => #{type => {file, "log/debug.log"}}}} + ]}]}]. + </code> </section> </section> @@ -687,8 +830,9 @@ logger:debug(#{got => connection_request, id => Id, state => State}, <p>To get log events on the same format as produced by <c>error_logger_tty_h</c> and <c>error_logger_file_h</c>, use the default formatter, <c>logger_formatter</c>, with - configuration parameter <c>legacy_header => true</c>. This is - also the default.</p> + configuration parameter <c>legacy_header</c> set + to <c>true</c>. This is the default configuration of + the <c>default</c> handler started by Kernel.</p> </item> <tag>Default Format of Log Events from OTP</tag> <item> @@ -700,12 +844,11 @@ logger:debug(#{got => connection_request, id => Id, state => State}, <item> <p>By SASL reports we mean supervisor reports, crash reports and progress reports.</p> - <p>In earlier releases, these reports were only logged when - the SASL application was running, and they were printed - trough specific event handlers - named <c>sasl_report_tty_h</c> + <p>Prior to Erlang/OTP 21.0, these reports were only logged + when the SASL application was running, and they were printed + trough SASL's own event handlers <c>sasl_report_tty_h</c> and <c>sasl_report_file_h</c>.</p> - <p>The destination of these log events were configured by + <p>The destination of these log events was configured by <seealso marker="sasl:sasl_app#deprecated_error_logger_config">SASL configuration parameters</seealso>.</p> <p>Due to the specific event handlers, the output format @@ -716,17 +859,20 @@ logger:debug(#{got => connection_request, id => Id, state => State}, <list> <item>Supervisor reports, crash reports, and progress reports are no longer connected to the SASL application.</item> - <item>Supervisor reports and crash reports are logged by - default.</item> - <item>Progress reports are not logged by default, but can be - enabled with the Kernel configuration - parameter <seealso marker="kernel_app#logger_progress_reports"> - <c>logger_progress_reports</c></seealso>.</item> + <item>Supervisor reports and crash reports are issued + as <c>error</c> level log events, and are logged through + the default handler started by Kernel.</item> + <item>Progress reports are issued as <c>info</c> level log + events, and since the default primary log level + is <c>notice</c>, these are not logged by default. To + enable printing of progress reports, set + the <seealso marker="#primary_level">primary log + level</seealso> to <c>info</c>.</item> <item>The output format is the same for all log events.</item> </list> - <p>If the old behaviour is preferred, the Kernel configuation - parameter <seealso marker="kernel_app:logger_sasl_compatible"> + <p>If the old behaviour is preferred, the Kernel configuration + parameter <seealso marker="kernel_app#logger_sasl_compatible"> <c>logger_sasl_compatible</c></seealso> can be set to <c>true</c>. The <seealso marker="sasl:sasl_app#deprecated_error_logger_config">SASL @@ -734,11 +880,10 @@ logger:debug(#{got => connection_request, id => Id, state => State}, before, and the SASL reports will only be printed if the SASL application is running, through a second log handler named <c>sasl</c>.</p> - <p>All SASL reports have a metadata - field <c>domain => [beam,erlang,otp,sasl]</c>, which can be - used, for example, by filters to stop or allow the - log events.</p> - <p>See the <seealso marker="sasl:error_logging">SASL User's + <p>All SASL reports have a metadata field <c>domain</c> which + is set to <c>[otp,sasl]</c>. This field can be + used by filters to stop or allow the log events.</p> + <p>See section <seealso marker="sasl:error_logging">SASL User's Guide</seealso> for more information about the old SASL error logging functionality.</p> </item> @@ -749,21 +894,22 @@ logger:debug(#{got => connection_request, id => Id, state => State}, <code> error_logger:add_report_handler/1,2. </code> - <p>This will automatically start the <c>error_logger</c> - event manager, and add <c>error_logger</c> as a - handler to <c>logger</c>, with configuration</p> + <p>This automatically starts the error logger event manager, + and adds <c>error_logger</c> as a handler to Logger, with + the following configuration:</p> <code> #{level => info, filter_default => log, filters => []}. </code> - <p>Notice that this handler will ignore events that do not - originate from the <c>error_logger</c> API, or from within - OTP. This means that if your code uses the Logger API for - logging, then your log events will be discarded by this - handler.</p> - <p>Also notice that <c>error_logger</c> is not overload - protected.</p> + <note> + <p>This handler ignores events that do not originate from + the <c>error_logger</c> API, or from within OTP. This + means that if your code uses the Logger API for logging, + then your log events will be discarded by this + handler.</p> + <p>The handler is not overload protected.</p> + </note> </item> </taglist> </section> @@ -771,100 +917,108 @@ error_logger:add_report_handler/1,2. <section> <title>Error Handling</title> - <p>Log data is expected to be either a format string and - arguments, a string - (<seealso marker="stdlib:unicode#type-chardata"> - <c>unicode:chardata()</c></seealso>), or a report (map or - key-value list) which can be converted to a format string and - arguments by the handler. If a report is given, a default report - callback can be included in the log event's metadata. The - handler can use this callback for converting the report to a - format string and arguments. If the format obtained by the - provided callback is not desired, or if there is no provided - callback, the handler must do a custom conversion.</p> - <p>Logger does, to a certain extent, check its input data - before forwarding a log event to the handlers, but it does not - evaluate conversion funs or check the validity of format strings - and arguments. This means that any filter or handler must be - careful when formatting the data of a log event, making sure - that it does not crash due to bad input data or faulty - callbacks.</p> + <p>Logger does, to a certain extent, check its input data before + forwarding a log event to filters and handlers. It does, + however, not evaluate report callbacks, or check the validity of + format strings and arguments. This means that all filters and + handlers must be careful when formatting the data of a log + event, making sure that it does not crash due to bad input data + or faulty callbacks.</p> <p>If a filter or handler still crashes, Logger will remove the filter or handler in question from the configuration, and print a short error message to the terminal. A debug event containing - the crash reason and other details is also issued, and can be - seen if a handler logging debug events is installed.</p> + the crash reason and other details is also issued.</p> + <p>See section <seealso marker="#log_message">Log + Message</seealso> for more information about report callbacks + and valid forms of log messages.</p> </section> <section> - <title>Example: add a handler to log debug events to file</title> + <title>Example: Add a handler to log debug events to file</title> <p>When starting an Erlang node, the default behaviour is that all - log events with level info and above are logged to the - terminal. In order to also log debug events, you can either - change the global log level to <c>debug</c> or add a separate - handler to take care of this. In this example we will add a new - handler which prints the debug events to a separate file.</p> - <p>First, we add an instance of <c>logger_std_h</c> with - type <c>{file,File}</c>, and we set the handler's level - to <c>debug</c>:</p> + log events on level info or more severe, are logged to the + terminal via the default handler. To also log debug events, you + can either change the primary log level to <c>debug</c>:</p> <pre> -1> <input>Config = #{level => debug, logger_std_h => #{type => {file,"./debug.log"}}}.</input> -#{logger_std_h => #{type => {file,"./debug.log"}}, - level => debug} -2> <input>logger:add_handler(debug_handler,logger_std_h,Config).</input> +1> <input>logger:set_primary_config(level, debug).</input> ok</pre> - <p>By default, the handler receives all events - (<c>filter_default=log</c>, see - section <seealso marker="#filters">Filters</seealso> for more - details), so we need to add a filter to stop all non-debug - events. The built-in - filter <seealso marker="logger_filters#level-2"> - <c>logger_filters:level/2</c></seealso> - is used for this:</p> + <p>or set the level for one or a few modules only:</p> <pre> -3> <input>logger:add_handler_filter(debug_handler,stop_non_debug, - {fun logger_filters:level/2,{stop,neq,debug}}).</input> +2> <input>logger:set_module_level(mymodule, debug).</input> ok</pre> - <p>And finally, we need to make sure that Logger itself allows - debug events. This can either be done by setting the global - log level:</p> + <p>This allows debug events to pass through to the default handler, + and be printed to the terminal as well. If there are many debug + events, it can be useful to print these to a file instead.</p> + <p>First, set the log level of the default handler to <c>info</c>, + preventing it from printing debug events to the terminal:</p> <pre> -4> <input>logger:set_logger_config(level,debug).</input> +3> <input>logger:set_handler_config(default, level, info).</input> ok</pre> - <p>Or by allowing debug events from one or a few modules only:</p> + <p>Then, add a new handler which prints to file. You can use the + handler + module <seealso marker="logger_std_h"><c>logger_std_h</c></seealso>, + and specify type <c>{file,File}</c>. The default handler level + is <c>all</c>, so you don't need to specify that:</p> + <pre> +4> <input>Config = #{config => #{type => {file,"./debug.log"}}}.</input> +#{config => #{type => {file,"./debug.log"}}} +5> <input>logger:add_handler(debugger, logger_std_h, Config).</input> +ok</pre> + <p>Since <c>filter_default</c> defaults to <c>log</c>, this + handler now receives all log events. If you want debug events + only in the file, you must add a filter to stop all non-debug + events. The built-in + filter <seealso marker="logger_filters#level-2"> + <c>logger_filters:level/2</c></seealso> + can do this:</p> <pre> -5> <input>logger:set_module_level(mymodule,debug).</input> +6> <input>logger:add_handler_filter(debugger, stop_non_debug, + {fun logger_filters:level/2, {stop, neq, debug}}).</input> ok</pre> + <p>See section <seealso marker="#filters">Filters</seealso> for + more information about the filters and the <c>filter_default</c> + configuration parameter.</p> </section> <section> - <title>Example: implement a handler</title> - <p>The only requirement that a handler MUST fulfill is to export - the following function:</p> - <code>log(logger:log_event(),logger:config()) -> ok</code> - <p>It can optionally also implement the following callbacks:</p> - <code> -adding_handler(logger:config()) -> {ok,logger:config()} | {error,term()} -removing_handler(logger:config()) -> ok -changing_config(logger:config(),logger:config()) -> {ok,logger:config()} | {error,term()} - </code> - <p>When <c>logger:add_handler(Id,Module,Config)</c> is called, + <title>Example: Implement a handler</title> + <p>Section <seealso marker="logger#handler_callback_functions">Handler + Callback Functions</seealso> in the logger(3) manual page + describes the callback functions that can be implemented for a + Logger handler.</p> + <p>A handler callback module must export:</p> + <list> + <item><c>log(Log, Config)</c></item> + </list> + <p>It can optionally also export some, or all, of the following:</p> + <list> + <item><c>adding_handler(Config)</c></item> + <item><c>removing_handler(Config)</c></item> + <item><c>changing_config(OldConfig, NewConfig)</c></item> + </list> + <p>When a handler is added, by for example a call + to <seealso marker="logger#add_handler-3"> + <c>logger:add_handler(Id, HModule, Config)</c></seealso>, Logger first calls <c>HModule:adding_handler(Config)</c>. If - this function returns <c>{ok,NewConfig}</c>, Logger - writes <c>NewConfig</c> to the configuration database, and + this function returns <c>{ok,Config1}</c>, Logger + writes <c>Config1</c> to the configuration database, and the <c>logger:add_handler/3</c> call returns. After this, the handler is installed and must be ready to receive log events as calls to <c>HModule:log/2</c>.</p> <p>A handler can be removed by calling - <c>logger:remove_handler(Id)</c>. Logger calls + <seealso marker="logger#remove_handler-1"> + <c>logger:remove_handler(Id)</c></seealso>. Logger calls <c>HModule:removing_handler(Config)</c>, and removes the handler's configuration from the configuration database.</p> - <p>When <c>logger:set_handler_config/2,3</c> - or <c>logger:update_handler_config/2</c> is called, Logger - calls <c>HModule:changing_config(OldConfig,NewConfig)</c>. If - this function returns <c>{ok,NewConfig}</c>, Logger - writes <c>NewConfig</c> to the configuration database.</p> + <p>When <seealso marker="logger#set_handler_config-2"> + <c>logger:set_handler_config/2,3</c></seealso> + or <seealso marker="logger#update_handler_config/2"> + <c>logger:update_handler_config/2</c></seealso> is called, + Logger + calls <c>HModule:changing_config(OldConfig, NewConfig)</c>. If + this function returns <c>{ok,NewConfig1}</c>, Logger + writes <c>NewConfig1</c> to the configuration database.</p> <p>A simple handler that prints to the terminal can be implemented as follows:</p> @@ -872,11 +1026,11 @@ changing_config(logger:config(),logger:config()) -> {ok,logger:config()} | {erro -module(myhandler). -export([log/2]). -log(LogEvent,#{formatter:={FModule,FConfig}) -> - io:put_chars(FModule:format(LogEvent,FConfig)). +log(LogEvent, #{formatter := {FModule, FConfig}) -> + io:put_chars(FModule:format(LogEvent, FConfig)). </code> - <p>A simple handler which prints to file could be implemented like + <p>A simple handler which prints to file can be implemented like this:</p> <code> -module(myhandler). @@ -884,28 +1038,29 @@ log(LogEvent,#{formatter:={FModule,FConfig}) -> -export([init/1, handle_call/3, handle_cast/2, terminate/2]). adding_handler(Config) -> - {ok,Fd} = file:open(File,[append,{encoding,utf8}]), - {ok,Config#{myhandler_fd => Fd}}. + {ok, Fd} = file:open(File, [append, {encoding, utf8}]), + {ok, Config#{myhandler_fd => Fd}}. -removing_handler(#{myhandler_fd:=Fd}) -> +removing_handler(#{myhandler_fd := Fd}) -> _ = file:close(Fd), ok. -log(LogEvent,#{myhandler_fd:=Fd,formatter:={FModule,FConfig}}) -> - io:put_chars(Fd,FModule:format(LogEvent,FConfig)). +log(LogEvent,#{myhandler_fd := Fd, formatter := {FModule, FConfig}}) -> + io:put_chars(Fd, FModule:format(LogEvent, FConfig)). </code> - <note><p>The above handlers do not have any overload - protection, and all log events are printed directly from the - client process.</p></note> - - <p>For information and examples of overload protection, please - refer to - section <seealso marker="#overload_protection">Protecting the - Handler from Overload</seealso>, and the implementation - of <seealso marker="logger_std_h"><c>logger_std_h(3)</c></seealso> - and <seealso marker="logger_disk_log_h"><c>logger_disk_log_h(3)</c> - </seealso>.</p> + <note> + <p>The above handlers do not have any overload + protection, and all log events are printed directly from the + client process.</p> + <p>For information and examples of overload protection, please + refer to + section <seealso marker="#overload_protection">Protecting the + Handler from Overload</seealso>, and the implementation + of <seealso marker="logger_std_h"><c>logger_std_h</c></seealso> + and <seealso marker="logger_disk_log_h"><c>logger_disk_log_h</c> + </seealso>.</p> + </note> <p>Below is a simpler example of a handler which logs through one single process.</p> @@ -915,33 +1070,33 @@ log(LogEvent,#{myhandler_fd:=Fd,formatter:={FModule,FConfig}}) -> -export([init/1, handle_call/3, handle_cast/2, terminate/2]). adding_handler(Config) -> - {ok,Pid} = gen_server:start(?MODULE,Config), - {ok,Config#{myhandler_pid => Pid}}. + {ok, Pid} = gen_server:start(?MODULE, Config), + {ok, Config#{myhandler_pid => Pid}}. -removing_handler(#{myhandler_pid:=Pid}) -> +removing_handler(#{myhandler_pid := Pid}) -> gen_server:stop(Pid). -log(LogEvent,#{myhandler_pid:=Pid} = Config) -> - gen_server:cast(Pid,{log,LogEvent,Config}). +log(LogEvent,#{myhandler_pid := Pid} = Config) -> + gen_server:cast(Pid, {log, LogEvent, Config}). -init(#{myhandler_file:=File}) -> - {ok,Fd} = file:open(File,[append,{encoding,utf8}]), - {ok,#{file => File, fd => Fd}}. +init(#{myhandler_file := File}) -> + {ok, Fd} = file:open(File, [append, {encoding, utf8}]), + {ok, #{file => File, fd => Fd}}. -handle_call(_,_,State) -> - {reply,{error,bad_request},State}. +handle_call(_, _, State) -> + {reply, {error, bad_request}, State}. -handle_cast({log,LogEvent,Config},#{fd:=Fd} = State) -> - do_log(Fd,LogEvent,Config), - {noreply,State}. +handle_cast({log, LogEvent, Config}, #{fd := Fd} = State) -> + do_log(Fd, LogEvent, Config), + {noreply, State}. -terminate(Reason,#{fd:=Fd}) -> +terminate(Reason, #{fd := Fd}) -> _ = file:close(Fd), ok. -do_log(Fd,LogEvent,#{formatter:={FModule,FConfig}}) -> - String = FModule:format(LogEvent,FConfig), - io:put_chars(Fd,String). +do_log(Fd, LogEvent, #{formatter := {FModule, FConfig}}) -> + String = FModule:format(LogEvent, FConfig), + io:put_chars(Fd, String). </code> </section> @@ -985,7 +1140,7 @@ do_log(Fd,LogEvent,#{formatter:={FModule,FConfig}}) -> level below the <c>toggle_sync_qlen</c> threshold, asynchronous operation is resumed. The switch from asynchronous to synchronous mode will force the logging tempo of few busy senders to slow down, - but can not protect the handler sufficiently in situations of many + but cannot protect the handler sufficiently in situations of many concurrent senders.</p> </item> <tag><c>drop_new_reqs_qlen</c></tag> @@ -1044,11 +1199,11 @@ do_log(Fd,LogEvent,#{formatter:={FModule,FConfig}}) -> <p>A configuration example:</p> <code type="none"> logger:add_handler(my_standard_h, logger_std_h, - #{logger_std_h => - #{type => {file,"./system_info.log"}, - toggle_sync_qlen => 100, - drop_new_reqs_qlen => 1000, - flush_reqs_qlen => 2000}}). + #{config => + #{type => {file,"./system_info.log"}, + toggle_sync_qlen => 100, + drop_new_reqs_qlen => 1000, + flush_reqs_qlen => 2000}}). </code> </section> @@ -1086,10 +1241,10 @@ logger:add_handler(my_standard_h, logger_std_h, <code type="none"> logger:add_handler(my_disk_log_h, logger_disk_log_h, #{disk_log_opts => - #{file => "./my_disk_log"}, - logger_disk_log_h => - #{burst_limit_size => 10, - burst_window_time => 500}}). + #{file => "./my_disk_log"}, + config => + #{burst_limit_size => 10, + burst_window_time => 500}}). </code> </section> diff --git a/lib/kernel/doc/src/logger_disk_log_h.xml b/lib/kernel/doc/src/logger_disk_log_h.xml index 20b49b8ca0..63c29cb010 100644 --- a/lib/kernel/doc/src/logger_disk_log_h.xml +++ b/lib/kernel/doc/src/logger_disk_log_h.xml @@ -44,7 +44,7 @@ the handler configuration.</p> <p>The default standard handler, <seealso marker="logger_std_h"><c>logger_std_h</c></seealso>, can be - replaced by a disk_log handler at startup of the Kernel application. + replaced by a disk_log handler at start up of the Kernel application. See an example of this below.</p> <p>The handler has an overload protection mechanism that will keep the handler process and the Kernel application alive during a high load of log @@ -60,7 +60,7 @@ </seealso>, as well as handler specific parameters.</p> <p>The settings for the disk_log log file should be specified with the key <c>disk_log_opts</c>. These settings are a subset of the disk_log - datatype + data type <seealso marker="disk_log#open-1"><c>dlog_option()</c></seealso>.</p> <p>Parameters in the <c>disk_log_opts</c> map:</p> <taglist> @@ -81,7 +81,7 @@ log.</item> </taglist> <p>Specific configuration for the handler (represented as a sub map) - is specified with the key <c>logger_disk_log_h</c>. It may contain the + is specified with the key <c>config</c>. It may contain the following parameter:</p> <taglist> <tag><c>filesync_repeat_interval</c></tag> @@ -93,7 +93,7 @@ since the last sync. The default value is <c>5000</c> milliseconds. If <c>no_repeat</c> is set as value, the repeated sync operation is disabled. The user can also call the - <seealso marker="logger_disk_log_h#disk_log_sync-1"><c>disk_log_sync/1</c> + <seealso marker="logger_disk_log_h#sync-1"><c>sync/1</c> </seealso> function to perform a disk_log sync.</p></item> </taglist> <p>There are a number of other configuration parameters available, that are @@ -117,7 +117,7 @@ logger:add_handler(my_disk_log_h, logger_disk_log_h, type => wrap, max_no_files => 4, max_no_bytes => 10000}, - logger_disk_log_h => + config => #{filesync_repeat_interval => 1000}}). </code> <p>In order to use the disk_log handler instead of the default standard @@ -125,14 +125,14 @@ logger:add_handler(my_disk_log_h, logger_disk_log_h, use disk_log. Example:</p> <code type="none"> erl -kernel logger '[{handler,default,logger_disk_log_h, - #{ disk_log_opts => #{ file => "./system_disk_log"}}}]' + #{disk_log_opts => #{file => "./system_disk_log"}}}]' </code> </description> <funcs> <func> - <name name="disk_log_sync" arity="1" clause_i="1"/> + <name name="sync" arity="1" clause_i="1"/> <fsummary>Writes buffered data to disk.</fsummary> <desc> <p>Write buffered data to disk.</p> @@ -143,9 +143,9 @@ erl -kernel logger '[{handler,default,logger_disk_log_h, <section> <title>See Also</title> - <p><seealso marker="logger"><c>logger(3)</c></seealso></p> - <p><seealso marker="logger_std_h"><c>logger_std_h(3)</c></seealso></p> - <p><seealso marker="disk_log"><c>disk_log(3)</c></seealso></p> + <p><seealso marker="logger"><c>logger(3)</c></seealso>, + <seealso marker="logger_std_h"><c>logger_std_h(3)</c></seealso>, + <seealso marker="disk_log"><c>disk_log(3)</c></seealso></p> </section> </erlref> diff --git a/lib/kernel/doc/src/logger_filters.xml b/lib/kernel/doc/src/logger_filters.xml index f92181ea3f..90f1fcc270 100644 --- a/lib/kernel/doc/src/logger_filters.xml +++ b/lib/kernel/doc/src/logger_filters.xml @@ -36,15 +36,15 @@ <modulesummary>Filters to use with Logger.</modulesummary> <description> - <p>All functions exported from this module can be used as logger + <p>All functions exported from this module can be used as primary or handler - filters. See <seealso marker="logger#add_logger_filter-2"> - <c>logger:add_logger_filter/2</c></seealso> + filters. See <seealso marker="logger#add_primary_filter-2"> + <c>logger:add_primary_filter/2</c></seealso> and <seealso marker="logger#add_handler_filter-3"> <c>logger:add_handler_filter/3</c></seealso> for more information about how filters are added.</p> - <p>Filters are removed with <seealso marker="logger#remove_logger_filter-1"> - <c>logger:remove_logger_filter/1</c></seealso> + <p>Filters are removed with <seealso marker="logger#remove_primary_filter-1"> + <c>logger:remove_primary_filter/1</c></seealso> and <seealso marker="logger#remove_handler_filter-2"> <c>logger:remove_handler_filter/2</c></seealso>.</p> </description> @@ -64,18 +64,18 @@ <p>A domain field must be a list of atoms, creating smaller and more specialized domains as the list grows longer. The - biggest domain is <c>[]</c>, which comprices all - possible domains.</p> + greatest domain is <c>[]</c>, which comprises all possible + domains.</p> <p>For example, consider the following domains:</p> <pre> -D1 = [beam,erlang,otp] -D2 = [beam,erlang,otp,sasl]</pre> +D1 = [otp] +D2 = [otp, sasl]</pre> - <p><c>D1</c> is the biggest of the two, and is said to be a + <p><c>D1</c> is the greatest of the two, and is said to be a super-domain of <c>D2</c>. <c>D2</c> is a sub-domain <c>D1</c>. Both <c>D1</c> and <c>D2</c> are - sub-domains of <c>[]</c></p> + sub-domains of <c>[]</c>.</p> <p>The above domains are used for logs originating from Erlang/OTP. D1 specifies that the log event comes from @@ -86,50 +86,50 @@ D2 = [beam,erlang,otp,sasl]</pre> <p>The <c><anno>Extra</anno></c> parameter to the <c>domain/2</c> function is specified when adding the - filter via <seealso marker="logger#add_logger_filter-2"> - <c>logger:add_logger_filter/2</c></seealso> + filter via <seealso marker="logger#add_primary_filter-2"> + <c>logger:add_primary_filter/2</c></seealso> or <seealso marker="logger#add_handler_filter-3"> <c>logger:add_handler_filter/3</c></seealso>.</p> - <p>The filter compares the value of the <c>domain</c> field - in the log event's metadata (<c>Domain</c>) - to <c><anno>MatchDomain</anno></c> as follows:</p> + <p>The filter compares the value of the <c>domain</c> field in + the log event's metadata (<c>Domain</c>) against + <c><anno>MatchDomain</anno></c>. The filter matches if the + value of <c>Compare</c> is:</p> <taglist> - <tag><c><anno>Compare</anno> = sub</c></tag> + <tag><c>sub</c></tag> <item> - <p>The filter matches if <c>Domain</c> is equal to or - a sub-domain of <c>MatchDomain</c>, that is, - if <c>MatchDomain</c> is a prefix of <c>Domain</c>.</p> + <p>and <c>Domain</c> is equal to or a sub-domain + of <c>MatchDomain</c>, that is, if <c>MatchDomain</c> is + a prefix of <c>Domain</c>.</p> </item> - <tag><c><anno>Compare</anno> = super</c></tag> + <tag><c>super</c></tag> <item> - <p>The filter matches if <c>Domain</c> is equal to or a - super-domain of <c>MatchDomain</c>, that is, - if <c>Domain</c> is a prefix of <c>MatchDomain</c>.</p> + <p>and <c>Domain</c> is equal to or a super-domain + of <c>MatchDomain</c>, that is, if <c>Domain</c> is a + prefix of <c>MatchDomain</c>.</p> </item> - <tag><c><anno>Compare</anno> = equal</c></tag> + <tag><c>equal</c></tag> <item> - <p>The filter matches if <c>Domain</c> is equal - to <c>MatchDomain</c>.</p> + <p>and <c>Domain</c> is equal to <c>MatchDomain</c>.</p> </item> - <tag><c><anno>Compare</anno> = not_equal</c></tag> + <tag><c>not_equal</c></tag> <item> - <p>The filter matches if <c>Domain</c> is not equal - to <c>MatchDomain</c>, or if there is no domain field in - metadata.</p> + <p>and <c>Domain</c> differs from <c>MatchDomain</c>, or + if there is no domain field in metadata.</p> </item> - <tag><c><anno>Compare</anno> = undefined</c></tag> - <item><p>The filter matches if there is no domain field in - metadata. In this case <c><anno>MatchDomain</anno></c> - must be set to <c>[]</c>.</p> + <tag><c>undefined</c></tag> + <item> + <p>and there is no domain field in metadata. In this + case <c><anno>MatchDomain</anno></c> must be set + to <c>[]</c>.</p> </item> </taglist> - <p>If the filter matches and <c><anno>Action</anno> = log</c>, - the log event is allowed. If the filter matches - and <c><anno>Action</anno> = stop</c>, the log event is - stopped.</p> + <p>If the filter matches and <c><anno>Action</anno></c> is + <c>log</c>, the log event is allowed. If the filter matches + and <c><anno>Action</anno></c> is <c>stop</c>, the log event + is stopped.</p> <p>If the filter does not match, it returns <c>ignore</c>, meaning that other filters, or the value of the @@ -137,16 +137,16 @@ D2 = [beam,erlang,otp,sasl]</pre> event is allowed or not.</p> <p>Log events that do not contain any domain field, match only - when <c><anno>Compare</anno> = undefined</c> - or <c><anno>Compare</anno> = not_equal</c>.</p> + when <c><anno>Compare</anno></c> is equal + to <c>undefined</c> or <c>not_equal</c>.</p> - <p>Example: stop all events with - domain <c>[beam,erlang,otp,sasl|_]</c></p> + <p>Example: stop all events with domain <c>[otp, + sasl | _]</c></p> <code> -logger:set_handler_config(h1,filter_default,log). % this is the default -Filter = {fun logger_filters:domain/2,{stop,sub,[beam,erlang,otp,sasl]}}. -logger:add_handler_filter(h1,no_sasl,Filter). +logger:set_handler_config(h1, filter_default, log). % this is the default +Filter = {fun logger_filters:domain/2, {stop, sub, [otp, sasl]}}. +logger:add_handler_filter(h1, no_sasl, Filter). ok</code> </desc> </func> @@ -157,34 +157,44 @@ ok</code> <desc> <p>This filter provides a way of filtering log events based on the log level. It matches log events by comparing the - log level with a predefined <c>MatchLevel</c></p> + log level with a specified <c>MatchLevel</c></p> <p>The <c><anno>Extra</anno></c> parameter is specified when adding the filter - via <seealso marker="logger#add_logger_filter-2"> - <c>logger:add_logger_filter/2</c></seealso> + via <seealso marker="logger#add_primary_filter-2"> + <c>logger:add_primary_filter/2</c></seealso> or <seealso marker="logger#add_handler_filter-3"> <c>logger:add_handler_filter/3</c></seealso>.</p> <p>The filter compares the value of the event's log level (<c>Level</c>) to <c><anno>MatchLevel</anno></c> by calling <seealso marker="logger#compare_levels-2"> - <c>logger:compare_levels(Level,MatchLevel) -> CmpRet</c></seealso>. It - matches the event if:</p> - - <list> - <item><c>CmpRet = eq</c> and <c><anno>Operator</anno> = - eq | lteq | gteq</c></item> - <item><c>CmpRet = lt</c> and <c><anno>Operator</anno> = - lt | lteq | neq</c></item> - <item><c>CmpRet = gt</c> and <c><anno>Operator</anno> = - gt | gteq | neq</c></item> - </list> - - <p>If the filter matches and <c><anno>Action</anno> = - log</c>, the log event is allowed. If the filter matches - and <c><anno>Action</anno> = stop</c>, the log event is - stopped.</p> + <c>logger:compare_levels(Level, MatchLevel)</c></seealso>. + The filter matches if the value + of <c><anno>Operator</anno></c> is:</p> + + <taglist> + <tag><c>neq</c></tag> + <item><p>and the compare function returns <c>lt</c> + or <c>gt</c>.</p></item> + <tag><c>eq</c></tag> + <item><p>and the compare function returns <c>eq</c>.</p></item> + <tag><c>lt</c></tag> + <item><p>and the compare function returns <c>lt</c>.</p></item> + <tag><c>gt</c></tag> + <item><p>and the compare function returns <c>gt</c>.</p></item> + <tag><c>lteq</c></tag> + <item><p>and the compare function returns <c>lt</c> + or <c>eq</c>.</p></item> + <tag><c>gteq</c></tag> + <item><p>and the compare function returns <c>gt</c> + or <c>eq</c>.</p></item> + </taglist> + + <p>If the filter matches and <c><anno>Action</anno></c> is + <c>log</c>, the log event is allowed. If the filter + matches and <c><anno>Action</anno></c> is <c>stop</c>, the + log event is stopped.</p> <p>If the filter does not match, it returns <c>ignore</c>, meaning that other filters, or the value of the @@ -194,9 +204,9 @@ ok</code> <p>Example: only allow debug level log events</p> <code> -logger:set_handler_config(h1,filter_default,stop). -Filter = {fun logger_filters:level/2,{log,eq,debug}}. -logger:add_handler_filter(h1,debug_only,Filter). +logger:set_handler_config(h1, filter_default, stop). +Filter = {fun logger_filters:level/2, {log, eq, debug}}. +logger:add_handler_filter(h1, debug_only, Filter). ok</code> </desc> </func> @@ -208,9 +218,9 @@ ok</code> <p>This filter matches all progress reports from <c>supervisor</c> and <c>application_controller</c>.</p> - <p>If <c><anno>Extra</anno> = log</c>, the progress reports - are allowed. If <c><anno>Extra</anno> = stop</c>, the - progress reports are stopped.</p> + <p>If <c><anno>Extra</anno></c> is <c>log</c>, the progress + reports are allowed. If <c><anno>Extra</anno></c> + is <c>stop</c>, the progress reports are stopped.</p> <p>The filter returns <c>ignore</c> for all other log events.</p> </desc> @@ -223,9 +233,9 @@ ok</code> <p>This filter matches all events originating from a process that has its group leader on a remote node.</p> - <p>If <c><anno>Extra</anno> = log</c>, the matching events - are allowed. If <c><anno>Extra</anno> = stop</c>, the - matching events are stopped.</p> + <p>If <c><anno>Extra</anno></c> is <c>log</c>, the matching + events are allowed. If <c><anno>Extra</anno></c> + is <c>stop</c>, the matching events are stopped.</p> <p>The filter returns <c>ignore</c> for all other log events.</p> </desc> @@ -233,6 +243,12 @@ ok</code> </funcs> + <section> + <title>See Also</title> + <p> + <seealso marker="logger"><c>logger(3)</c></seealso> + </p> + </section> </erlref> diff --git a/lib/kernel/doc/src/logger_formatter.xml b/lib/kernel/doc/src/logger_formatter.xml index 02f89b26be..59f5dbe367 100644 --- a/lib/kernel/doc/src/logger_formatter.xml +++ b/lib/kernel/doc/src/logger_formatter.xml @@ -36,12 +36,15 @@ <modulesummary>Default formatter for Logger.</modulesummary> <description> - <p>Each log handler has a configured formatter specified as a + <p>Each Logger handler has a configured formatter specified as a module and a configuration term. The purpose of the formatter is to translate the log events to a final printable string (<seealso marker="stdlib:unicode#type-chardata"><c>unicode:chardata()</c> - </seealso>) which can be written to the output - device of the handler.</p> + </seealso>) which can be written to the output device of the + handler. See + sections <seealso marker="logger_chapter#handlers">Handlers</seealso> + and <seealso marker="logger_chapter#formatters">Formatters</seealso> + in the Kernel User's Guide for more information.</p> <p><c>logger_formatter</c> is the default formatter used by Logger.</p> </description> @@ -55,7 +58,8 @@ <seealso marker="stdlib:maps">map</seealso>, and the following keys can be set as configuration parameters:</p> <taglist> - <tag><c>chars_limit = pos_integer() | unlimited</c></tag> + <tag><marker id="chars_limit"/> + <c>chars_limit = integer() > 0 | unlimited</c></tag> <item> <p>A positive integer representing the value of the option with the same name to be used when calling @@ -65,14 +69,8 @@ for each log event. Notice that this is a soft limit. For a hard truncation limit, see option <c>max_size</c>.</p> <p>Defaults to <c>unlimited</c>.</p> - <note> - <p><c>chars_limit</c> has no effect on log messages on - string form. These are expected to be short, but can - still be truncated by the <c>max_size</c> - parameter.</p> - </note> </item> - <tag><marker id="depth"/><c>depth = pos_integer() | unlimited</c></tag> + <tag><marker id="depth"/><c>depth = integer() > 0 | unlimited</c></tag> <item> <p>A positive integer representing the maximum depth to which terms shall be printed by this formatter. Format @@ -83,26 +81,23 @@ <seealso marker="stdlib:io#format-2">io:format/2,3</seealso> in STDLIB.</p> <p>Defaults to <c>unlimited</c>.</p> - <note> - <p><c>depth</c> has no effect on log messages on string - form. These are expected to be short, but can still be - truncated by the <c>max_size</c> parameter.</p> - </note> </item> <tag><c>legacy_header = boolean()</c></tag> <item> <p>If set to <c>true</c> a header field is added to logger_formatter's part of <c>Metadata</c>. The value of this field is a string similar to the header created by - the old <c>error_logger</c> event handlers. It can be - included in the log event by adding the - tuple <c>{logger_formatter,header}</c> to the + the + old <seealso marker="error_logger"><c>error_logger</c></seealso> + event handlers. It can be included in the log event by + adding the list <c>[logger_formatter,header]</c> to the template. See the description of the <seealso marker="#type-template"><c>template()</c></seealso> type for more information.</p> <p>Defaults to <c>false</c>.</p> </item> - <tag><c>max_size = pos_integer() | unlimited</c></tag> + <tag><marker id="max_size"/> + <c>max_size = integer() > 0 | unlimited</c></tag> <item> <p>A positive integer representing the absolute maximum size a string returned from this formatter can have. If the @@ -110,12 +105,12 @@ by <c>chars_limit</c> or <c>depth</c>, it is truncated.</p> <p>Defaults to <c>unlimited</c>.</p> </item> - <tag><c>report_cb = fun((</c><seealso marker="logger#type-report"><c>logger:report()</c></seealso><c>) -> {</c><seealso marker="stdlib:io#type-format"><c>io:format()</c></seealso><c>,[term()]})</c></tag> + <tag><c>report_cb = fun((</c><seealso marker="logger#type-report"><c>logger:report()</c></seealso><c>) -> {</c><seealso marker="stdlib:io#type-format"><c>io:format()</c></seealso><c>, [term()]})</c></tag> <item> <p>A report callback is used by the formatter to transform log messages on report form to a format string and arguments. The report callback can be specified in the - metadata for the log event. If no report callback exist + metadata for the log event. If no report callback exists in metadata, <c>logger_formatter</c> will use <seealso marker="logger#format_report-1"> <c>logger:format_report/1</c></seealso> as default @@ -131,12 +126,14 @@ <tag><c>single_line = boolean()</c></tag> <item> <p>If set to <c>true</c>, all newlines in the message are - replaced with <c>", "</c>, and whitespaces following - directly after newlines are removed. Note that newlines + replaced with <c>", "</c>, and white spaces following + directly after newlines are removed. Notice that newlines added by the <c>template</c> parameter are not replaced.</p> <p>Defaults to <c>true</c>.</p> </item> - <tag><c>template = </c><seealso marker="#type-template"><c>template()</c></seealso></tag> + <tag><marker id="template"/> + <c>template = </c><seealso marker="#type-template"><c>template()</c> + </seealso></tag> <item> <p>The template describes how the formatted string is composed by combining different data values from the log @@ -184,31 +181,42 @@ </desc> </datatype> <datatype> + <name name="metakey"/> + <desc> + <p></p> + </desc> + </datatype> + <datatype> <name name="template"/> <desc> - <p>The template is a list of atoms, tuples and strings. The + <p>The template is a list of atoms, atom lists, tuples and strings. The atoms <c>level</c> or <c>msg</c>, are treated as placeholders for the severity level and the log message, - respectively. Other atoms or tuples are interpreted as + respectively. Other atoms or atom lists are interpreted as placeholders for metadata, where atoms are expected to match - top level keys, and tuples represent paths to sub keys when + top level keys, and atom lists represent paths to sub keys when the metadata is a nested map. For example the - tuple <c>{key1,key2}</c> is replaced by the value of + list <c>[key1,key2]</c> is replaced by the value of the <c>key2</c> field in the nested map below. The atom <c>key1</c> on its own is replaced by the complete value of the <c>key1</c> field. The values are converted to strings.</p> -<code> -#{key1=>#{key2=>my_value, - ...} + <code> +#{key1 => #{key2 => my_value, + ...} ...}</code> - <p>Strings in the template are printed literally.</p> - <p>The default template differs depending on the values - of <c>legacy_header</c> - and <c>single_line</c>:</p> + <p>Tuples in the template express if-exist tests for metadata + keys. For example, the following tuple says that + if <c>key1</c> exists in the metadata map, + print <c>"key1=Value"</c>, where <c>Value</c> is the value + that <c>key1</c> is associated with in the metadata map. If + <c>key1</c> does not exist, print nothing.</p> + <code> +{key1, ["key1=",key1], []}</code> + <p>Strings in the template are printed literally.</p> <p>The default value for the <c>template</c> configuration parameter depends on the value of the <c>single_line</c> and <c>legacy_header</c> configuration parameters as @@ -216,13 +224,13 @@ <p>The log event used in the examples is:</p> <code> -?LOG_ERROR("name: ~p~nexit_reason: ~p",[my_name,"It crashed"])</code> +?LOG_ERROR("name: ~p~nexit_reason: ~p", [my_name, "It crashed"])</code> <taglist> - <tag><c>legacy_header=true, single_line=false</c></tag> + <tag><c>legacy_header = true, single_line = false</c></tag> <item> <p>Default - template: <c>[{logger_formatter,header},"\n",msg,"\n"]</c></p> + template: <c>[[logger_formatter,header],"\n",msg,"\n"]</c></p> <p>Example log entry:</p> <code type="none"> @@ -231,15 +239,16 @@ name: my_name exit_reason: "It crashed"</code> <p>Notice that all eight levels can occur in the heading, - not only <c>ERROR</c>, <c>WARNING</c> or <c>INFO</c> as the - old <c>error_logger</c> produced. And microseconds are - added at the end of the timestamp.</p> + not only <c>ERROR</c>, <c>WARNING</c> or <c>INFO</c> as + <seealso marker="error_logger"><c>error_logger</c></seealso> + produces. And microseconds are added at the end of the + timestamp.</p> </item> - <tag><c>legacy_header=true, single_line=true</c></tag> + <tag><c>legacy_header = true, single_line = true</c></tag> <item> <p>Default - template: <c>[{logger_formatter,header},"\n",msg,"\n"]</c></p> + template: <c>[[logger_formatter,header],"\n",msg,"\n"]</c></p> <p>Notice that the template is here the same as for <c>single_line=false</c>, but the resulting log entry @@ -250,7 +259,7 @@ exit_reason: "It crashed"</code> name: my_name, exit_reason: "It crashed"</code> </item> - <tag><c>legacy_header=false, single_line=true</c></tag> + <tag><c>legacy_header = false, single_line = true</c></tag> <item> <p>Default template: <c>[time," ",level,": ",msg,"\n"]</c></p> @@ -259,7 +268,7 @@ name: my_name, exit_reason: "It crashed"</code> 2018-05-17T18:31:31.152864+02:00 error: name: my_name, exit_reason: "It crashed"</code> </item> - <tag><c>legacy_header=false, single_line=false</c></tag> + <tag><c>legacy_header = false, single_line = false</c></tag> <item> <p>Default template: <c>[time," ",level,":\n",msg,"\n"]</c></p> @@ -279,10 +288,21 @@ exit_reason: "It crashed"</code> <name name="check_config" arity="1"/> <fsummary>Validates the given formatter configuration.</fsummary> <desc> - <p>This callback function is called by Logger when the - formatter configuration for a handler is set or modified. It + <p>The function is called by Logger when the formatter + configuration for a handler is set or modified. It returns <c>ok</c> if the configuration is valid, and <c>{error,term()}</c> if it is faulty.</p> + <p>The following Logger API functions can trigger this callback:</p> + <list> + <item><seealso marker="logger#add_handler-3"> + <c>logger:add_handler/3</c></seealso></item> + <item><seealso marker="logger#set_handler_config-2"> + <c>logger:set_handler_config/2,3</c></seealso></item> + <item><seealso marker="logger#update_handler_config-2"> + <c>logger:updata_handler_config/2</c></seealso></item> + <item><seealso marker="logger#update_formatter_config-2"> + <c>logger:update_formatter_config/2</c></seealso></item> + </list> </desc> </func> <func> @@ -293,22 +313,38 @@ exit_reason: "It crashed"</code> handlers. The log event is processed as follows:</p> <list> <item>If the message is on report form, it is converted to - <c>{Format,Args}</c> by calling the report - callback.</item> - <item>The size is limited according to the values of - configuration parameters <c>chars_limit</c> - and <c>depth</c>. Notice that this does not apply to - messages on string form.</item> + <c>{Format,Args}</c> by calling the report callback. See + section <seealso marker="logger_chapter#log_message">Log + Message</seealso> in the Kernel User's Guide for more + information about report callbacks and valid forms of log + messages.</item> + <item>The message size is limited according to the values of + configuration parameters <seealso marker="#chars_limit"> + <c>chars_limit</c></seealso> + and <seealso marker="#depth"><c>depth</c></seealso>.</item> <item>The full log entry is composed according to - the <c>template</c>.</item> + the <seealso marker="#template"><c>template</c></seealso>.</item> <item>If the final string is too long, it is truncated according to the value of configuration - parameter <c>max_size</c>.</item> + parameter <seealso marker="#max_size"><c>max_size</c></seealso>.</item> </list> </desc> </func> </funcs> + <section> + <title>See Also</title> + <p> + <seealso marker="stdlib:calendar"><c>calendar(3)</c></seealso>, + <seealso marker="error_logger"><c>error_logger(3)</c></seealso>, + <seealso marker="stdlib:io"><c>io(3)</c></seealso>, + <seealso marker="stdlib:io_lib"><c>io_lib(3)</c></seealso>, + <seealso marker="logger"><c>logger(3)</c></seealso>, + <seealso marker="stdlib:maps"><c>maps(3)</c></seealso>, + <seealso marker="sasl:sasl_app"><c>sasl(6)</c></seealso>, + <seealso marker="stdlib:unicode"><c>unicode(3)</c></seealso> + </p> + </section> </erlref> diff --git a/lib/kernel/doc/src/logger_std_h.xml b/lib/kernel/doc/src/logger_std_h.xml index a4f2848037..89e11389c5 100644 --- a/lib/kernel/doc/src/logger_std_h.xml +++ b/lib/kernel/doc/src/logger_std_h.xml @@ -54,7 +54,7 @@ general configuration parameters, as documented in the <seealso marker="logger_chapter#handler_configuration"><c>User's Guide</c> </seealso>, as well as handler specific parameters. The specific parameters - are stored in a sub map with the key <c>logger_std_h</c>. The following + are stored in a sub map with the key <c>config</c>. The following keys and values may be specified:</p> <taglist> <tag><marker id="type"/><c>type</c></tag> @@ -78,7 +78,7 @@ If <c>no_repeat</c> is set as value, the repeated file sync operation is disabled, and it will be the operating system settings that determine how quickly or slowly data gets written to disk. The user can also call - the <seealso marker="logger_std_h#filesync-1"><c>filesync/1</c></seealso> + the <seealso marker="logger_std_h#sync-1"><c>sync/1</c></seealso> function to perform a file sync.</p></item> </taglist> <p>There are a number of other configuration parameters available, that are @@ -99,26 +99,26 @@ logger:add_handler(my_standard_h, logger_std_h, #{level => info, filter_default => log, - logger_std_h => - #{type => {file,"./system_info.log"}, - filesync_repeat_interval => 1000}}). + config => + #{type => {file,"./system_info.log"}, + filesync_repeat_interval => 1000}}). </code> <p>In order to configure the default handler (that starts initially with the Kernel application) to log to file instead of <c>standard_io</c>, change the Kernel default logger to use a file. Example:</p> <code type="none"> erl -kernel logger '[{handler,default,logger_std_h, - #{ logger_std_h => #{ type => {file,"./log.log"}}}}]' + #{config => #{type => {file,"./log.log"}}}}]' </code> <p>An example of how to replace the standard handler with a disk_log handler - at startup can be found in the manual of + at start up can be found in the manual of <seealso marker="logger_disk_log_h"><c>logger_disk_log_h</c></seealso>.</p> </description> <funcs> <func> - <name name="filesync" arity="1" clause_i="1"/> + <name name="sync" arity="1" clause_i="1"/> <fsummary>Writes buffered data to disk.</fsummary> <desc> <p>Write buffered data to disk.</p> @@ -129,8 +129,9 @@ erl -kernel logger '[{handler,default,logger_std_h, <section> <title>See Also</title> - <p><seealso marker="logger"><c>logger(3)</c></seealso></p> - <p><seealso marker="logger_disk_log_h"><c>logger_disk_log_h(3)</c></seealso></p> + <p><seealso marker="logger"><c>logger(3)</c></seealso>, + <seealso marker="logger_disk_log_h"> + <c>logger_disk_log_h(3)</c></seealso></p> </section> </erlref> diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 3eda30f981..09844f1502 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -31,262 +31,6 @@ </header> <p>This document describes the changes made to the Kernel application.</p> -<section><title>Kernel 6.0</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> Clarify the documentation of <c>rpc:multicall/5</c>. - </p> - <p> - Own Id: OTP-10551</p> - </item> - <item> - <p> - The DNS resolver when getting econnrefused from a server - retained an invalid socket so look up towards the next - server(s) also failed.</p> - <p> - Own Id: OTP-13133 Aux Id: PR-1557 </p> - </item> - <item> - <p> - No resolver backend returns V4Mapped IPv6 addresses any - more. This was inconsistent before, some did, some did - not. To facilitate working with such addresses a new - function <c>inet:ipv4_mapped_ipv6_address/1</c> has been - added.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13761 Aux Id: ERL-503 </p> - </item> - <item> - <p> - The type specifications for <c>file:posix/0</c> and - <c>inet:posix/0</c> have been updated according to which - errors file and socket operations should be able to - return.</p> - <p> - Own Id: OTP-14019 Aux Id: ERL-550 </p> - </item> - <item> - <p> - Fix name resolving in IPv6 only environments when doing - the initial distributed connection.</p> - <p> - Own Id: OTP-14501</p> - </item> - <item> - <p> File operations used to accept <seealso - marker="kernel:file#type-name_all">filenames</seealso> - containing null characters (integer value zero). This - caused the name to be truncated and in some cases - arguments to primitive operations to be mixed up. - Filenames containing null characters inside the filename - are now <em>rejected</em> and will cause primitive file - operations to fail. </p> <p> Also environment variable - operations used to accept <seealso - marker="kernel:os#type-env_var_name">names</seealso> and - <seealso - marker="kernel:os#type-env_var_value">values</seealso> of - environment variables containing null characters (integer - value zero). This caused operations to silently produce - erroneous results. Environment variable names and values - containing null characters inside the name or value are - now <em>rejected</em> and will cause environment variable - operations to fail. </p> <p>Primitive environment - variable operations also used to accept the <c>$=</c> - character in environment variable names causing various - problems. <c>$=</c> characters in environment variable - names are now also <em>rejected</em>. </p> <p>Also - <seealso - marker="kernel:os#cmd/1"><c>os:cmd/1</c></seealso> now - reject null characters inside its <seealso - marker="kernel:os#type-os_command">command</seealso>. - </p> <p><seealso - marker="erts:erlang#open_port/2"><c>erlang:open_port/2</c></seealso> - will also reject null characters inside the port name - from now on.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14543 Aux Id: ERL-370 </p> - </item> - <item> - <p><c>os:putenv</c> and <c>os:getenv</c> no longer access - the process environment directly and instead work on a - thread-safe emulation. The only observable difference is - that it's <em>not</em> kept in sync with libc - <c>getenv(3)</c> / <c>putenv(3)</c>, so those who relied - on that behavior in drivers or NIFs will need to add - manual synchronization.</p> <p>On Windows this means that - you can no longer resolve DLL dependencies by modifying - the <c>PATH</c> just before loading the driver/NIF. To - make this less of a problem, the emulator now adds the - target DLL's folder to the DLL search path.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14666</p> - </item> - <item> - <p> - Fixed connection tick toward primitive hidden nodes - (erl_interface) that could cause faulty tick timeout in - rare cases when payload data is sent to hidden node but - not received.</p> - <p> - Own Id: OTP-14681</p> - </item> - <item> - <p> - Make group react immediately on an EXIT-signal from shell - in e.g ssh.</p> - <p> - Own Id: OTP-14991 Aux Id: PR1705 </p> - </item> - <item> - <p> - Calls to <c>gen_tcp:send/2</c> on closed sockets now - returns <c>{error, closed}</c> instead of - <c>{error,enotconn}</c>.</p> - <p> - Own Id: OTP-15001</p> - </item> - <item> - <p> - The <c>included_applications</c> key are no longer - duplicated as application environment variable. Earlier, - the included applications could be read both with - <c>application:get[_all]_env(...)</c> and - <c>application:get[_all]_key(...)</c> functions. Now, it - can only be read with - <c>application:get[_all]_key(...)</c>.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-15071</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>A new logging API is added to Erlang/OTP, see the - <seealso - marker="kernel:logger"><c>logger(3)</c></seealso> manual - page, and section <seealso - marker="kernel:logger_chapter">Logging</seealso> in the - Kernel User's Guide.</p> - <p>Calls to <c>error_logger</c> are automatically - redirected to the new API, and legacy error logger event - handlers can still be used. It is, however, recommended - to use the Logger API directly when writing new code.</p> - <p>Notice the following potential incompatibilities:</p> - <list> <item><p>Kernel configuration parameters - <c>error_logger</c> still works, but is overruled if the - default handler's output destination is configured with - Kernel configuration parameter <c>logger</c>.</p> <p>In - general, parameters for configuring error logger are - overwritten by new parameters for configuring - Logger.</p></item> <item><p>The concept of SASL error - logging is deprecated, meaning that by default the SASL - application does not affect which log events are - logged.</p> <p>By default, supervisor reports and crash - reports are logged by the default Logger handler started - by Kernel, and end up at the same destination (terminal - or file) as other standard log event from Erlang/OTP.</p> - <p>Progress reports are not logged by default, but can be - enabled with the Kernel configuration parameter - <c>logger_progress_reports</c>.</p> <p>To obtain - backwards compatibility with the SASL error logging - functionality from earlier releases, set Kernel - configuration parameter <c>logger_sasl_compatible</c> to - <c>true</c>. This prevents the default Logger handler - from logging any supervisor-, crash-, or progress - reports. Instead, SASL adds a separate Logger handler - during application start, which takes care of these log - events. The SASL configuration parameters - <c>sasl_error_logger</c> and <c>sasl_errlog_type</c> - specify the destination (terminal or file) and severity - level to log for these events.</p></item></list> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13295</p> - </item> - <item> - <p> - The function <c>inet:i/0</c> has been documented.</p> - <p> - Own Id: OTP-13713 Aux Id: PR-1645 </p> - </item> - <item> - <p> - Typespecs for <c>netns</c> and <c>bind_to_device</c> - options have been added to <c>gen_tcp</c>, <c>gen_udp</c> - and <c>gen_sctp</c> functions.</p> - <p> - Own Id: OTP-14359 Aux Id: PR-1816 </p> - </item> - <item> - <p> - New functionality for implementation of alternative - carriers for the Erlang distribution has been introduced. - This mainly consists of support for usage of distribution - controller processes (previously only ports could be used - as distribution controllers). For more information see - <seealso marker="erts:alt_dist#distribution_module">ERTS - User's Guide ➜ How to implement an Alternative Carrier - for the Erlang Distribution ➜ Distribution - Module</seealso>.</p> - <p> - Own Id: OTP-14459</p> - </item> - <item> - <p><c>seq_trace</c> labels may now be any erlang - term.</p> - <p> - Own Id: OTP-14899</p> - </item> - <item> - <p> - The SSL distribution protocol <c>-proto inet_tls</c> has - stopped setting the SSL option - <c>server_name_indication</c>. New verify funs for client - and server in <c>inet_tls_dist</c> has been added, not - documented yet, that checks node name if present in peer - certificate. Usage is still also yet to be documented.</p> - <p> - Own Id: OTP-14969 Aux Id: OTP-14465, ERL-598 </p> - </item> - <item> - <p> - Changed timeout of <c>gen_server</c> calls to <c>auth</c> - server from default 5 seconds to <c>infinity</c>.</p> - <p> - Own Id: OTP-15009 Aux Id: ERL-601 </p> - </item> - <item> - <p>The callback module passed as <c>-epmd_module</c> to - erl has been expanded to be able to do name and port - resolving.</p> <p>Documentation has also been added in - the <seealso - marker="kernel:erl_epmd"><c>erl_epmd</c></seealso> - reference manual and ERTS User's Guide <seealso - marker="erts:alt_disco">How to Implement an Alternative - Service Discovery for Erlang Distribution</seealso>.</p> - <p> - Own Id: OTP-15086 Aux Id: PR-1694 </p> - </item> - </list> - </section> - -</section> - <section><title>Kernel 5.4.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/kernel/doc/src/part.xml b/lib/kernel/doc/src/part.xml index 68eb4530e2..fa7e92835f 100644 --- a/lib/kernel/doc/src/part.xml +++ b/lib/kernel/doc/src/part.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1996</year><year>2017</year> + <year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -22,17 +22,14 @@ </legalnotice> - <title>Logger User's Guide</title> + <title>Kernel User's Guide</title> <prepared>OTP Team</prepared> <docno></docno> - <date>2017-12-01</date> - <rev>0.1</rev> + <date>2018-06-06</date> <file>part.xml</file> </header> <description> - <p>The System Architecture Support Libraries SASL application - provides support for alarm handling, release handling, and - related functions.</p> + <p></p> </description> <xi:include href="introduction_chapter.xml"/> <xi:include href="logger_chapter.xml"/> diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl index ff5df667b5..0dad6ae935 100644 --- a/lib/kernel/src/application_controller.erl +++ b/lib/kernel/src/application_controller.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2017. All Rights Reserved. +%% Copyright Ericsson AB 1996-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -1914,19 +1914,19 @@ info_started(Name, Node) -> ?LOG_INFO(#{label=>{application_controller,progress}, report=>[{application, Name}, {started_at, Node}]}, - #{domain=>[beam,erlang,otp,sasl], + #{domain=>[otp,sasl], report_cb=>fun logger:format_otp_report/1, logger_formatter=>#{title=>"PROGRESS REPORT"}, error_logger=>#{tag=>info_report,type=>progress}}). info_exited(Name, Reason, Type) -> - ?LOG_INFO(#{label=>{application_controller,exit}, - report=>[{application, Name}, - {exited, Reason}, - {type, Type}]}, - #{domain=>[beam,erlang,otp], - report_cb=>fun logger:format_otp_report/1, - error_logger=>#{tag=>info_report,type=>std_info}}). + ?LOG_NOTICE(#{label=>{application_controller,exit}, + report=>[{application, Name}, + {exited, Reason}, + {type, Type}]}, + #{domain=>[otp], + report_cb=>fun logger:format_otp_report/1, + error_logger=>#{tag=>info_report,type=>std_info}}). %%----------------------------------------------------------------- %% Reply to all processes waiting this application to be started. @@ -2013,5 +2013,5 @@ to_string(Term) -> true -> Term; false -> - lists:flatten(io_lib:format("~134217728p", [Term])) + lists:flatten(io_lib:format("~0p", [Term])) end. diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl index f143a49d2f..7faef93609 100644 --- a/lib/kernel/src/code.erl +++ b/lib/kernel/src/code.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2017. All Rights Reserved. +%% Copyright Ericsson AB 1996-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -630,7 +630,7 @@ do_par_recv(N, Good, Bad) -> call(Req) -> code_server:call(Req). --spec start_link() -> {'ok', pid()} | {'error', 'crash'}. +-spec start_link() -> {'ok', pid()}. start_link() -> do_start(). diff --git a/lib/kernel/src/error_logger.erl b/lib/kernel/src/error_logger.erl index b3957d0c7e..918a915729 100644 --- a/lib/kernel/src/error_logger.erl +++ b/lib/kernel/src/error_logger.erl @@ -101,8 +101,8 @@ stop() -> %%%----------------------------------------------------------------- %%% Callbacks for logger --spec adding_handler(logger:config()) -> - {ok,logger:config()} | {error,term()}. +-spec adding_handler(logger:handler_config()) -> + {ok,logger:handler_config()} | {error,term()}. adding_handler(#{id:=?MODULE}=Config) -> case start() of ok -> @@ -111,12 +111,12 @@ adding_handler(#{id:=?MODULE}=Config) -> Error end. --spec removing_handler(logger:config()) -> ok. +-spec removing_handler(logger:handler_config()) -> ok. removing_handler(#{id:=?MODULE}) -> stop(), ok. --spec log(logger:log_event(),logger:config()) -> ok. +-spec log(logger:log_event(),logger:handler_config()) -> ok. log(#{level:=Level,msg:=Msg,meta:=Meta},_Config) -> do_log(Level,Msg,Meta). @@ -169,16 +169,25 @@ do_log(_Level,_Msg,_Meta) -> -spec notify(logger:level(), msg_tag(), any(), any(), map()) -> 'ok'. notify(Level,Tag0,FormatOrType0,ArgsOrReport,#{pid:=Pid0,gl:=GL,?MODULE:=My}) -> - Tag = fix_warning_tag(Level,Tag0), + {Tag,FormatOrType} = maybe_map_warnings(Level,Tag0,FormatOrType0), Pid = case maps:get(emulator,My,false) of true -> emulator; _ -> Pid0 end, - FormatOrType = fix_warning_type(Level,FormatOrType0), gen_event:notify(?MODULE,{Tag,GL,{Pid,FormatOrType,ArgsOrReport}}). -%% This is to fix the case when the client has explicitly added the -%% error logger tag and type in metadata, and not checked the warning map. +%% For backwards compatibility with really old even handlers, check +%% the warning map and update tag and type. +maybe_map_warnings(warning,Tag,FormatOrType) -> + case error_logger:warning_map() of + warning -> + {Tag,FormatOrType}; + Level -> + {fix_warning_tag(Level,Tag),fix_warning_type(Level,FormatOrType)} + end; +maybe_map_warnings(_,Tag,FormatOrType) -> + {Tag,FormatOrType}. + fix_warning_tag(error,warning_msg) -> error; fix_warning_tag(error,warning_report) -> error_report; fix_warning_tag(info,warning_msg) -> info_msg; @@ -263,29 +272,10 @@ warning_report(Report) -> Report :: report(). warning_report(Type, Report) -> - Level = error_logger:warning_map(), - {Tag, NType} = case Level of - info -> - if - Type =:= std_warning -> - {info_report, std_info}; - true -> - {info_report, Type} - end; - warning -> - {warning_report, Type}; - error -> - if - Type =:= std_warning -> - {error_report, std_error}; - true -> - {error_report, Type} - end - end, - logger:log(Level, + logger:log(warning, #{label=>{?MODULE,warning_report}, report=>Report}, - meta(Tag,NType)). + meta(warning_report,Type)). %%----------------------------------------------------------------- %% This function provides similar functions as error_msg for @@ -304,20 +294,11 @@ warning_msg(Format) -> Data :: list(). warning_msg(Format, Args) -> - Level = error_logger:warning_map(), - Tag = case Level of - warning -> - warning_msg; - info -> - info_msg; - error -> - error - end, - logger:log(Level, + logger:log(warning, #{label=>{?MODULE,warning_msg}, format=>Format, args=>Args}, - meta(Tag)). + meta(warning_msg)). %%----------------------------------------------------------------- %% This function should be used for information reports. Events @@ -336,7 +317,7 @@ info_report(Report) -> Report :: report(). info_report(Type, Report) -> - logger:log(info, + logger:log(notice, #{label=>{?MODULE,info_report}, report=>Report}, meta(info_report,Type)). @@ -357,7 +338,7 @@ info_msg(Format) -> Data :: list(). info_msg(Format, Args) -> - logger:log(info, + logger:log(notice, #{label=>{?MODULE,info_msg}, format=>Format, args=>Args}, @@ -377,7 +358,7 @@ error_info(Error) -> false -> {"~p",[Error]} end, MyMeta = #{tag=>info,type=>Error}, - logger:log(info, Format, Args, #{?MODULE=>MyMeta,domain=>[Error]}). + logger:log(notice, Format, Args, #{?MODULE=>MyMeta,domain=>[Error]}). %%----------------------------------------------------------------- %% Create metadata @@ -532,17 +513,17 @@ tty(true) -> _ = case lists:member(error_logger_tty_h, which_report_handlers()) of false -> case logger:get_handler_config(default) of - {ok,{logger_std_h,#{logger_std_h:=#{type:=standard_io}}}} -> + {ok,#{module:=logger_std_h,config:=#{type:=standard_io}}} -> logger:remove_handler_filter(default, error_logger_tty_false); _ -> logger:add_handler(error_logger_tty_true,logger_std_h, #{filter_default=>stop, filters=>?DEFAULT_HANDLER_FILTERS( - [beam,erlang,otp]), + [otp]), formatter=>{?DEFAULT_FORMATTER, ?DEFAULT_FORMAT_CONFIG}, - logger_std_h=>#{type=>standard_io}}) + config=>#{type=>standard_io}}) end; true -> ok @@ -552,7 +533,7 @@ tty(false) -> delete_report_handler(error_logger_tty_h), _ = logger:remove_handler(error_logger_tty_true), _ = case logger:get_handler_config(default) of - {ok,{logger_std_h,#{logger_std_h:=#{type:=standard_io}}}} -> + {ok,#{module:=logger_std_h,config:=#{type:=standard_io}}} -> logger:add_handler_filter(default,error_logger_tty_false, {fun(_,_) -> stop end, ok}); _ -> @@ -575,6 +556,8 @@ get_format_depth() -> case application:get_env(kernel, error_logger_format_depth) of {ok, Depth} when is_integer(Depth) -> max(10, Depth); + {ok, unlimited} -> + unlimited; undefined -> unlimited end. diff --git a/lib/kernel/src/file_server.erl b/lib/kernel/src/file_server.erl index ecc1ffbdd6..29eaa23375 100644 --- a/lib/kernel/src/file_server.erl +++ b/lib/kernel/src/file_server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2017. All Rights Reserved. +%% Copyright Ericsson AB 2000-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -73,7 +73,7 @@ stop() -> %% {stop, Reason} %%---------------------------------------------------------------------- --spec init([]) -> {'ok', state()} | {'stop', term()}. +-spec init([]) -> {'ok', state()}. init([]) -> process_flag(trap_exit, true), @@ -225,7 +225,7 @@ handle_cast(Msg, State) -> %%---------------------------------------------------------------------- -spec handle_info(term(), state()) -> - {'noreply', state()} | {'stop', 'normal', state()}. + {'noreply', state()}. handle_info({'EXIT', Pid, _Reason}, State) when is_pid(Pid) -> ets:delete(?FILE_IO_SERVER_TABLE, Pid), diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src index d873178f55..390f1fa42a 100644 --- a/lib/kernel/src/kernel.app.src +++ b/lib/kernel/src/kernel.app.src @@ -140,9 +140,8 @@ inet_db, pg2]}, {applications, []}, - {env, [{logger_level, info}, - {logger_sasl_compatible, false}, - {logger_progress_reports, stop} + {env, [{logger_level, notice}, + {logger_sasl_compatible, false} ]}, {mod, {kernel, []}}, {runtime_dependencies, ["erts-10.0", "stdlib-3.5", "sasl-3.0"]} diff --git a/lib/kernel/src/kernel_refc.erl b/lib/kernel/src/kernel_refc.erl index 05076dc885..8e04ff99d8 100644 --- a/lib/kernel/src/kernel_refc.erl +++ b/lib/kernel/src/kernel_refc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2017. All Rights Reserved. +%% Copyright Ericsson AB 2017-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ scheduler_wall_time(Bool) -> %% Callback functions from gen_server %%----------------------------------------------------------------- --spec init([]) -> {'ok', map()} | {'stop', term()}. +-spec init([]) -> {'ok', map()}. init([]) -> resource(scheduler_wall_time, false), diff --git a/lib/kernel/src/logger.erl b/lib/kernel/src/logger.erl index 3beb3102fa..7d121f22fe 100644 --- a/lib/kernel/src/logger.erl +++ b/lib/kernel/src/logger.erl @@ -35,14 +35,17 @@ %% Configuration -export([add_handler/3, remove_handler/1, - add_logger_filter/2, add_handler_filter/3, - remove_logger_filter/1, remove_handler_filter/2, - set_module_level/2, unset_module_level/1, - set_logger_config/1, set_logger_config/2, + add_primary_filter/2, add_handler_filter/3, + remove_primary_filter/1, remove_handler_filter/2, + set_module_level/2, + unset_module_level/1, unset_module_level/0, + get_module_level/0, get_module_level/1, + set_primary_config/1, set_primary_config/2, set_handler_config/2, set_handler_config/3, - update_logger_config/1, update_handler_config/2, + update_primary_config/1, update_handler_config/2, update_formatter_config/2, update_formatter_config/3, - get_logger_config/0, get_handler_config/1, + get_primary_config/0, get_handler_config/1, + get_handler_config/0, get_handler_ids/0, get_config/0, add_handlers/1]). %% Private configuration @@ -52,7 +55,6 @@ -export([compare_levels/2]). -export([set_process_metadata/1, update_process_metadata/1, unset_process_metadata/0, get_process_metadata/0]). --export([i/0, i/1]). %% Basic report formatting -export([format_report/1, format_otp_report/1]). @@ -93,19 +95,24 @@ filter_return()),filter_arg()}. -type filter_arg() :: term(). -type filter_return() :: stop | ignore | log_event(). --type config() :: #{id => handler_id(), - level => level(), - filter_default => log | stop, - filters => [{filter_id(),filter()}], - formatter => {module(),formatter_config()}, - atom() => term()}. +-type primary_config() :: #{level => level() | all | none, + filter_default => log | stop, + filters => [{filter_id(),filter()}]}. +-type handler_config() :: #{id => handler_id(), + config => term(), + level => level() | all | none, + module => module(), + filter_default => log | stop, + filters => [{filter_id(),filter()}], + formatter => {module(),formatter_config()}}. -type timestamp() :: integer(). -type formatter_config() :: #{atom() => term()}. --type config_handler() :: {handler, handler_id(), module(), config()}. +-type config_handler() :: {handler, handler_id(), module(), handler_config()}. --export_type([log_event/0,level/0,report/0,msg_fun/0,metadata/0,config/0, - handler_id/0,filter_id/0,filter/0,filter_arg/0,filter_return/0, +-export_type([log_event/0,level/0,report/0,msg_fun/0,metadata/0, + primary_config/0,handler_config/0,handler_id/0, + filter_id/0,filter/0,filter_arg/0,filter_return/0, config_handler/0,formatter_config/0]). %%%----------------------------------------------------------------- @@ -308,11 +315,11 @@ internal_log(Level,Term) when is_atom(Level) -> %%%----------------------------------------------------------------- %%% Configuration --spec add_logger_filter(FilterId,Filter) -> ok | {error,term()} when +-spec add_primary_filter(FilterId,Filter) -> ok | {error,term()} when FilterId :: filter_id(), Filter :: filter(). -add_logger_filter(FilterId,Filter) -> - logger_server:add_filter(logger,{FilterId,Filter}). +add_primary_filter(FilterId,Filter) -> + logger_server:add_filter(primary,{FilterId,Filter}). -spec add_handler_filter(HandlerId,FilterId,Filter) -> ok | {error,term()} when HandlerId :: handler_id(), @@ -322,10 +329,10 @@ add_handler_filter(HandlerId,FilterId,Filter) -> logger_server:add_filter(HandlerId,{FilterId,Filter}). --spec remove_logger_filter(FilterId) -> ok | {error,term()} when +-spec remove_primary_filter(FilterId) -> ok | {error,term()} when FilterId :: filter_id(). -remove_logger_filter(FilterId) -> - logger_server:remove_filter(logger,FilterId). +remove_primary_filter(FilterId) -> + logger_server:remove_filter(primary,FilterId). -spec remove_handler_filter(HandlerId,FilterId) -> ok | {error,term()} when HandlerId :: handler_id(), @@ -336,7 +343,7 @@ remove_handler_filter(HandlerId,FilterId) -> -spec add_handler(HandlerId,Module,Config) -> ok | {error,term()} when HandlerId :: handler_id(), Module :: module(), - Config :: config(). + Config :: handler_config(). add_handler(HandlerId,Module,Config) -> logger_server:add_handler(HandlerId,Module,Config). @@ -345,16 +352,16 @@ add_handler(HandlerId,Module,Config) -> remove_handler(HandlerId) -> logger_server:remove_handler(HandlerId). --spec set_logger_config(Key,Value) -> ok | {error,term()} when +-spec set_primary_config(Key,Value) -> ok | {error,term()} when Key :: atom(), Value :: term(). -set_logger_config(Key,Value) -> - logger_server:set_config(logger,Key,Value). +set_primary_config(Key,Value) -> + logger_server:set_config(primary,Key,Value). --spec set_logger_config(Config) -> ok | {error,term()} when - Config :: config(). -set_logger_config(Config) -> - logger_server:set_config(logger,Config). +-spec set_primary_config(Config) -> ok | {error,term()} when + Config :: primary_config(). +set_primary_config(Config) -> + logger_server:set_config(primary,Config). -spec set_handler_config(HandlerId,Key,Value) -> ok | {error,term()} when HandlerId :: handler_id(), @@ -365,59 +372,101 @@ set_handler_config(HandlerId,Key,Value) -> -spec set_handler_config(HandlerId,Config) -> ok | {error,term()} when HandlerId :: handler_id(), - Config :: config(). + Config :: handler_config(). set_handler_config(HandlerId,Config) -> logger_server:set_config(HandlerId,Config). --spec update_logger_config(Config) -> ok | {error,term()} when - Config :: config(). -update_logger_config(Config) -> - logger_server:update_config(logger,Config). +-spec update_primary_config(Config) -> ok | {error,term()} when + Config :: primary_config(). +update_primary_config(Config) -> + logger_server:update_config(primary,Config). -spec update_handler_config(HandlerId,Config) -> ok | {error,term()} when HandlerId :: handler_id(), - Config :: config(). + Config :: handler_config(). update_handler_config(HandlerId,Config) -> logger_server:update_config(HandlerId,Config). --spec get_logger_config() -> {ok,Config} when - Config :: config(). -get_logger_config() -> - {ok,Config} = logger_config:get(?LOGGER_TABLE,logger), - {ok,maps:remove(handlers,Config)}. +-spec get_primary_config() -> Config when + Config :: primary_config(). +get_primary_config() -> + {ok,Config} = logger_config:get(?LOGGER_TABLE,primary), + maps:remove(handlers,Config). --spec get_handler_config(HandlerId) -> {ok,{Module,Config}} | {error,term()} when +-spec get_handler_config(HandlerId) -> {ok,Config} | {error,term()} when HandlerId :: handler_id(), - Module :: module(), - Config :: config(). + Config :: handler_config(). get_handler_config(HandlerId) -> - logger_config:get(?LOGGER_TABLE,HandlerId). + case logger_config:get(?LOGGER_TABLE,HandlerId) of + {ok,{_,Config}} -> + {ok,Config}; + Error -> + Error + end. + +-spec get_handler_config() -> [Config] when + Config :: handler_config(). +get_handler_config() -> + [begin + {ok,Config} = get_handler_config(HandlerId), + Config + end || HandlerId <- get_handler_ids()]. + +-spec get_handler_ids() -> [HandlerId] when + HandlerId :: handler_id(). +get_handler_ids() -> + {ok,#{handlers:=HandlerIds}} = logger_config:get(?LOGGER_TABLE,primary), + HandlerIds. -spec update_formatter_config(HandlerId,FormatterConfig) -> ok | {error,term()} when - HandlerId :: config(), + HandlerId :: handler_id(), FormatterConfig :: formatter_config(). update_formatter_config(HandlerId,FormatterConfig) -> logger_server:update_formatter_config(HandlerId,FormatterConfig). -spec update_formatter_config(HandlerId,Key,Value) -> ok | {error,term()} when - HandlerId :: config(), + HandlerId :: handler_id(), Key :: atom(), Value :: term(). update_formatter_config(HandlerId,Key,Value) -> logger_server:update_formatter_config(HandlerId,#{Key=>Value}). --spec set_module_level(Module,Level) -> ok | {error,term()} when +-spec set_module_level(Modules,Level) -> ok | {error,term()} when + Modules :: [module()] | module(), + Level :: level() | all | none. +set_module_level(Module,Level) when is_atom(Module) -> + set_module_level([Module],Level); +set_module_level(Modules,Level) -> + logger_server:set_module_level(Modules,Level). + +-spec unset_module_level(Modules) -> ok when + Modules :: [module()] | module(). +unset_module_level(Module) when is_atom(Module) -> + unset_module_level([Module]); +unset_module_level(Modules) -> + logger_server:unset_module_level(Modules). + +-spec unset_module_level() -> ok. +unset_module_level() -> + logger_server:unset_module_level(). + +-spec get_module_level(Modules) -> [{Module,Level}] when + Modules :: [Module] | Module, Module :: module(), - Level :: level(). -set_module_level(Module,Level) -> - logger_server:set_module_level(Module,Level). - --spec unset_module_level(Module) -> ok | {error,term()} when - Module :: module(). -unset_module_level(Module) -> - logger_server:unset_module_level(Module). + Level :: level() | all | none. +get_module_level(Module) when is_atom(Module) -> + get_module_level([Module]); +get_module_level(Modules) when is_list(Modules) -> + [{M,L} || {M,L} <- get_module_level(), + lists:member(M,Modules)]. + +-spec get_module_level() -> [{Module,Level}] when + Module :: module(), + Level :: level() | all | none. +get_module_level() -> + logger_config:get_module_level(?LOGGER_TABLE). %%%----------------------------------------------------------------- %%% Misc @@ -466,82 +515,13 @@ unset_process_metadata() -> _ = erase(?LOGGER_META_KEY), ok. --spec i() -> #{logger=>config(), - handlers=>[{handler_id(),module(),config()}], - module_levels=>[{module(),level()}]}. -i() -> - i(term). - --spec i(term) -> #{logger=>config(), - handlers=>[{handler_id(),module(),config()}], - module_levels=>[{module(),level()}]}; - (print) -> ok; - (string) -> iolist(). -i(_Action = print) -> - io:put_chars(i(string)); -i(_Action = string) -> - #{logger := #{level := Level, - filters := Filters, - filter_default := FilterDefault}, - handlers := HandlerConfigs, - module_levels := Modules} = i(term), - [io_lib:format("Current logger configuration:~n", []), - io_lib:format(" Level: ~p~n",[Level]), - io_lib:format(" Filter Default: ~p~n", [FilterDefault]), - io_lib:format(" Filters: ~n", []), - print_filters(4, Filters), - io_lib:format(" Handlers: ~n", []), - print_handlers(HandlerConfigs), - io_lib:format(" Level set per module: ~n", []), - print_module_levels(Modules) - ]; -i(_Action = term) -> - {Logger, Handlers, Modules} = logger_config:get(tid()), - #{logger=>maps:remove(handlers,Logger), - handlers=>lists:keysort(1,Handlers), - module_levels=>lists:keysort(1,Modules)}. - -print_filters(Indent, {Id, {Fun, Config}}) -> - io_lib:format("~sId: ~p~n" - "~s Fun: ~p~n" - "~s Config: ~p~n",[Indent, Id, Indent, Fun, Indent, Config]); -print_filters(Indent, Filters) -> - IndentStr = io_lib:format("~.*s",[Indent, ""]), - lists:map(fun(Filter) ->print_filters(IndentStr, Filter) end, Filters). - - -print_handlers({Id,Module, - #{level := Level, - filters := Filters, filter_default := FilterDefault, - formatter := {FormatterModule,FormatterConfig}} = Config}) -> - MyKeys = [filter_default, filters, formatter, level, id], - UnhandledConfig = maps:filter(fun(Key, _) -> - not lists:member(Key, MyKeys) - end, Config), - Unhandled = lists:map(fun({Key, Value}) -> - io_lib:format(" ~p: ~p~n",[Key, Value]) - end, maps:to_list(UnhandledConfig)), - io_lib:format(" Id: ~p~n" - " Module: ~p~n" - " Level: ~p~n" - " Formatter:~n" - " Module: ~p~n" - " Config: ~p~n" - " Filter Default: ~p~n" - " Filters:~n~s" - " Handler Config:~n" - "~s" - "",[Id, Module, Level, FormatterModule, FormatterConfig, - FilterDefault, print_filters(8, Filters), Unhandled]); -print_handlers(Handlers) -> - lists:map(fun print_handlers/1, Handlers). - -print_module_levels({Module,Level}) -> - io_lib:format(" Module: ~p~n" - " Level: ~p~n", - [Module,Level]); -print_module_levels(ModuleLevels) -> - lists:map(fun print_module_levels/1, ModuleLevels). +-spec get_config() -> #{primary=>primary_config(), + handlers=>[handler_config()], + module_levels=>[{module(),level() | all | none}]}. +get_config() -> + #{primary=>get_primary_config(), + handlers=>get_handler_config(), + module_levels=>lists:keysort(1,get_module_level())}. -spec internal_init_logger() -> ok | {error,term()}. %% This function is responsible for config of the logger @@ -550,13 +530,13 @@ print_module_levels(ModuleLevels) -> %% tree is started. internal_init_logger() -> try - ok = logger:set_logger_config(level, get_logger_level()), - ok = logger:set_logger_config(filter_default, get_logger_filter_default()), + ok = logger:set_primary_config(level, get_logger_level()), + ok = logger:set_primary_config(filter_default, get_primary_filter_default()), - [case logger:add_logger_filter(Id, Filter) of + [case logger:add_primary_filter(Id, Filter) of ok -> ok; {error, Reason} -> throw(Reason) - end || {Id, Filter} <- get_logger_filters()], + end || {Id, Filter} <- get_primary_filters()], _ = [[case logger:set_module_level(Module, Level) of ok -> ok; @@ -677,7 +657,7 @@ get_logger_level() -> throw({logger_level, Level}) end. -get_logger_filter_default() -> +get_primary_filter_default() -> case lists:keyfind(filters,1,get_logger_env()) of {filters,Default,_} -> Default; @@ -685,7 +665,7 @@ get_logger_filter_default() -> log end. -get_logger_filters() -> +get_primary_filters() -> lists:foldl( fun({filters, _, Filters}, _Acc) -> Filters; @@ -700,7 +680,7 @@ init_default_config(Type) when Type==standard_io; element(1,Type)==file -> Env = get_logger_env(), DefaultFormatter = #{formatter=>{?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}}, - DefaultConfig = DefaultFormatter#{logger_std_h=>#{type=>Type}}, + DefaultConfig = DefaultFormatter#{config=>#{type=>Type}}, NewLoggerEnv = case lists:keyfind(default, 2, Env) of {handler, default, Module, Config} -> @@ -731,17 +711,9 @@ init_default_config(Type) -> get_default_handler_filters() -> case application:get_env(kernel, logger_sasl_compatible, false) of true -> - ?DEFAULT_HANDLER_FILTERS([beam,erlang,otp]); + ?DEFAULT_HANDLER_FILTERS([otp]); false -> - Extra = - case application:get_env(kernel, logger_progress_reports, stop) of - log -> - []; - stop -> - [{stop_progress, - {fun logger_filters:progress/2,stop}}] - end, - Extra ++ ?DEFAULT_HANDLER_FILTERS([beam,erlang,otp,sasl]) + ?DEFAULT_HANDLER_FILTERS([otp,sasl]) end. get_logger_env() -> @@ -749,19 +721,14 @@ get_logger_env() -> %%%----------------------------------------------------------------- %%% Internal -do_log(warning,Msg,Meta) -> - do_log_1(error_logger:warning_map(),Msg,Meta); -do_log(Level,Msg,Meta) -> - do_log_1(Level,Msg,Meta). - -do_log_1(Level,Msg,#{mfa:={Module,_,_}}=Meta) -> +do_log(Level,Msg,#{mfa:={Module,_,_}}=Meta) -> case logger_config:allow(?LOGGER_TABLE,Level,Module) of true -> log_allowed(#{},Level,Msg,Meta); false -> ok end; -do_log_1(Level,Msg,Meta) -> +do_log(Level,Msg,Meta) -> case logger_config:allow(?LOGGER_TABLE,Level) of true -> log_allowed(#{},Level,Msg,Meta); diff --git a/lib/kernel/src/logger_backend.erl b/lib/kernel/src/logger_backend.erl index b3cf7d67dd..a73b681e0d 100644 --- a/lib/kernel/src/logger_backend.erl +++ b/lib/kernel/src/logger_backend.erl @@ -28,9 +28,9 @@ %%%----------------------------------------------------------------- %%% The default logger backend log_allowed(Log, Tid) -> - {ok,Config} = logger_config:get(Tid,logger), + {ok,Config} = logger_config:get(Tid,primary), Filters = maps:get(filters,Config,[]), - case apply_filters(logger,Log,Filters,Config) of + case apply_filters(primary,Log,Filters,Config) of stop -> ok; Log1 -> diff --git a/lib/kernel/src/logger_config.erl b/lib/kernel/src/logger_config.erl index 1d35c2e068..7b2148d034 100644 --- a/lib/kernel/src/logger_config.erl +++ b/lib/kernel/src/logger_config.erl @@ -25,7 +25,7 @@ get/2, get/3, get/1, create/3, create/4, set/3, set_module_level/3,unset_module_level/2, - cache_module_level/2, + get_module_level/1,cache_module_level/2, level_to_int/1]). -include("logger_internal.hrl"). @@ -54,7 +54,7 @@ allow(Tid,Level,Module) -> end. allow(Tid,Level) -> - GlobalLevelInt = ets:lookup_element(Tid,?LOGGER_KEY,2), + GlobalLevelInt = ets:lookup_element(Tid,?PRIMARY_KEY,2), level_to_int(Level) =< GlobalLevelInt. exist(Tid,What) -> @@ -71,7 +71,7 @@ get(Tid,What) -> end. get(Tid,What,Level) -> - MS = [{{table_key(What),'$1','$2'}, % logger config + MS = [{{table_key(What),'$1','$2'}, % primary config [{'>=','$1',level_to_int(Level)}], ['$2']}, {{table_key(What),'$1','$2','$3'}, % handler config @@ -94,7 +94,7 @@ set(Tid,What,Config) -> %% Should do this only if the level has actually changed. Possibly %% overwrite instead of delete? case What of - logger -> + primary -> _ = ets:select_delete(Tid,[{{'_',{'$1',cached}}, [{'=/=','$1',LevelInt}], [true]}]), @@ -105,27 +105,38 @@ set(Tid,What,Config) -> ets:update_element(Tid,table_key(What),[{2,LevelInt},{3,Config}]), ok. -set_module_level(Tid,Module,Level) -> - ets:insert(Tid,{Module,level_to_int(Level)}), +set_module_level(Tid,Modules,Level) -> + LevelInt = level_to_int(Level), + [ets:insert(Tid,{Module,LevelInt}) || Module <- Modules], ok. -unset_module_level(Tid,Module) -> - ets:delete(Tid,Module), % should possibley overwrite instead of delete? +%% should possibly overwrite instead of delete? +unset_module_level(Tid,all) -> + MS = [{{'$1','$2'},[{is_atom,'$1'},{is_integer,'$2'}],[true]}], + _ = ets:select_delete(Tid,MS), + ok; +unset_module_level(Tid,Modules) -> + [ets:delete(Tid,Module) || Module <- Modules], ok. +get_module_level(Tid) -> + MS = [{{'$1','$2'},[{is_atom,'$1'},{is_integer,'$2'}],[{{'$1','$2'}}]}], + Modules = ets:select(Tid,MS), + lists:sort([{M,int_to_level(L)} || {M,L} <- Modules]). + cache_module_level(Tid,Module) -> - GlobalLevelInt = ets:lookup_element(Tid,?LOGGER_KEY,2), + GlobalLevelInt = ets:lookup_element(Tid,?PRIMARY_KEY,2), ets:insert_new(Tid,{Module,{GlobalLevelInt,cached}}), ok. get(Tid) -> - {ok,Logger} = get(Tid,logger), + {ok,Primary} = get(Tid,primary), HMS = [{{table_key('$1'),'_','$2','$3'},[],[{{'$1','$3','$2'}}]}], Handlers = ets:select(Tid,HMS), - MMS = [{{'$1','$2'},[{is_atom,'$1'},{is_integer,'$2'}],[{{'$1','$2'}}]}], - Modules = ets:select(Tid,MMS), - {Logger,Handlers,[{M,int_to_level(L)} || {M,L} <- Modules]}. + Modules = get_module_level(Tid), + {Primary,Handlers,Modules}. +level_to_int(none) -> ?LOG_NONE; level_to_int(emergency) -> ?EMERGENCY; level_to_int(alert) -> ?ALERT; level_to_int(critical) -> ?CRITICAL; @@ -133,8 +144,10 @@ level_to_int(error) -> ?ERROR; level_to_int(warning) -> ?WARNING; level_to_int(notice) -> ?NOTICE; level_to_int(info) -> ?INFO; -level_to_int(debug) -> ?DEBUG. +level_to_int(debug) -> ?DEBUG; +level_to_int(all) -> ?LOG_ALL. +int_to_level(?LOG_NONE) -> none; int_to_level(?EMERGENCY) -> emergency; int_to_level(?ALERT) -> alert; int_to_level(?CRITICAL) -> critical; @@ -142,10 +155,11 @@ int_to_level(?ERROR) -> error; int_to_level(?WARNING) -> warning; int_to_level(?NOTICE) -> notice; int_to_level(?INFO) -> info; -int_to_level(?DEBUG) -> debug. +int_to_level(?DEBUG) -> debug; +int_to_level(?LOG_ALL) -> all. %%%----------------------------------------------------------------- %%% Internal -table_key(logger) -> ?LOGGER_KEY; +table_key(primary) -> ?PRIMARY_KEY; table_key(HandlerId) -> {?HANDLER_KEY,HandlerId}. diff --git a/lib/kernel/src/logger_disk_log_h.erl b/lib/kernel/src/logger_disk_log_h.erl index 773aa75bc6..a074d0210e 100644 --- a/lib/kernel/src/logger_disk_log_h.erl +++ b/lib/kernel/src/logger_disk_log_h.erl @@ -26,16 +26,17 @@ -include("logger_h_common.hrl"). %%% API --export([start_link/3, info/1, disk_log_sync/1, reset/1]). +-export([start_link/3, info/1, sync/1, reset/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% logger callbacks --export([log/2, - adding_handler/1, removing_handler/1, - changing_config/2, swap_buffer/2]). +-export([log/2, adding_handler/1, removing_handler/1, changing_config/2]). + +%% handler internal +-export([log_handler_info/4]). %%%=================================================================== %%% API @@ -47,7 +48,7 @@ %%% handler process gets added (as a result of calling add/3). -spec start_link(Name, Config, HandlerState) -> {ok,Pid} | {error,Reason} when Name :: atom(), - Config :: logger:config(), + Config :: logger:handler_config(), HandlerState :: map(), Pid :: pid(), Reason :: term(). @@ -57,18 +58,19 @@ start_link(Name, Config, HandlerState) -> %%%----------------------------------------------------------------- %%% --spec disk_log_sync(Name) -> ok | {error,Reason} when +-spec sync(Name) -> ok | {error,Reason} when Name :: atom(), Reason :: handler_busy | {badarg,term()}. -disk_log_sync(Name) when is_atom(Name) -> +sync(Name) when is_atom(Name) -> try - gen_server:call(Name, disk_log_sync, ?DEFAULT_CALL_TIMEOUT) + gen_server:call(?name_to_reg_name(?MODULE,Name), + disk_log_sync, ?DEFAULT_CALL_TIMEOUT) catch _:{timeout,_} -> {error,handler_busy} end; -disk_log_sync(Name) -> - {error,{badarg,{disk_log_sync,[Name]}}}. +sync(Name) -> + {error,{badarg,{sync,[Name]}}}. %%%----------------------------------------------------------------- %%% @@ -79,7 +81,8 @@ disk_log_sync(Name) -> info(Name) when is_atom(Name) -> try - gen_server:call(Name, info, ?DEFAULT_CALL_TIMEOUT) + gen_server:call(?name_to_reg_name(?MODULE,Name), + info, ?DEFAULT_CALL_TIMEOUT) catch _:{timeout,_} -> {error,handler_busy} end; @@ -94,7 +97,8 @@ info(Name) -> reset(Name) when is_atom(Name) -> try - gen_server:call(Name, reset, ?DEFAULT_CALL_TIMEOUT) + gen_server:call(?name_to_reg_name(?MODULE,Name), + reset, ?DEFAULT_CALL_TIMEOUT) catch _:{timeout,_} -> {error,handler_busy} end; @@ -112,23 +116,16 @@ adding_handler(#{id:=Name}=Config) -> case check_config(adding, Config) of {ok, Config1} -> %% create initial handler state by merging defaults with config - HConfig = maps:get(?MODULE, Config1, #{}), + HConfig = maps:get(config, Config1, #{}), HState = maps:merge(get_init_state(), HConfig), case logger_h_common:overload_levels_ok(HState) of true -> - case start(Name, Config1, HState) of - ok -> - %% Make sure wait_for_buffer is not stored, so we - %% won't hang and wait for buffer on a restart - {ok, maps:remove(wait_for_buffer,Config1)}; - Error -> - Error - end; + start(Name, Config1, HState); false -> - #{toggle_sync_qlen := TSQL, - drop_new_reqs_qlen := DNRQL, - flush_reqs_qlen := FRQL} = HState, - {error,{invalid_levels,{TSQL,DNRQL,FRQL}}} + #{sync_mode_qlen := SMQL, + drop_mode_qlen := DMQL, + flush_qlen := FQL} = HState, + {error,{invalid_levels,{SMQL,DMQL,FQL}}} end; Error -> Error @@ -136,86 +133,89 @@ adding_handler(#{id:=Name}=Config) -> %%%----------------------------------------------------------------- %%% Updating handler config -changing_config(OldConfig=#{id:=Name, disk_log_opts:=DLOpts}, - NewConfig=#{id:=Name, disk_log_opts:=DLOpts}) -> +changing_config(OldConfig = #{id:=Name, config:=OldHConfig}, + NewConfig = #{id:=Name, config:=NewHConfig}) -> + #{type:=Type, file:=File, max_no_files:=MaxFs, + max_no_bytes:=MaxBytes} = OldHConfig, + case NewHConfig of + #{type:=Type, file:=File, max_no_files:=MaxFs, + max_no_bytes:=MaxBytes} -> + changing_config1(OldConfig, NewConfig); + _ -> + {error,{illegal_config_change,OldConfig,NewConfig}} + end; +changing_config(OldConfig, NewConfig) -> + {error,{illegal_config_change,OldConfig,NewConfig}}. + +changing_config1(OldConfig=#{config:=OldHConfig}, NewConfig) -> case check_config(changing, NewConfig) of - Result = {ok,NewConfig1} -> - try gen_server:call(Name, {change_config,OldConfig,NewConfig1}, + {ok,NewConfig1 = #{config:=NewHConfig}} -> + #{handler_pid:=HPid, + mode_tab:=ModeTab} = OldHConfig, + NewHConfig1 = NewHConfig#{handler_pid=>HPid, + mode_tab=>ModeTab}, + NewConfig2 = NewConfig1#{config=>NewHConfig1}, + try gen_server:call(HPid, {change_config,OldConfig,NewConfig2}, ?DEFAULT_CALL_TIMEOUT) of - ok -> Result; + ok -> {ok,NewConfig2}; HError -> HError catch _:{timeout,_} -> {error,handler_busy} end; Error -> Error - end; -changing_config(OldConfig, NewConfig) -> - {error,{illegal_config_change,OldConfig,NewConfig}}. + end. check_config(adding, #{id:=Name}=Config) -> - %% Merge in defaults on handler level - LogOpts0 = maps:get(disk_log_opts, Config, #{}), - LogOpts = merge_default_logopts(Name, LogOpts0), - case check_log_opts(maps:to_list(LogOpts)) of + %% merge handler specific config data + HConfig = merge_default_logopts(Name, maps:get(config, Config, #{})), + case check_h_config(maps:to_list(HConfig)) of ok -> - MyConfig = maps:get(?MODULE, Config, #{}), - case check_my_config(maps:to_list(MyConfig)) of - ok -> - {ok,Config#{disk_log_opts=>LogOpts, - ?MODULE=>MyConfig}}; - Error -> - Error - end; + {ok,Config#{config=>HConfig}}; Error -> Error end; check_config(changing, Config) -> - MyConfig = maps:get(?MODULE, Config, #{}), - case check_my_config(maps:to_list(MyConfig)) of + HConfig = maps:get(config, Config, #{}), + case check_h_config(maps:to_list(HConfig)) of ok -> {ok,Config}; Error -> Error end. -merge_default_logopts(Name, LogOpts) -> - Type = maps:get(type, LogOpts, wrap), +merge_default_logopts(Name, HConfig) -> + Type = maps:get(type, HConfig, wrap), {DefaultNoFiles,DefaultNoBytes} = case Type of halt -> {undefined,infinity}; _wrap -> {10,1048576} end, {ok,Dir} = file:get_cwd(), - Default = #{file => filename:join(Dir,Name), - max_no_files => DefaultNoFiles, - max_no_bytes => DefaultNoBytes, - type => Type}, - maps:merge(Default,LogOpts). - -check_log_opts([{file,File}|Opts]) when is_list(File) -> - check_log_opts(Opts); -check_log_opts([{max_no_files,undefined}|Opts]) -> - check_log_opts(Opts); -check_log_opts([{max_no_files,N}|Opts]) when is_integer(N), N>0 -> - check_log_opts(Opts); -check_log_opts([{max_no_bytes,infinity}|Opts]) -> - check_log_opts(Opts); -check_log_opts([{max_no_bytes,N}|Opts]) when is_integer(N), N>0 -> - check_log_opts(Opts); -check_log_opts([{type,Type}|Opts]) when Type==wrap; Type==halt -> - check_log_opts(Opts); -check_log_opts([Invalid|_]) -> - {error,{invalid_config,disk_log_opt,Invalid}}; -check_log_opts([]) -> - ok. - -check_my_config([Other | Config]) -> + Defaults = #{file => filename:join(Dir,Name), + max_no_files => DefaultNoFiles, + max_no_bytes => DefaultNoBytes, + type => Type}, + maps:merge(Defaults, HConfig). + +check_h_config([{file,File}|Config]) when is_list(File) -> + check_h_config(Config); +check_h_config([{max_no_files,undefined}|Config]) -> + check_h_config(Config); +check_h_config([{max_no_files,N}|Config]) when is_integer(N), N>0 -> + check_h_config(Config); +check_h_config([{max_no_bytes,infinity}|Config]) -> + check_h_config(Config); +check_h_config([{max_no_bytes,N}|Config]) when is_integer(N), N>0 -> + check_h_config(Config); +check_h_config([{type,Type}|Config]) when Type==wrap; Type==halt -> + check_h_config(Config); +check_h_config([Other | Config]) -> case logger_h_common:check_common_config(Other) of valid -> - check_my_config(Config); + check_h_config(Config); invalid -> {error,{invalid_config,?MODULE,Other}} end; -check_my_config([]) -> +check_h_config([]) -> ok. %%%----------------------------------------------------------------- @@ -224,86 +224,90 @@ removing_handler(#{id:=Name}) -> stop(Name). %%%----------------------------------------------------------------- -%%% Get buffer when swapping from simple handler -swap_buffer(Name,Buffer) -> - case whereis(Name) of - undefined -> - ok; - _ -> - Name ! {buffer,Buffer} - end. - -%%%----------------------------------------------------------------- %%% Log a string or report -spec log(LogEvent, Config) -> ok | dropped when LogEvent :: logger:log_event(), - Config :: logger:config(). + Config :: logger:handler_config(). -log(LogEvent,Config=#{id:=Name}) -> - %% if the handler has crashed, we must drop this request +log(LogEvent, Config = #{id := Name, + config := #{handler_pid := HPid, + mode_tab := ModeTab}}) -> + %% if the handler has crashed, we must drop this event %% and hope the handler restarts so we can try again - true = is_pid(whereis(Name)), - Bin = logger_h_common:log_to_binary(LogEvent,Config), - logger_h_common:call_cast_or_drop(Name, Bin). - + true = is_process_alive(HPid), + Bin = logger_h_common:log_to_binary(LogEvent, Config), + logger_h_common:call_cast_or_drop(Name, HPid, ModeTab, Bin). %%%=================================================================== %%% gen_server callbacks %%%=================================================================== -init([Name, Config = #{disk_log_opts := LogOpts}, +init([Name, + Config = #{config := HConfig = #{file:=File, + type:=Type, + max_no_bytes:=MNB, + max_no_files:=MNF}}, State = #{dl_sync_int := DLSyncInt}]) -> - register(Name, self()), + + register(?name_to_reg_name(?MODULE,Name), self()), process_flag(trap_exit, true), process_flag(message_queue_data, off_heap), ?init_test_hooks(), ?start_observation(Name), - - case open_disk_log(Name, LogOpts) of + + LogOpts = #{file=>File, type=>Type, max_no_bytes=>MNB, max_no_files=>MNF}, + case open_disk_log(Name, File, Type, MNB, MNF) of ok -> - catch ets:new(Name, [public, named_table]), - ?set_mode(Name, async), - proc_lib:init_ack({ok,self()}), - T0 = ?timestamp(), - State1 = - ?merge_with_stats(State#{id => Name, - mode => async, - dl_sync => DLSyncInt, - log_opts => LogOpts, - last_qlen => 0, - last_log_ts => T0, - burst_win_ts => T0, - burst_msg_count => 0, - last_op => sync, - prev_log_result => ok, - prev_sync_result => ok, - prev_disk_log_info => undefined}), - gen_server:cast(self(), repeated_disk_log_sync), - enter_loop(Config, State1); + try ets:new(Name, [public]) of + ModeTab -> + ?set_mode(ModeTab, async), + T0 = ?timestamp(), + State1 = + ?merge_with_stats(State#{ + id => Name, + mode_tab => ModeTab, + mode => async, + dl_sync => DLSyncInt, + log_opts => LogOpts, + last_qlen => 0, + last_log_ts => T0, + burst_win_ts => T0, + burst_msg_count => 0, + last_op => sync, + prev_log_result => ok, + prev_sync_result => ok, + prev_disk_log_info => undefined}), + Config1 = + Config#{config => HConfig#{handler_pid => self(), + mode_tab => ModeTab}}, + proc_lib:init_ack({ok,self(),Config1}), + gen_server:cast(self(), repeated_disk_log_sync), + case logger_h_common:unset_restart_flag(Name, ?MODULE) of + true -> + %% inform about restart + gen_server:cast(self(), {log_handler_info, + "Handler ~p restarted", + [Name]}); + false -> + %% initial start + ok + end, + enter_loop(Config1, State1) + catch + _:Error -> + logger_h_common:error_notify({open_disk_log,Name,Error}), + proc_lib:init_ack(Error) + end; Error -> logger_h_common:error_notify({open_disk_log,Name,Error}), proc_lib:init_ack(Error) end. -enter_loop(#{wait_for_buffer:=true}=Config,State) -> - State1 = - receive - {buffer,Buffer} -> - lists:foldl( - fun(Log,S) -> - Bin = logger_h_common:log_to_binary(Log,Config), - {_,S1} = do_log(Bin,cast,S), - S1 - end, - State, - Buffer) - end, - gen_server:enter_loop(?MODULE,[],State1); enter_loop(_Config,State) -> gen_server:enter_loop(?MODULE,[],State). -%% This is the synchronous log request. +%% This is the synchronous log event. handle_call({log, Bin}, _From, State) -> {Result,State1} = do_log(Bin, call, State), %% Result == ok | dropped @@ -315,10 +319,10 @@ handle_call(disk_log_sync, _From, State = #{id := Name}) -> handle_call({change_config,_OldConfig,NewConfig}, _From, State = #{filesync_repeat_interval := FSyncInt0}) -> - HConfig = maps:get(?MODULE, NewConfig, #{}), - State1 = #{toggle_sync_qlen := TSQL, - drop_new_reqs_qlen := DNRQL, - flush_reqs_qlen := FRQL} = maps:merge(State, HConfig), + HConfig = maps:get(config, NewConfig, #{}), + State1 = #{sync_mode_qlen := SMQL, + drop_mode_qlen := DMQL, + flush_qlen := FQL} = maps:merge(State, HConfig), case logger_h_common:overload_levels_ok(State1) of true -> _ = @@ -339,7 +343,7 @@ handle_call({change_config,_OldConfig,NewConfig}, _From, end, {reply, ok, State1}; false -> - {reply, {error,{invalid_levels,{TSQL,DNRQL,FRQL}}}, State} + {reply, {error,{invalid_levels,{SMQL,DMQL,FQL}}}, State} end; handle_call(info, _From, State) -> @@ -357,15 +361,19 @@ handle_call(stop, _From, State) -> {stop, {shutdown,stopped}, ok, State}. -%% This is the asynchronous log request. +%% This is the asynchronous log event. handle_cast({log, Bin}, State) -> {_,State1} = do_log(Bin, cast, State), {noreply, State1}; +handle_cast({log_handler_info, Format, Args}, State = #{id:=Name}) -> + log_handler_info(Name, Format, Args, State), + {noreply, State}; + %% If FILESYNC_REPEAT_INTERVAL is set to a millisec value, this %% clause gets called repeatedly by the handler. In order to %% guarantee that a filesync *always* happens after the last log -%% request, the repeat operation must be active! +%% event, the repeat operation must be active! handle_cast(repeated_disk_log_sync, State = #{id := Name, filesync_repeat_interval := FSyncInt, @@ -429,19 +437,19 @@ code_change(_OldVsn, State, _Extra) -> %%%----------------------------------------------------------------- %%% get_init_state() -> - #{toggle_sync_qlen => ?TOGGLE_SYNC_QLEN, - drop_new_reqs_qlen => ?DROP_NEW_REQS_QLEN, - flush_reqs_qlen => ?FLUSH_REQS_QLEN, - enable_burst_limit => ?ENABLE_BURST_LIMIT, - burst_limit_size => ?BURST_LIMIT_SIZE, - burst_window_time => ?BURST_WINDOW_TIME, - enable_kill_overloaded => ?ENABLE_KILL_OVERLOADED, - handler_overloaded_qlen => ?HANDLER_OVERLOADED_QLEN, - handler_overloaded_mem => ?HANDLER_OVERLOADED_MEM, - handler_restart_after => ?HANDLER_RESTART_AFTER, - dl_sync_int => ?CONTROLLER_SYNC_INTERVAL, - filesync_ok_qlen => ?FILESYNC_OK_QLEN, - filesync_repeat_interval => ?FILESYNC_REPEAT_INTERVAL}. + #{sync_mode_qlen => ?SYNC_MODE_QLEN, + drop_mode_qlen => ?DROP_MODE_QLEN, + flush_qlen => ?FLUSH_QLEN, + burst_limit_enable => ?BURST_LIMIT_ENABLE, + burst_limit_max_count => ?BURST_LIMIT_MAX_COUNT, + burst_limit_window_time => ?BURST_LIMIT_WINDOW_TIME, + overload_kill_enable => ?OVERLOAD_KILL_ENABLE, + overload_kill_qlen => ?OVERLOAD_KILL_QLEN, + overload_kill_mem_size => ?OVERLOAD_KILL_MEM_SIZE, + overload_kill_restart_after => ?OVERLOAD_KILL_RESTART_AFTER, + dl_sync_int => ?CONTROLLER_SYNC_INTERVAL, + filesync_ok_qlen => ?FILESYNC_OK_QLEN, + filesync_repeat_interval => ?FILESYNC_REPEAT_INTERVAL}. %%%----------------------------------------------------------------- %%% Add a disk_log handler to the logger. @@ -449,22 +457,21 @@ get_init_state() -> %%% exist if the handler is registered with logger (and should not %%% exist if the handler is not registered). %%% -%%% Config is the logger:config() map containing a sub map with any of -%%% the following associations: +%%% Config is the logger:handler_config() map. Handler specific parameters +%%% should be provided with a sub map associated with a key named +%%% 'config', e.g: %%% -%%% Config = #{disk_log_opts => #{file => file:filename(), -%%% max_no_bytes => integer(), -%%% max_no_files => integer(), -%%% type => wrap | halt}}. +%%% Config = #{config => #{sync_mode_qlen => 50} %%% -%%% This map will be merged with the logger configuration data for -%%% the disk_log LogName. If type == halt, then max_no_files is -%%% ignored. +%%% The 'config' sub map will also contain parameters for configuring +%%% the disk_log: %%% -%%% Handler specific config should be provided with a sub map associated -%%% with a key named the same as this module, e.g: +%%% Config = #{config => #{file => file:filename(), +%%% max_no_bytes => integer(), +%%% max_no_files => integer(), +%%% type => wrap | halt}}. %%% -%%% Config = #{logger_disk_log_h => #{toggle_sync_qlen => 50} +%%% If type == halt, then max_no_files is ignored. %%% %%% The disk_log handler process is linked to logger_sup, which is %%% part of the kernel application's supervision tree. @@ -477,8 +484,8 @@ start(Name, Config, HandlerState) -> type => worker, modules => [?MODULE]}, case supervisor:start_child(logger_sup, LoggerDLH) of - {ok,_} -> - ok; + {ok,_Pid,Config1} -> + {ok,Config1}; Error -> Error end. @@ -486,16 +493,16 @@ start(Name, Config, HandlerState) -> %%%----------------------------------------------------------------- %%% Stop and remove the handler. stop(Name) -> - case whereis(Name) of + case whereis(?name_to_reg_name(?MODULE,Name)) of undefined -> ok; - _ -> + Pid -> %% We don't want to do supervisor:terminate_child here %% since we need to distinguish this explicit stop from a %% system termination in order to avoid circular attempts %% at removing the handler (implying deadlocks and %% timeouts). - _ = gen_server:call(Name,stop), + _ = gen_server:call(Pid, stop), _ = supervisor:delete_child(logger_sup, Name), ok end. @@ -506,21 +513,31 @@ stop(Name) -> if C == 0 -> Interval; true -> C-1 end). -%% check for overload between every request (and set Mode to async, +%% check for overload between every event (and set Mode to async, %% sync or drop accordingly), but never flush the whole mailbox -%% before LogWindowSize requests have been handled -do_log(Bin, CallOrCast, State = #{id:=Name, mode := _Mode0}) -> +%% before LogWindowSize events have been handled +do_log(Bin, CallOrCast, State = #{id:=Name, mode := Mode0}) -> T1 = ?timestamp(), %% check if the handler is getting overloaded, or if it's %% recovering from overload (the check must be done for each - %% request to react quickly to large bursts of requests and + %% event to react quickly to large bursts of events and %% to ensure that the handler can never end up in drop mode %% with an empty mailbox, which would stop operation) {Mode1,QLen,Mem,State1} = logger_h_common:check_load(State), + if (Mode1 == drop) andalso (Mode0 =/= drop) -> + log_handler_info(Name, "Handler ~p switched to drop mode", + [Name], State); + (Mode0 == drop) andalso ((Mode1 == async) orelse (Mode1 == sync)) -> + log_handler_info(Name, "Handler ~p switched to ~w mode", + [Name,Mode1], State); + true -> + ok + end, + %% kill the handler if it can't keep up with the load - logger_h_common:kill_if_choked(Name, QLen, Mem, State), + logger_h_common:kill_if_choked(Name, QLen, Mem, ?MODULE, State), if Mode1 == flush -> flush(Name, QLen, T1, State1); @@ -530,10 +547,14 @@ do_log(Bin, CallOrCast, State = #{id:=Name, mode := _Mode0}) -> %% this function is called by do_log/3 after an overload check %% has been performed, where QLen > FlushQLen -flush(Name, _QLen0, T1, State=#{last_log_ts := _T0}) -> +flush(Name, _QLen0, T1, State=#{last_log_ts := _T0, mode_tab := ModeTab}) -> %% flush messages in the mailbox (a limited number in %% order to not cause long delays) - _NewFlushed = logger_h_common:flush_log_requests(?FLUSH_MAX_N), + NewFlushed = logger_h_common:flush_log_events(?FLUSH_MAX_N), + + %% write info in log about flushed messages + log_handler_info(Name, "Handler ~p flushed ~w log events", + [Name,NewFlushed], State), %% because of the receive loop when flushing messages, the %% handler will be scheduled out often and the mailbox could @@ -541,26 +562,27 @@ flush(Name, _QLen0, T1, State=#{last_log_ts := _T0}) -> {_,_QLen1} = process_info(self(), message_queue_len), ?observe(Name,{max_qlen,_QLen1}), - %% Add 1 for the current log request - ?observe(Name,{flushed,_NewFlushed+1}), + %% Add 1 for the current log event + ?observe(Name,{flushed,NewFlushed+1}), State1 = ?update_max_time(?diff_time(T1,_T0),State), - {dropped,?update_other(flushed,FLUSHED,_NewFlushed, - State1#{mode => ?set_mode(Name,async), + {dropped,?update_other(flushed,FLUSHED,NewFlushed, + State1#{mode => ?set_mode(ModeTab,async), last_qlen => 0, last_log_ts => T1})}. %% this function is called to write to disk_log write(Name, Mode, T1, Bin, _CallOrCast, - State = #{dl_sync := DLSync, + State = #{mode_tab := ModeTab, + dl_sync := DLSync, dl_sync_int := DLSyncInt, last_qlen := LastQLen, last_log_ts := T0}) -> %% check if we need to limit the number of writes - %% during a burst of log requests + %% during a burst of log events {DoWrite,BurstWinT,BurstMsgCount} = logger_h_common:limit_burst(State), - %% only send a synhrounous request to the disk_log process + %% only send a synhrounous event to the disk_log process %% every DLSyncInt time, to give the handler time between %% writes so it can keep up with incoming messages {Status,LastQLen1,State1} = @@ -578,18 +600,18 @@ write(Name, Mode, T1, Bin, _CallOrCast, {dropped, LastQLen, State} end, - %% Check if the time since the previous log request is long enough - + %% Check if the time since the previous log event is long enough - %% and the queue length small enough - to assume the mailbox has %% been emptied, and if so, do filesync operation and reset mode to %% async. Note that this is the best we can do to detect an idle %% handler without setting a timer after each log call/cast. If the - %% time between two consecutive log requests is fast and no new - %% request comes in after the last one, idle state won't be detected! + %% time between two consecutive log events is fast and no new + %% event comes in after the last one, idle state won't be detected! Time = ?diff_time(T1,T0), {Mode1,BurstMsgCount1,State2} = if (LastQLen1 < ?FILESYNC_OK_QLEN) andalso (Time > ?IDLE_DETECT_TIME_USEC) -> - {?change_mode(Name,Mode,async), 0, disk_log_sync(Name,State1)}; + {?change_mode(ModeTab,Mode,async), 0, disk_log_sync(Name,State1)}; true -> {Mode, BurstMsgCount,State1} end, @@ -607,11 +629,21 @@ write(Name, Mode, T1, Bin, _CallOrCast, {Status,State4}. -open_disk_log(Name, LogOpts) -> - #{file := File, - max_no_bytes := MaxNoBytes, - max_no_files := MaxNoFiles, - type := Type} = LogOpts, +log_handler_info(Name, Format, Args, State) -> + Config = + case logger:get_handler_config(Name) of + {ok,Conf} -> Conf; + _ -> #{formatter=>{?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}} + end, + Meta = #{time=>erlang:system_time(microsecond)}, + Bin = logger_h_common:log_to_binary(#{level => notice, + msg => {Format,Args}, + meta => Meta}, Config), + _ = disk_log_write(Name, Bin, State), + ok. + + +open_disk_log(Name, File, Type, MaxNoBytes, MaxNoFiles) -> case filelib:ensure_dir(File) of ok -> Size = diff --git a/lib/kernel/src/logger_formatter.erl b/lib/kernel/src/logger_formatter.erl index 4d727b3da0..33b250eef6 100644 --- a/lib/kernel/src/logger_formatter.erl +++ b/lib/kernel/src/logger_formatter.erl @@ -35,7 +35,8 @@ template=>template(), time_designator=>byte(), time_offset=>integer()|[byte()]}. --type template() :: [atom()|tuple()|string()]. +-type template() :: [metakey()|{metakey(),template(),template()}|string()]. +-type metakey() :: atom() | [atom()]. %%%----------------------------------------------------------------- %%% API @@ -53,8 +54,8 @@ format(#{level:=Level,msg:=Msg0,meta:=Meta},Config0) [msg|Rest] -> {true,Rest}; _ ->{false,AT0} end, - B = do_format(Level,"",Meta1,BT,Config), - A = do_format(Level,"",Meta1,AT,Config), + B = do_format(Level,Meta1,BT,Config), + A = do_format(Level,Meta1,AT,Config), MsgStr = if DoMsg -> Config1 = @@ -84,26 +85,37 @@ format(#{level:=Level,msg:=Msg0,meta:=Meta},Config0) end, truncate(B ++ MsgStr ++ A,maps:get(max_size,Config)). -do_format(Level,Msg,Data,[level|Format],Config) -> - [to_string(level,Level,Config)|do_format(Level,Msg,Data,Format,Config)]; -do_format(Level,Msg,Data,[Key|Format],Config) when is_atom(Key); is_tuple(Key) -> - Value = value(Key,Data), - [to_string(Key,Value,Config)|do_format(Level,Msg,Data,Format,Config)]; -do_format(Level,Msg,Data,[Str|Format],Config) -> - [Str|do_format(Level,Msg,Data,Format,Config)]; -do_format(_Level,_Msg,_Data,[],_Config) -> +do_format(Level,Data,[level|Format],Config) -> + [to_string(level,Level,Config)|do_format(Level,Data,Format,Config)]; +do_format(Level,Data,[{Key,IfExist,Else}|Format],Config) -> + String = + case value(Key,Data) of + {ok,Value} -> do_format(Level,Data#{Key=>Value},IfExist,Config); + error -> do_format(Level,Data,Else,Config) + end, + [String|do_format(Level,Data,Format,Config)]; +do_format(Level,Data,[Key|Format],Config) + when is_atom(Key) orelse + (is_list(Key) andalso is_atom(hd(Key))) -> + String = + case value(Key,Data) of + {ok,Value} -> to_string(Key,Value,Config); + error -> "" + end, + [String|do_format(Level,Data,Format,Config)]; +do_format(Level,Data,[Str|Format],Config) -> + [Str|do_format(Level,Data,Format,Config)]; +do_format(_Level,_Data,[],_Config) -> []. -value(Key,Meta) when is_atom(Key), is_map(Meta) -> - maps:get(Key,Meta,""); -value(Key,_) when is_atom(Key) -> - ""; -value(Keys,Meta) when is_tuple(Keys) -> - value(tuple_to_list(Keys),Meta); -value([Key|Keys],Meta) -> - value(Keys,value(Key,Meta)); +value(Key,Meta) when is_map_key(Key,Meta) -> + {ok,maps:get(Key,Meta)}; +value([Key|Keys],Meta) when is_map_key(Key,Meta) -> + value(Keys,maps:get(Key,Meta)); value([],Value) -> - Value. + {ok,Value}; +value(_,_) -> + error. to_string(time,Time,Config) -> format_time(Time,Config); @@ -223,7 +235,7 @@ format_mfa(MFA) -> maybe_add_legacy_header(Level, #{time:=Timestamp}=Meta, #{legacy_header:=true}=Config) -> - #{title:=Title}=MyMeta = add_legacy_title(Level,maps:get(?MODULE,Meta,#{})), + #{title:=Title}=MyMeta = add_legacy_title(Level,Meta,Config), {{Y,Mo,D},{H,Mi,S},Micro,UtcStr} = timestamp_to_datetimemicro(Timestamp,Config), Header = @@ -233,11 +245,23 @@ maybe_add_legacy_header(Level, maybe_add_legacy_header(_,Meta,_) -> Meta. -add_legacy_title(_Level,#{title:=_}=MyMeta) -> +add_legacy_title(_Level,#{?MODULE:=#{title:=_}=MyMeta},_) -> MyMeta; -add_legacy_title(Level,MyMeta) -> - Title = string:uppercase(atom_to_list(Level)) ++ " REPORT", - MyMeta#{title=>Title}. +add_legacy_title(Level,Meta,Config) -> + case maps:get(?MODULE,Meta,#{}) of + #{title:=_}=MyMeta -> + MyMeta; + MyMeta -> + TitleLevel = + case (Level=:=notice andalso maps:find(error_logger,Meta)) of + {ok,_} -> + maps:get(error_logger_notice_header,Config); + _ -> + Level + end, + Title = string:uppercase(atom_to_list(TitleLevel)) ++ " REPORT", + MyMeta#{title=>Title} + end. month(1) -> "Jan"; month(2) -> "Feb"; @@ -257,6 +281,7 @@ month(12) -> "Dec". add_default_config(Config0) -> Default = #{legacy_header=>false, + error_logger_notice_header=>info, single_line=>true, chars_limit=>unlimited, time_designator=>$T}, @@ -341,19 +366,15 @@ do_check_config([{single_line,SL}|Config]) when is_boolean(SL) -> do_check_config(Config); do_check_config([{legacy_header,LH}|Config]) when is_boolean(LH) -> do_check_config(Config); +do_check_config([{error_logger_notice_header,ELNH}|Config]) when ELNH == info; + ELNH == notice -> + do_check_config(Config); do_check_config([{report_cb,RCB}|Config]) when is_function(RCB,1) -> do_check_config(Config); -do_check_config([{template,T}|Config]) when is_list(T) -> - case lists:all(fun(X) when is_atom(X) -> true; - (X) when is_tuple(X), is_atom(element(1,X)) -> true; - (X) when is_list(X) -> io_lib:printable_unicode_list(X); - (_) -> false - end, - T) of - true -> - do_check_config(Config); - false -> - {error,{invalid_formatter_template,?MODULE,T}} +do_check_config([{template,T}|Config]) -> + case check_template(T) of + ok -> do_check_config(Config); + error -> {error,{invalid_formatter_template,?MODULE,T}} end; do_check_config([{time_offset,Offset}|Config]) -> case check_offset(Offset) of @@ -381,6 +402,42 @@ check_limit(unlimited) -> check_limit(_) -> error. +check_template([Key|T]) when is_atom(Key) -> + check_template(T); +check_template([Key|T]) when is_list(Key), is_atom(hd(Key)) -> + case lists:all(fun(X) when is_atom(X) -> true; + (_) -> false + end, + Key) of + true -> + check_template(T); + false -> + error + end; +check_template([{Key,IfExist,Else}|T]) + when is_atom(Key) orelse + (is_list(Key) andalso is_atom(hd(Key))) -> + case check_template(IfExist) of + ok -> + case check_template(Else) of + ok -> + check_template(T); + error -> + error + end; + error -> + error + end; +check_template([Str|T]) when is_list(Str) -> + case io_lib:printable_unicode_list(Str) of + true -> check_template(T); + false -> error + end; +check_template([]) -> + ok; +check_template(_) -> + error. + check_offset(I) when is_integer(I) -> ok; check_offset(Tz) when Tz=:=""; Tz=:="Z"; Tz=:="z" -> diff --git a/lib/kernel/src/logger_h_common.erl b/lib/kernel/src/logger_h_common.erl index 336398cd4a..d556938f02 100644 --- a/lib/kernel/src/logger_h_common.erl +++ b/lib/kernel/src/logger_h_common.erl @@ -24,13 +24,15 @@ -export([log_to_binary/2, check_common_config/1, - call_cast_or_drop/2, + call_cast_or_drop/4, check_load/1, limit_burst/1, - kill_if_choked/4, - flush_log_requests/0, - flush_log_requests/1, + kill_if_choked/5, + flush_log_events/0, + flush_log_events/1, handler_exit/2, + set_restart_flag/2, + unset_restart_flag/2, cancel_timer/1, stop_or_restart/3, overload_levels_ok/1, @@ -41,7 +43,7 @@ %%% Covert log data on any form to binary -spec log_to_binary(LogEvent,Config) -> LogString when LogEvent :: logger:log_event(), - Config :: logger:config(), + Config :: logger:handler_config(), LogString :: binary(). log_to_binary(#{msg:={report,_},meta:=#{report_cb:=_}}=Log,Config) -> do_log_to_binary(Log,Config); @@ -52,7 +54,8 @@ log_to_binary(Log,Config) -> do_log_to_binary(Log,Config). do_log_to_binary(Log,Config) -> - {Formatter,FormatterConfig} = maps:get(formatter,Config), + {Formatter,FormatterConfig} = + maps:get(formatter,Config,{?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}), String = try_format(Log,Formatter,FormatterConfig), try unicode:characters_to_binary(String) catch _:_ -> @@ -84,29 +87,37 @@ try_format(Log,Formatter,FormatterConfig) -> %%%----------------------------------------------------------------- %%% Check that the configuration term is valid -check_common_config({toggle_sync_qlen,N}) when is_integer(N) -> +check_common_config({mode_tab,_Tid}) -> valid; -check_common_config({drop_new_reqs_qlen,N}) when is_integer(N) -> +check_common_config({handler_pid,Pid}) when is_pid(Pid) -> valid; -check_common_config({flush_reqs_qlen,N}) when is_integer(N) -> + +check_common_config({sync_mode_qlen,N}) when is_integer(N) -> + valid; +check_common_config({drop_mode_qlen,N}) when is_integer(N) -> + valid; +check_common_config({flush_qlen,N}) when is_integer(N) -> valid; -check_common_config({enable_burst_limit,Bool}) when Bool == true; + +check_common_config({burst_limit_enable,Bool}) when Bool == true; Bool == false -> valid; -check_common_config({burst_limit_size,N}) when is_integer(N) -> +check_common_config({burst_limit_max_count,N}) when is_integer(N) -> valid; -check_common_config({burst_window_time,N}) when is_integer(N) -> +check_common_config({burst_limit_window_time,N}) when is_integer(N) -> valid; -check_common_config({enable_kill_overloaded,Bool}) when Bool == true; - Bool == false -> + +check_common_config({overload_kill_enable,Bool}) when Bool == true; + Bool == false -> valid; -check_common_config({handler_overloaded_qlen,N}) when is_integer(N) -> +check_common_config({overload_kill_qlen,N}) when is_integer(N) -> valid; -check_common_config({handler_overloaded_mem,N}) when is_integer(N) -> +check_common_config({overload_kill_mem_size,N}) when is_integer(N) -> valid; -check_common_config({handler_restart_after,NorA}) when is_integer(NorA); - NorA == never -> +check_common_config({overload_kill_restart_after,NorA}) when is_integer(NorA); + NorA == never -> valid; + check_common_config({filesync_repeat_interval,NorA}) when is_integer(NorA); NorA == no_repeat -> valid; @@ -116,16 +127,16 @@ check_common_config(_) -> %%%----------------------------------------------------------------- %%% Overload Protection -call_cast_or_drop(Name, Bin) -> - %% If the handler process is getting overloaded, the log request +call_cast_or_drop(_Name, HandlerPid, ModeTab, Bin) -> + %% If the handler process is getting overloaded, the log event %% will be synchronous instead of asynchronous (slows down the %% logging tempo of a process doing lots of logging. If the - %% handler is choked, drop mode is set and no request will be sent. - try ?get_mode(Name) of + %% handler is choked, drop mode is set and no event will be sent. + try ?get_mode(ModeTab) of async -> - gen_server:cast(Name, {log,Bin}); + gen_server:cast(HandlerPid, {log,Bin}); sync -> - try gen_server:call(Name, {log,Bin}, ?DEFAULT_CALL_TIMEOUT) of + try gen_server:call(HandlerPid, {log,Bin}, ?DEFAULT_CALL_TIMEOUT) of %% if return value from call == dropped, the %% message has been flushed by handler and should %% therefore not be counted as dropped in stats @@ -133,32 +144,50 @@ call_cast_or_drop(Name, Bin) -> dropped -> ok catch _:{timeout,_} -> - ?observe(Name,{dropped,1}) + ?observe(_Name,{dropped,1}) end; drop -> - ?observe(Name,{dropped,1}) + ?observe(_Name,{dropped,1}) catch %% if the ETS table doesn't exist (maybe because of a - %% handler restart), we can only drop the request - _:_ -> ?observe(Name,{dropped,1}) + %% handler restart), we can only drop the event + _:_ -> ?observe(_Name,{dropped,1}) end, ok. handler_exit(_Name, Reason) -> exit(Reason). -check_load(State = #{id:=Name, mode := Mode, - toggle_sync_qlen := ToggleSyncQLen, - drop_new_reqs_qlen := DropNewQLen, - flush_reqs_qlen := FlushQLen}) -> +set_restart_flag(Name, Module) -> + Flag = list_to_atom(lists:concat([Module,"_",Name,"_restarting"])), + spawn(fun() -> + register(Flag, self()), + timer:sleep(infinity) + end), + ok. + +unset_restart_flag(Name, Module) -> + Flag = list_to_atom(lists:concat([Module,"_",Name,"_restarting"])), + case whereis(Flag) of + undefined -> + false; + Pid -> + exit(Pid, kill), + true + end. + +check_load(State = #{id:=_Name, mode_tab := ModeTab, mode := Mode, + sync_mode_qlen := SyncModeQLen, + drop_mode_qlen := DropModeQLen, + flush_qlen := FlushQLen}) -> {_,Mem} = process_info(self(), memory), - ?observe(Name,{max_mem,Mem}), + ?observe(_Name,{max_mem,Mem}), {_,QLen} = process_info(self(), message_queue_len), - ?observe(Name,{max_qlen,QLen}), + ?observe(_Name,{max_qlen,QLen}), %% When the handler process gets scheduled in, it's impossible %% to predict the QLen. We could jump "up" arbitrarily from say %% async to sync, async to drop, sync to flush, etc. However, when - %% the handler process manages the log requests (without flushing), + %% the handler process manages the log events (without flushing), %% one after the other, we will move "down" from drop to sync and %% from sync to async. This way we don't risk getting stuck in %% drop or sync mode with an empty mailbox. @@ -166,33 +195,33 @@ check_load(State = #{id:=Name, mode := Mode, if QLen >= FlushQLen -> {flush, 0,1}; - QLen >= DropNewQLen -> - %% Note that drop mode will force log requests to + QLen >= DropModeQLen -> + %% Note that drop mode will force log events to %% be dropped on the client side (never sent get to %% the handler). IncDrops = if Mode == drop -> 0; true -> 1 end, - {?change_mode(Name, Mode, drop), IncDrops,0}; - QLen >= ToggleSyncQLen -> - {?change_mode(Name, Mode, sync), 0,0}; + {?change_mode(ModeTab, Mode, drop), IncDrops,0}; + QLen >= SyncModeQLen -> + {?change_mode(ModeTab, Mode, sync), 0,0}; true -> - {?change_mode(Name, Mode, async), 0,0} + {?change_mode(ModeTab, Mode, async), 0,0} end, State1 = ?update_other(drops,DROPS,_NewDrops,State), {Mode1, QLen, Mem, ?update_other(flushes,FLUSHES,_NewFlushes, State1#{last_qlen => QLen})}. -limit_burst(#{enable_burst_limit := false}) -> +limit_burst(#{burst_limit_enable := false}) -> {true,0,0}; limit_burst(#{burst_win_ts := BurstWinT0, burst_msg_count := BurstMsgCount, - burst_window_time := BurstWinTime, - burst_limit_size := BurstLimitSz}) -> - if (BurstMsgCount >= BurstLimitSz) -> + burst_limit_window_time := BurstLimitWinTime, + burst_limit_max_count := BurstLimitMaxCnt}) -> + if (BurstMsgCount >= BurstLimitMaxCnt) -> %% the limit for allowed messages has been reached BurstWinT1 = ?timestamp(), case ?diff_time(BurstWinT1,BurstWinT0) of - BurstCheckTime when BurstCheckTime < (BurstWinTime*1000) -> + BurstCheckTime when BurstCheckTime < (BurstLimitWinTime*1000) -> %% we're still within the burst time frame {false,BurstWinT0,BurstMsgCount}; _BurstCheckTime -> @@ -204,38 +233,42 @@ limit_burst(#{burst_win_ts := BurstWinT0, {true,BurstWinT0,BurstMsgCount+1} end. -kill_if_choked(Name, QLen, Mem, - #{enable_kill_overloaded := KillIfOL, - handler_overloaded_qlen := HOLQLen, - handler_overloaded_mem := HOLMem}) -> +kill_if_choked(Name, QLen, Mem, HandlerMod, + State = #{overload_kill_enable := KillIfOL, + overload_kill_qlen := OLKillQLen, + overload_kill_mem_size := OLKillMem}) -> if KillIfOL andalso - ((QLen > HOLQLen) orelse (Mem > HOLMem)) -> + ((QLen > OLKillQLen) orelse (Mem > OLKillMem)) -> + HandlerMod:log_handler_info(Name, + "Handler ~p overloaded and stopping", + [Name], State), + set_restart_flag(Name, HandlerMod), handler_exit(Name, {shutdown,{overloaded,Name,QLen,Mem}}); true -> ok end. -flush_log_requests() -> - flush_log_requests(-1). +flush_log_events() -> + flush_log_events(-1). -flush_log_requests(Limit) -> +flush_log_events(Limit) -> process_flag(priority, high), - Flushed = flush_log_requests(0, Limit), + Flushed = flush_log_events(0, Limit), process_flag(priority, normal), Flushed. -flush_log_requests(Limit, Limit) -> +flush_log_events(Limit, Limit) -> Limit; -flush_log_requests(N, Limit) -> - %% flush log requests but leave other requests, such as +flush_log_events(N, Limit) -> + %% flush log events but leave other events, such as %% file/disk_log_sync, info and change_config, so that these %% have a chance to be processed even under heavy load receive {'$gen_cast',{log,_}} -> - flush_log_requests(N+1, Limit); + flush_log_events(N+1, Limit); {'$gen_call',{Pid,MRef},{log,_}} -> Pid ! {MRef, dropped}, - flush_log_requests(N+1, Limit) + flush_log_events(N+1, Limit) after 0 -> N end. @@ -245,7 +278,7 @@ cancel_timer(TRef) -> timer:cancel(TRef). stop_or_restart(Name, {shutdown,Reason={overloaded,_Name,_QLen,_Mem}}, - #{handler_restart_after := RestartAfter}) -> + #{overload_kill_restart_after := RestartAfter}) -> %% If we're terminating because of an overload situation (see %% logger_h_common:kill_if_choked/4), we need to remove the handler %% and set a restart timer. A separate process must perform this @@ -262,7 +295,7 @@ stop_or_restart(Name, {shutdown,Reason={overloaded,_Name,_QLen,_Mem}}, exit(HandlerPid, kill) end, case logger:get_handler_config(Name) of - {ok,{HMod,HConfig}} when is_integer(RestartAfter) -> + {ok,#{module:=HMod}=HConfig} when is_integer(RestartAfter) -> _ = logger:remove_handler(Name), _ = timer:apply_after(RestartAfter, logger, add_handler, [Name,HMod,HConfig]); @@ -293,10 +326,10 @@ stop_or_restart(_Name, _Reason, _State) -> ok. overload_levels_ok(HandlerConfig) -> - TSQL = maps:get(toggle_sync_qlen, HandlerConfig, ?TOGGLE_SYNC_QLEN), - DNRQL = maps:get(drop_new_reqs_qlen, HandlerConfig, ?DROP_NEW_REQS_QLEN), - FRQL = maps:get(flush_reqs_qlen, HandlerConfig, ?FLUSH_REQS_QLEN), - (DNRQL > 1) andalso (TSQL =< DNRQL) andalso (DNRQL =< FRQL). + SMQL = maps:get(sync_mode_qlen, HandlerConfig, ?SYNC_MODE_QLEN), + DMQL = maps:get(drop_mode_qlen, HandlerConfig, ?DROP_MODE_QLEN), + FQL = maps:get(flush_qlen, HandlerConfig, ?FLUSH_QLEN), + (DMQL > 1) andalso (SMQL =< DMQL) andalso (DMQL =< FQL). error_notify(Term) -> ?internal_log(error, Term). diff --git a/lib/kernel/src/logger_h_common.hrl b/lib/kernel/src/logger_h_common.hrl index ed365ce6eb..ad80b51109 100644 --- a/lib/kernel/src/logger_h_common.hrl +++ b/lib/kernel/src/logger_h_common.hrl @@ -4,47 +4,47 @@ %%! *** NOTE *** %%! It's important that: -%%! TOGGLE_SYNC_QLEN < DROP_NEW_REQS_QLEN < FLUSH_REQS_QLEN -%%! and that DROP_NEW_REQS_QLEN >= 2. +%%! SYNC_MODE_QLEN =< DROP_MODE_QLEN =< FLUSH_QLEN +%%! and that DROP_MODE_QLEN >= 2. %%! Otherwise the handler could end up in drop mode with no new %%! log requests to process. This would cause all future requests %%! to be dropped (no switch to async mode would ever take place). %% This specifies the message_queue_len value where the log %% requests switch from asynchronous casts to synchronous calls. --define(TOGGLE_SYNC_QLEN, 10). +-define(SYNC_MODE_QLEN, 10). %% Above this message_queue_len, log requests will be dropped, %% i.e. no log requests get sent to the handler process. --define(DROP_NEW_REQS_QLEN, 200). +-define(DROP_MODE_QLEN, 200). %% Above this message_queue_len, the handler process will flush %% its mailbox and only leave this number of messages in it. --define(FLUSH_REQS_QLEN, 1000). +-define(FLUSH_QLEN, 1000). %% Never flush more than this number of messages in one go, %% or the handler will be unresponsive for seconds (keep this %% number as large as possible or the mailbox could grow large). -define(FLUSH_MAX_N, 5000). -%% BURST_LIMIT is the max number of log requests allowed to be -%% written within a BURST_WINDOW_TIME time frame. --define(ENABLE_BURST_LIMIT, true). --define(BURST_LIMIT_SIZE, 500). --define(BURST_WINDOW_TIME, 1000). +%% BURST_LIMIT_MAX_COUNT is the max number of log requests allowed +%% to be written within a BURST_LIMIT_WINDOW_TIME time frame. +-define(BURST_LIMIT_ENABLE, true). +-define(BURST_LIMIT_MAX_COUNT, 500). +-define(BURST_LIMIT_WINDOW_TIME, 1000). %% This enables/disables the feature to automatically get the %% handler terminated if it gets too loaded (and can't keep up). --define(ENABLE_KILL_OVERLOADED, false). +-define(OVERLOAD_KILL_ENABLE, false). %% If the message_queue_len goes above this size even after %% flushing has been performed, the handler is terminated. --define(HANDLER_OVERLOADED_QLEN, 20000). +-define(OVERLOAD_KILL_QLEN, 20000). %% If the memory usage exceeds this level --define(HANDLER_OVERLOADED_MEM, 3000000). +-define(OVERLOAD_KILL_MEM_SIZE, 3000000). %% This is the default time that the handler will wait before %% restarting and accepting new requests. The value 'never' %% disables restarts. --define(HANDLER_RESTART_AFTER, 5000). -%%-define(HANDLER_RESTART_AFTER, never). +-define(OVERLOAD_KILL_RESTART_AFTER, 5000). +%%-define(OVERLOAD_KILL_RESTART_AFTER, never). %% The handler sends asynchronous write requests to the process %% controlling the i/o device, but every once in this interval @@ -77,29 +77,30 @@ -define(DISK_LOG_MAX_NO_BYTES, 1048576). %%%----------------------------------------------------------------- +%%% Utility macros + +-define(name_to_reg_name(MODULE,Name), + list_to_atom(lists:concat([MODULE,"_",Name]))). + +%%%----------------------------------------------------------------- %%% Overload protection macros -define(timestamp(), erlang:monotonic_time(microsecond)). --define(get_mode(HandlerName), - case ets:lookup(HandlerName, mode) of - [{mode,sync}] -> - case whereis(HandlerName)==self() of - true -> async; - _ -> sync - end; +-define(get_mode(Tid), + case ets:lookup(Tid, mode) of [{mode,M}] -> M; _ -> async end). --define(set_mode(HandlerName, M), - begin ets:insert(HandlerName, {mode,M}), M end). +-define(set_mode(Tid, M), + begin ets:insert(Tid, {mode,M}), M end). --define(change_mode(HandlerName, M0, M1), +-define(change_mode(Tid, M0, M1), if M0 == M1 -> M0; true -> - ets:insert(HandlerName, {mode,M1}), + ets:insert(Tid, {mode,M1}), M1 end). @@ -124,7 +125,7 @@ %%% slow down execution and therefore should not be include in code %%% to be officially released. --define(TEST_HOOKS, true). +%%-define(TEST_HOOKS, true). -ifdef(TEST_HOOKS). -define(TEST_HOOKS_TAB, logger_h_test_hooks). diff --git a/lib/kernel/src/logger_internal.hrl b/lib/kernel/src/logger_internal.hrl index fedd6db370..8941409a25 100644 --- a/lib/kernel/src/logger_internal.hrl +++ b/lib/kernel/src/logger_internal.hrl @@ -19,12 +19,11 @@ %% -include_lib("kernel/include/logger.hrl"). -define(LOGGER_TABLE,logger). --define(LOGGER_KEY,'$logger_config$'). +-define(PRIMARY_KEY,'$primary_config$'). -define(HANDLER_KEY,'$handler_config$'). -define(LOGGER_META_KEY,'$logger_metadata$'). -define(STANDARD_HANDLER, default). --define(DEFAULT_HANDLER_FILTERS, - ?DEFAULT_HANDLER_FILTERS([beam,erlang,otp])). +-define(DEFAULT_HANDLER_FILTERS,?DEFAULT_HANDLER_FILTERS([otp])). -define(DEFAULT_HANDLER_FILTERS(Domain), [{remote_gl,{fun logger_filters:remote_gl/2,stop}}, {domain,{fun logger_filters:domain/2,{log,super,Domain}}}, @@ -33,7 +32,7 @@ -define(DEFAULT_FORMAT_CONFIG,#{legacy_header=>true, single_line=>false}). -define(DEFAULT_FORMAT_TEMPLATE_HEADER, - [{logger_formatter,header},"\n",msg,"\n"]). + [[logger_formatter,header],"\n",msg,"\n"]). -define(DEFAULT_FORMAT_TEMPLATE_SINGLE, [time," ",level,": ",msg,"\n"]). -define(DEFAULT_FORMAT_TEMPLATE, @@ -55,14 +54,17 @@ %%%----------------------------------------------------------------- %%% Levels %%% Using same as syslog --define(LEVELS,[emergency, +-define(LEVELS,[none, + emergency, alert, critical, error, warning, notice, info, - debug]). + debug, + all]). +-define(LOG_NONE,-1). -define(EMERGENCY,0). -define(ALERT,1). -define(CRITICAL,2). @@ -71,6 +73,7 @@ -define(NOTICE,5). -define(INFO,6). -define(DEBUG,7). +-define(LOG_ALL,10). -define(IS_LEVEL(L), (L=:=emergency orelse diff --git a/lib/kernel/src/logger_server.erl b/lib/kernel/src/logger_server.erl index 47010c9fa5..e50954fc40 100644 --- a/lib/kernel/src/logger_server.erl +++ b/lib/kernel/src/logger_server.erl @@ -25,8 +25,8 @@ -export([start_link/0, add_handler/3, remove_handler/1, add_filter/2, remove_filter/2, - set_module_level/2, unset_module_level/1, - cache_module_level/1, + set_module_level/2, unset_module_level/0, + unset_module_level/1, cache_module_level/1, set_config/2, set_config/3, update_config/2, update_formatter_config/2]). @@ -53,7 +53,7 @@ add_handler(Id,Module,Config0) -> {ok,ok} -> case sanity_check(Id,Config0) of ok -> - Default = default_config(Id), + Default = default_config(Id,Module), Config = maps:merge(Default,Config0), call({add_handler,Id,Module,Config}); Error -> @@ -75,30 +75,41 @@ add_filter(Owner,Filter) -> remove_filter(Owner,FilterId) -> call({remove_filter,Owner,FilterId}). -set_module_level(Module,Level) when is_atom(Module) -> - case sanity_check(logger,level,Level) of - ok -> call({set_module_level,Module,Level}); - Error -> Error +set_module_level(Modules,Level) when is_list(Modules) -> + case lists:all(fun(M) -> is_atom(M) end,Modules) of + true -> + case sanity_check(primary,level,Level) of + ok -> call({set_module_level,Modules,Level}); + Error -> Error + end; + false -> + {error,{not_a_list_of_modles,Modules}} end; -set_module_level(Module,_) -> - {error,{not_a_module,Module}}. +set_module_level(Modules,_) -> + {error,{not_a_list_of_modules,Modules}}. + +unset_module_level() -> + call({unset_module_level,all}). -unset_module_level(Module) when is_atom(Module) -> - call({unset_module_level,Module}); -unset_module_level(Module) -> - {error,{not_a_module,Module}}. +unset_module_level(Modules) when is_list(Modules) -> + case lists:all(fun(M) -> is_atom(M) end,Modules) of + true -> + call({unset_module_level,Modules}); + false -> + {error,{not_a_list_of_modles,Modules}} + end; +unset_module_level(Modules) -> + {error,{not_a_list_of_modules,Modules}}. cache_module_level(Module) -> gen_server:cast(?SERVER,{cache_module_level,Module}). - set_config(Owner,Key,Value) -> update_config(Owner,#{Key=>Value}). -set_config(Owner,Config0) -> - case sanity_check(Owner,Config0) of +set_config(Owner,Config) -> + case sanity_check(Owner,Config) of ok -> - Config = maps:merge(default_config(Owner),Config0), call({set_config,Owner,Config}); Error -> Error @@ -125,11 +136,12 @@ update_formatter_config(_HandlerId, FormatterConfig) -> init([]) -> process_flag(trap_exit, true), + put(?LOGGER_SERVER_TAG,true), Tid = logger_config:new(?LOGGER_TABLE), - LoggerConfig = maps:merge(default_config(logger), + PrimaryConfig = maps:merge(default_config(primary), #{handlers=>[simple]}), - logger_config:create(Tid,logger,LoggerConfig), - SimpleConfig0 = maps:merge(default_config(simple), + logger_config:create(Tid,primary,PrimaryConfig), + SimpleConfig0 = maps:merge(default_config(simple,logger_simple_h), #{filter_default=>stop, filters=>?DEFAULT_HANDLER_FILTERS}), %% If this fails, then the node should crash @@ -154,9 +166,9 @@ handle_call({add_handler,Id,Module,HConfig}, From, #state{tid=Tid}=State) -> case erlang:function_exported(Module, log, 2) of true -> logger_config:create(Tid,Id,Module,HConfig1), - {ok,Config} = do_get_config(Tid,logger), + {ok,Config} = do_get_config(Tid,primary), Handlers = maps:get(handlers,Config,[]), - do_set_config(Tid,logger, + do_set_config(Tid,primary, Config#{handlers=>[Id|Handlers]}); false -> {error,{invalid_handler, @@ -170,7 +182,7 @@ handle_call({add_handler,Id,Module,HConfig}, From, #state{tid=Tid}=State) -> handle_call({remove_handler,HandlerId}, From, #state{tid=Tid}=State) -> case logger_config:get(Tid,HandlerId) of {ok,{Module,HConfig}} -> - {ok,Config} = do_get_config(Tid,logger), + {ok,Config} = do_get_config(Tid,primary), Handlers0 = maps:get(handlers,Config,[]), Handlers = lists:delete(HandlerId,Handlers0), call_h_async( @@ -179,7 +191,7 @@ handle_call({remove_handler,HandlerId}, From, #state{tid=Tid}=State) -> call_h(Module,removing_handler,[HConfig],ok) end, fun(_Res) -> - do_set_config(Tid,logger,Config#{handlers=>Handlers}), + do_set_config(Tid,primary,Config#{handlers=>Handlers}), logger_config:delete(Tid,HandlerId), ok end,From,State); @@ -203,13 +215,15 @@ handle_call({update_config,Id,NewConfig}, From, #state{tid=Tid}=State) -> Error -> {reply,Error,State} end; -handle_call({set_config,logger,Config}, _From, #state{tid=Tid}=State) -> - {ok,#{handlers:=Handlers}} = logger_config:get(Tid,logger), - Reply = do_set_config(Tid,logger,Config#{handlers=>Handlers}), +handle_call({set_config,primary,Config0}, _From, #state{tid=Tid}=State) -> + Config = maps:merge(default_config(primary),Config0), + {ok,#{handlers:=Handlers}} = logger_config:get(Tid,primary), + Reply = do_set_config(Tid,primary,Config#{handlers=>Handlers}), {reply,Reply,State}; -handle_call({set_config,HandlerId,Config}, From, #state{tid=Tid}=State) -> +handle_call({set_config,HandlerId,Config0}, From, #state{tid=Tid}=State) -> case logger_config:get(Tid,HandlerId) of {ok,{Module,OldConfig}} -> + Config = maps:merge(default_config(HandlerId,Module),Config0), call_h_async( fun() -> call_h(Module,changing_config,[OldConfig,Config], @@ -239,11 +253,11 @@ handle_call({update_formatter_config,HandlerId,NewFConfig},_From, {error,{not_found,HandlerId}} end, {reply,Reply,State}; -handle_call({set_module_level,Module,Level}, _From, #state{tid=Tid}=State) -> - Reply = logger_config:set_module_level(Tid,Module,Level), +handle_call({set_module_level,Modules,Level}, _From, #state{tid=Tid}=State) -> + Reply = logger_config:set_module_level(Tid,Modules,Level), {reply,Reply,State}; -handle_call({unset_module_level,Module}, _From, #state{tid=Tid}=State) -> - Reply = logger_config:unset_module_level(Tid,Module), +handle_call({unset_module_level,Modules}, _From, #state{tid=Tid}=State) -> + Reply = logger_config:unset_module_level(Tid,Modules), {reply,Reply,State}. handle_cast({async_req_reply,_Ref,_Reply} = Reply,State) -> @@ -270,7 +284,7 @@ handle_info({Ref,_Reply},State) when is_reference(Ref) -> handle_info({'DOWN',_Ref,_Proc,_Pid,_Reason} = Down,State) -> call_h_reply(Down,State); handle_info(Unexpected,State) when element(1,Unexpected) == 'EXIT' -> - %% The simple logger will send an 'EXIT' message when it is replaced + %% The simple handler will send an 'EXIT' message when it is replaced %% We may as well ignore all 'EXIT' messages that we get ?LOG_INTERNAL(debug, [{logger,got_unexpected_message}, @@ -343,16 +357,18 @@ do_set_config(Tid,Id,Config) -> logger_config:set(Tid,Id,Config), ok. -default_config(logger) -> - #{level=>info, +default_config(primary) -> + #{level=>notice, filters=>[], filter_default=>log}; default_config(Id) -> #{id=>Id, - level=>info, + level=>all, filters=>[], filter_default=>log, formatter=>{?DEFAULT_FORMATTER,#{}}}. +default_config(Id,Module) -> + (default_config(Id))#{module=>Module}. sanity_check(Owner,Key,Value) -> sanity_check_1(Owner,[{Key,Value}]). @@ -369,8 +385,8 @@ sanity_check_1(Owner,Config) when is_list(Config) -> catch throw:Error -> {error,Error} end. -get_type(logger) -> - logger; +get_type(primary) -> + primary; get_type(Id) -> check_id(Id), handler. @@ -387,8 +403,8 @@ check_config(Owner,[{filter_default,FD}|Config]) -> check_config(handler,[{formatter,Formatter}|Config]) -> check_formatter(Formatter), check_config(handler,Config); -check_config(logger,[C|_]) -> - throw({invalid_logger_config,C}); +check_config(primary,[C|_]) -> + throw({invalid_primary_config,C}); check_config(handler,[{_,_}|Config]) -> %% Arbitrary config elements are allowed for handlers check_config(handler,Config); diff --git a/lib/kernel/src/logger_std_h.erl b/lib/kernel/src/logger_std_h.erl index 63c3ab2dac..ce9daa50ab 100644 --- a/lib/kernel/src/logger_std_h.erl +++ b/lib/kernel/src/logger_std_h.erl @@ -28,15 +28,17 @@ -include_lib("kernel/include/file.hrl"). %% API --export([start_link/3, info/1, filesync/1, reset/1]). +-export([start_link/3, info/1, sync/1, reset/1]). %% gen_server and proc_lib callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% logger callbacks --export([log/2, adding_handler/1, removing_handler/1, - changing_config/2, swap_buffer/2]). +-export([log/2, adding_handler/1, removing_handler/1, changing_config/2]). + +%% handler internal +-export([log_handler_info/4]). %%%=================================================================== %%% API @@ -48,7 +50,7 @@ %%% handler process gets added -spec start_link(Name, Config, HandlerState) -> {ok,Pid} | {error,Reason} when Name :: atom(), - Config :: logger:config(), + Config :: logger:handler_config(), HandlerState :: map(), Pid :: pid(), Reason :: term(). @@ -58,18 +60,19 @@ start_link(Name, Config, HandlerState) -> %%%----------------------------------------------------------------- %%% --spec filesync(Name) -> ok | {error,Reason} when +-spec sync(Name) -> ok | {error,Reason} when Name :: atom(), Reason :: handler_busy | {badarg,term()}. -filesync(Name) when is_atom(Name) -> +sync(Name) when is_atom(Name) -> try - gen_server:call(Name, filesync, ?DEFAULT_CALL_TIMEOUT) + gen_server:call(?name_to_reg_name(?MODULE,Name), + filesync, ?DEFAULT_CALL_TIMEOUT) catch _:{timeout,_} -> {error,handler_busy} end; -filesync(Name) -> - {error,{badarg,{filesync,[Name]}}}. +sync(Name) -> + {error,{badarg,{sync,[Name]}}}. %%%----------------------------------------------------------------- %%% @@ -80,7 +83,8 @@ filesync(Name) -> info(Name) when is_atom(Name) -> try - gen_server:call(Name, info, ?DEFAULT_CALL_TIMEOUT) + gen_server:call(?name_to_reg_name(?MODULE,Name), + info, ?DEFAULT_CALL_TIMEOUT) catch _:{timeout,_} -> {error,handler_busy} end; @@ -95,7 +99,8 @@ info(Name) -> reset(Name) when is_atom(Name) -> try - gen_server:call(Name, reset, ?DEFAULT_CALL_TIMEOUT) + gen_server:call(?name_to_reg_name(?MODULE,Name), + reset, ?DEFAULT_CALL_TIMEOUT) catch _:{timeout,_} -> {error,handler_busy} end; @@ -113,23 +118,16 @@ adding_handler(#{id:=Name}=Config) -> case check_config(adding, Config) of {ok, Config1} -> %% create initial handler state by merging defaults with config - HConfig = maps:get(?MODULE, Config1, #{}), + HConfig = maps:get(config, Config1, #{}), HState = maps:merge(get_init_state(), HConfig), case logger_h_common:overload_levels_ok(HState) of true -> - case start(Name, Config1, HState) of - ok -> - %% Make sure wait_for_buffer is not stored, so we - %% won't hang and wait for buffer on a restart - {ok, maps:remove(wait_for_buffer,Config1)}; - Error -> - Error - end; + start(Name, Config1, HState); false -> - #{toggle_sync_qlen := TSQL, - drop_new_reqs_qlen := DNRQL, - flush_reqs_qlen := FRQL} = HState, - {error,{invalid_levels,{TSQL,DNRQL,FRQL}}} + #{sync_mode_qlen := SMQL, + drop_mode_qlen := DMQL, + flush_qlen := FQL} = HState, + {error,{invalid_levels,{SMQL,DMQL,FQL}}} end; Error -> Error @@ -137,24 +135,27 @@ adding_handler(#{id:=Name}=Config) -> %%%----------------------------------------------------------------- %%% Updating handler config -changing_config(OldConfig=#{id:=Name, ?MODULE:=#{type:=Type}}, +changing_config(OldConfig=#{id:=Name, config:=OldHConfig}, NewConfig=#{id:=Name}) -> - MyConfig = maps:get(?MODULE, NewConfig, #{}), - case maps:get(type, MyConfig, Type) of + #{type:=Type, handler_pid:=HPid, mode_tab:=ModeTab} = OldHConfig, + NewHConfig = maps:get(config, NewConfig, #{}), + case maps:get(type, NewHConfig, Type) of Type -> - MyConfig1 = MyConfig#{type=>Type}, - changing_config1(Name, OldConfig, - NewConfig#{?MODULE=>MyConfig1}); + NewHConfig1 = NewHConfig#{type=>Type, + handler_pid=>HPid, + mode_tab=>ModeTab}, + changing_config1(HPid, OldConfig, + NewConfig#{config=>NewHConfig1}); _ -> {error,{illegal_config_change,OldConfig,NewConfig}} end; changing_config(OldConfig, NewConfig) -> {error,{illegal_config_change,OldConfig,NewConfig}}. -changing_config1(Name, OldConfig, NewConfig) -> +changing_config1(HPid, OldConfig, NewConfig) -> case check_config(changing, NewConfig) of Result = {ok,NewConfig1} -> - try gen_server:call(Name, {change_config,OldConfig,NewConfig1}, + try gen_server:call(HPid, {change_config,OldConfig,NewConfig1}, ?DEFAULT_CALL_TIMEOUT) of ok -> Result; HError -> HError @@ -167,38 +168,38 @@ changing_config1(Name, OldConfig, NewConfig) -> check_config(adding, Config) -> %% Merge in defaults on handler level - MyConfig0 = maps:get(?MODULE, Config, #{}), - MyConfig = maps:merge(#{type => standard_io}, - MyConfig0), - case check_my_config(maps:to_list(MyConfig)) of + HConfig0 = maps:get(config, Config, #{}), + HConfig = maps:merge(#{type => standard_io}, + HConfig0), + case check_h_config(maps:to_list(HConfig)) of ok -> - {ok,Config#{?MODULE=>MyConfig}}; + {ok,Config#{config=>HConfig}}; Error -> Error end; check_config(changing, Config) -> - MyConfig = maps:get(?MODULE, Config, #{}), - case check_my_config(maps:to_list(MyConfig)) of + HConfig = maps:get(config, Config, #{}), + case check_h_config(maps:to_list(HConfig)) of ok -> {ok,Config}; Error -> Error end. -check_my_config([{type,Type} | Config]) when Type == standard_io; - Type == standard_error -> - check_my_config(Config); -check_my_config([{type,{file,File}} | Config]) when is_list(File) -> - check_my_config(Config); -check_my_config([{type,{file,File,Modes}} | Config]) when is_list(File), - is_list(Modes) -> - check_my_config(Config); -check_my_config([Other | Config]) -> +check_h_config([{type,Type} | Config]) when Type == standard_io; + Type == standard_error -> + check_h_config(Config); +check_h_config([{type,{file,File}} | Config]) when is_list(File) -> + check_h_config(Config); +check_h_config([{type,{file,File,Modes}} | Config]) when is_list(File), + is_list(Modes) -> + check_h_config(Config); +check_h_config([Other | Config]) -> case logger_h_common:check_common_config(Other) of valid -> - check_my_config(Config); + check_h_config(Config); invalid -> {error,{invalid_config,?MODULE,Other}} end; -check_my_config([]) -> +check_h_config([]) -> ok. @@ -208,35 +209,27 @@ removing_handler(#{id:=Name}) -> stop(Name). %%%----------------------------------------------------------------- -%%% Get buffer when swapping from simple handler -swap_buffer(Name,Buffer) -> - case whereis(Name) of - undefined -> - ok; - _ -> - Name ! {buffer,Buffer} - end. - -%%%----------------------------------------------------------------- %%% Log a string or report -spec log(LogEvent, Config) -> ok | dropped when LogEvent :: logger:log_event(), - Config :: logger:config(). + Config :: logger:handler_config(). -log(LogEvent,Config=#{id:=Name}) -> - %% if the handler has crashed, we must drop this request +log(LogEvent, Config = #{id := Name, + config := #{handler_pid := HPid, + mode_tab := ModeTab}}) -> + %% if the handler has crashed, we must drop this event %% and hope the handler restarts so we can try again - true = is_pid(whereis(Name)), - Bin = logger_h_common:log_to_binary(LogEvent,Config), - logger_h_common:call_cast_or_drop(Name, Bin). + true = is_process_alive(HPid), + Bin = logger_h_common:log_to_binary(LogEvent, Config), + logger_h_common:call_cast_or_drop(Name, HPid, ModeTab, Bin). %%%=================================================================== %%% gen_server callbacks %%%=================================================================== -init([Name, Config, - State0 = #{type := Type, file_ctrl_sync_int := FileCtrlSyncInt}]) -> - register(Name, self()), +init([Name, Config = #{config := HConfig}, + State0 = #{type := Type, file_ctrl_sync_int := FileCtrlSyncInt}]) -> + register(?name_to_reg_name(?MODULE,Name), self()), process_flag(trap_exit, true), process_flag(message_queue_data, off_heap), @@ -245,59 +238,59 @@ init([Name, Config, case do_init(Name, Type) of {ok,InitState} -> - catch ets:new(Name, [public, named_table]), - ?set_mode(Name, async), - State = maps:merge(State0, InitState), - T0 = ?timestamp(), - State1 = - ?merge_with_stats(State#{mode => async, - file_ctrl_sync => FileCtrlSyncInt, - last_qlen => 0, - last_log_ts => T0, - last_op => sync, - burst_win_ts => T0, - burst_msg_count => 0}), - proc_lib:init_ack({ok,self()}), - gen_server:cast(self(), repeated_filesync), - enter_loop(Config, State1); + try ets:new(Name, [public]) of + ModeTab -> + ?set_mode(ModeTab, async), + State = maps:merge(State0, InitState), + T0 = ?timestamp(), + State1 = + ?merge_with_stats(State#{ + mode_tab => ModeTab, + mode => async, + file_ctrl_sync => FileCtrlSyncInt, + last_qlen => 0, + last_log_ts => T0, + last_op => sync, + burst_win_ts => T0, + burst_msg_count => 0}), + Config1 = + Config#{config => HConfig#{handler_pid => self(), + mode_tab => ModeTab}}, + proc_lib:init_ack({ok,self(),Config1}), + gen_server:cast(self(), repeated_filesync), + enter_loop(Config1, State1) + catch + _:Error -> + logger_h_common:error_notify({init_handler,Name,Error}), + proc_lib:init_ack(Error) + end; Error -> logger_h_common:error_notify({init_handler,Name,Error}), proc_lib:init_ack(Error) end. -do_init(Name, Std) when Std=:=standard_io; Std=:=standard_error -> - case open_log_file(Name, Std) of - {ok,FileCtrlPid} -> - {ok,#{id=>Name,type=>Std,file_ctrl_pid=>FileCtrlPid}}; - Error -> - Error - end; -do_init(Name, FileInfo) when is_tuple(FileInfo) -> - case open_log_file(Name, FileInfo) of +do_init(Name, Type) -> + case open_log_file(Name, Type) of {ok,FileCtrlPid} -> - {ok,#{id=>Name,type=>FileInfo,file_ctrl_pid=>FileCtrlPid}}; + case logger_h_common:unset_restart_flag(Name, ?MODULE) of + true -> + %% inform about restart + gen_server:cast(self(), {log_handler_info, + "Handler ~p restarted", + [Name]}); + false -> + %% initial start + ok + end, + {ok,#{id=>Name,type=>Type,file_ctrl_pid=>FileCtrlPid}}; Error -> Error end. -enter_loop(#{wait_for_buffer:=true}=Config,State) -> - State1 = - receive - {buffer,Buffer} -> - lists:foldl( - fun(Log,S) -> - Bin = logger_h_common:log_to_binary(Log,Config), - {_,S1} = do_log(Bin,cast,S), - S1 - end, - State, - Buffer) - end, - gen_server:enter_loop(?MODULE,[],State1); enter_loop(_Config,State) -> gen_server:enter_loop(?MODULE,[],State). -%% This is the synchronous log request. +%% This is the synchronous log event. handle_call({log, Bin}, _From, State) -> {Result,State1} = do_log(Bin, call, State), %% Result == ok | dropped @@ -313,7 +306,7 @@ handle_call(filesync, _From, State = #{type := Type, handle_call({change_config,_OldConfig,NewConfig}, _From, State = #{filesync_repeat_interval := FSyncInt0}) -> - HConfig = maps:get(?MODULE, NewConfig, #{}), + HConfig = maps:get(config, NewConfig, #{}), State1 = maps:merge(State, HConfig), case logger_h_common:overload_levels_ok(State1) of true -> @@ -335,10 +328,10 @@ handle_call({change_config,_OldConfig,NewConfig}, _From, end, {reply, ok, State1}; false -> - #{toggle_sync_qlen := TSQL, - drop_new_reqs_qlen := DNRQL, - flush_reqs_qlen := FRQL} = State1, - {reply, {error,{invalid_levels,{TSQL,DNRQL,FRQL}}}, State} + #{sync_mode_qlen := SMQL, + drop_mode_qlen := DMQL, + flush_qlen := FQL} = State1, + {reply, {error,{invalid_levels,{SMQL,DMQL,FQL}}}, State} end; handle_call(info, _From, State) -> @@ -352,15 +345,19 @@ handle_call(reset, _From, State) -> handle_call(stop, _From, State) -> {stop, {shutdown,stopped}, ok, State}. -%% This is the asynchronous log request. +%% This is the asynchronous log event. handle_cast({log, Bin}, State) -> {_,State1} = do_log(Bin, cast, State), {noreply, State1}; +handle_cast({log_handler_info, Format, Args}, State = #{id:=Name}) -> + log_handler_info(Name, Format, Args, State), + {noreply, State}; + %% If FILESYNC_REPEAT_INTERVAL is set to a millisec value, this %% clause gets called repeatedly by the handler. In order to %% guarantee that a filesync *always* happens after the last log -%% request, the repeat operation must be active! +%% event, the repeat operation must be active! handle_cast(repeated_filesync, State = #{type := Type, file_ctrl_pid := FileCtrlPid, @@ -430,19 +427,19 @@ code_change(_OldVsn, State, _Extra) -> %%%----------------------------------------------------------------- %%% get_init_state() -> - #{toggle_sync_qlen => ?TOGGLE_SYNC_QLEN, - drop_new_reqs_qlen => ?DROP_NEW_REQS_QLEN, - flush_reqs_qlen => ?FLUSH_REQS_QLEN, - enable_burst_limit => ?ENABLE_BURST_LIMIT, - burst_limit_size => ?BURST_LIMIT_SIZE, - burst_window_time => ?BURST_WINDOW_TIME, - enable_kill_overloaded => ?ENABLE_KILL_OVERLOADED, - handler_overloaded_qlen => ?HANDLER_OVERLOADED_QLEN, - handler_overloaded_mem => ?HANDLER_OVERLOADED_MEM, - handler_restart_after => ?HANDLER_RESTART_AFTER, - file_ctrl_sync_int => ?CONTROLLER_SYNC_INTERVAL, - filesync_ok_qlen => ?FILESYNC_OK_QLEN, - filesync_repeat_interval => ?FILESYNC_REPEAT_INTERVAL}. + #{sync_mode_qlen => ?SYNC_MODE_QLEN, + drop_mode_qlen => ?DROP_MODE_QLEN, + flush_qlen => ?FLUSH_QLEN, + burst_limit_enable => ?BURST_LIMIT_ENABLE, + burst_limit_max_count => ?BURST_LIMIT_MAX_COUNT, + burst_limit_window_time => ?BURST_LIMIT_WINDOW_TIME, + overload_kill_enable => ?OVERLOAD_KILL_ENABLE, + overload_kill_qlen => ?OVERLOAD_KILL_QLEN, + overload_kill_mem_size => ?OVERLOAD_KILL_MEM_SIZE, + overload_kill_restart_after => ?OVERLOAD_KILL_RESTART_AFTER, + file_ctrl_sync_int => ?CONTROLLER_SYNC_INTERVAL, + filesync_ok_qlen => ?FILESYNC_OK_QLEN, + filesync_repeat_interval => ?FILESYNC_REPEAT_INTERVAL}. %%%----------------------------------------------------------------- %%% Add a standard handler to the logger. @@ -451,9 +448,9 @@ get_init_state() -> %%% exist if the handler is not registered). %%% %%% Handler specific config should be provided with a sub map associated -%%% with a key named the same as this module, e.g: +%%% with a key named 'config', e.g: %%% -%%% Config = #{logger_std_h => #{toggle_sync_qlen => 50} +%%% Config = #{config => #{sync_mode_qlen => 50} %%% %%% The standard handler process is linked to logger_sup, which is %%% part of the kernel application's supervision tree. @@ -466,8 +463,8 @@ start(Name, Config, HandlerState) -> type => worker, modules => [?MODULE]}, case supervisor:start_child(logger_sup, LoggerStdH) of - {ok,_Pid} -> - ok; + {ok,_Pid,Config1} -> + {ok,Config1}; Error -> Error end. @@ -475,16 +472,16 @@ start(Name, Config, HandlerState) -> %%%----------------------------------------------------------------- %%% Stop and remove the handler. stop(Name) -> - case whereis(Name) of + case whereis(?name_to_reg_name(?MODULE,Name)) of undefined -> ok; - _ -> + Pid -> %% We don't want to do supervisor:terminate_child here %% since we need to distinguish this explicit stop from a %% system termination in order to avoid circular attempts %% at removing the handler (implying deadlocks and %% timeouts). - _ = gen_server:call(Name,stop), + _ = gen_server:call(Pid, stop), _ = supervisor:delete_child(logger_sup, Name), ok end. @@ -495,21 +492,31 @@ stop(Name) -> if C == 0 -> Interval; true -> C-1 end). -%% check for overload between every request (and set Mode to async, +%% check for overload between every event (and set Mode to async, %% sync or drop accordingly), but never flush the whole mailbox -%% before LogWindowSize requests have been handled -do_log(Bin, CallOrCast, State = #{id:=Name}) -> +%% before LogWindowSize events have been handled +do_log(Bin, CallOrCast, State = #{id:=Name, mode:=Mode0}) -> T1 = ?timestamp(), %% check if the handler is getting overloaded, or if it's %% recovering from overload (the check must be done for each - %% request to react quickly to large bursts of requests and + %% event to react quickly to large bursts of events and %% to ensure that the handler can never end up in drop mode %% with an empty mailbox, which would stop operation) {Mode1,QLen,Mem,State1} = logger_h_common:check_load(State), + if (Mode1 == drop) andalso (Mode0 =/= drop) -> + log_handler_info(Name, "Handler ~p switched to drop mode", + [Name], State); + (Mode0 == drop) andalso ((Mode1 == async) orelse (Mode1 == sync)) -> + log_handler_info(Name, "Handler ~p switched to ~w mode", + [Name,Mode1], State); + true -> + ok + end, + %% kill the handler if it can't keep up with the load - logger_h_common:kill_if_choked(Name, QLen, Mem, State), + logger_h_common:kill_if_choked(Name, QLen, Mem, ?MODULE, State), if Mode1 == flush -> flush(Name, QLen, T1, State1); @@ -519,10 +526,14 @@ do_log(Bin, CallOrCast, State = #{id:=Name}) -> %% this clause is called by do_log/3 after an overload check %% has been performed, where QLen > FlushQLen -flush(Name, _QLen0, T1, State=#{last_log_ts := _T0}) -> +flush(Name, _QLen0, T1, State=#{last_log_ts := _T0, mode_tab := ModeTab}) -> %% flush messages in the mailbox (a limited number in %% order to not cause long delays) - _NewFlushed = logger_h_common:flush_log_requests(?FLUSH_MAX_N), + NewFlushed = logger_h_common:flush_log_events(?FLUSH_MAX_N), + + %% write info in log about flushed messages + log_handler_info(Name, "Handler ~p flushed ~w log events", + [Name,NewFlushed], State), %% because of the receive loop when flushing messages, the %% handler will be scheduled out often and the mailbox could @@ -530,50 +541,51 @@ flush(Name, _QLen0, T1, State=#{last_log_ts := _T0}) -> {_,_QLen1} = process_info(self(), message_queue_len), ?observe(Name,{max_qlen,_QLen1}), - %% Add 1 for the current log request - ?observe(Name,{flushed,_NewFlushed+1}), + %% Add 1 for the current log event + ?observe(Name,{flushed,NewFlushed+1}), State1 = ?update_max_time(?diff_time(T1,_T0),State), - {dropped,?update_other(flushed,FLUSHED,_NewFlushed, - State1#{mode => ?set_mode(Name,async), + {dropped,?update_other(flushed,FLUSHED,NewFlushed, + State1#{mode => ?set_mode(ModeTab,async), last_qlen => 0, last_log_ts => T1})}. %% this clause is called to write to file -write(Name, Mode, T1, Bin, _CallOrCast, - State = #{file_ctrl_pid := FileCtrlPid, +write(_Name, Mode, T1, Bin, _CallOrCast, + State = #{mode_tab := ModeTab, + file_ctrl_pid := FileCtrlPid, file_ctrl_sync := FileCtrlSync, last_qlen := LastQLen, last_log_ts := T0, file_ctrl_sync_int := FileCtrlSyncInt}) -> %% check if we need to limit the number of writes - %% during a burst of log requests + %% during a burst of log events {DoWrite,BurstWinT,BurstMsgCount} = logger_h_common:limit_burst(State), - %% only send a synhrounous request to the file controller process + %% only send a synhrounous event to the file controller process %% every FileCtrlSyncInt time, to give the handler time between %% file writes so it can keep up with incoming messages {Result,LastQLen1} = if DoWrite, FileCtrlSync == 0 -> - ?observe(Name,{_CallOrCast,1}), + ?observe(_Name,{_CallOrCast,1}), file_write_sync(FileCtrlPid, Bin, false), {ok,element(2, process_info(self(), message_queue_len))}; DoWrite -> - ?observe(Name,{_CallOrCast,1}), + ?observe(_Name,{_CallOrCast,1}), file_write_async(FileCtrlPid, Bin), {ok,LastQLen}; not DoWrite -> - ?observe(Name,{flushed,1}), + ?observe(_Name,{flushed,1}), {dropped,LastQLen} end, - %% Check if the time since the previous log request is long enough - + %% Check if the time since the previous log event is long enough - %% and the queue length small enough - to assume the mailbox has %% been emptied, and if so, do filesync operation and reset mode to %% async. Note that this is the best we can do to detect an idle %% handler without setting a timer after each log call/cast. If the - %% time between two consecutive log requests is fast and no new - %% request comes in after the last one, idle state won't be detected! + %% time between two consecutive log events is fast and no new + %% event comes in after the last one, idle state won't be detected! Time = ?diff_time(T1,T0), {Mode1,BurstMsgCount1} = if (LastQLen1 < ?FILESYNC_OK_QLEN) andalso @@ -585,7 +597,7 @@ write(Name, Mode, T1, Bin, _CallOrCast, _File -> file_ctrl_filesync_async(FileCtrlPid) end, - {?change_mode(Name, Mode, async),0}; + {?change_mode(ModeTab, Mode, async),0}; true -> {Mode,BurstMsgCount} end, @@ -634,6 +646,20 @@ close_log_file(Fd) -> _ = file:datasync(Fd), _ = file:close(Fd). + +log_handler_info(Name, Format, Args, #{file_ctrl_pid := FileCtrlPid}) -> + Config = + case logger:get_handler_config(Name) of + {ok,Conf} -> Conf; + _ -> #{formatter=>{?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}} + end, + Meta = #{time=>erlang:system_time(microsecond)}, + Bin = logger_h_common:log_to_binary(#{level => notice, + msg => {Format,Args}, + meta => Meta}, Config), + _ = file_write_async(FileCtrlPid, Bin), + ok. + %%%----------------------------------------------------------------- %%% File control process @@ -706,7 +732,7 @@ file_ctrl_init(HandlerName, StdDev, Starter) -> file_ctrl_loop(Fd, Type, DevName, Synced, PrevWriteResult, PrevSyncResult, HandlerName) -> receive - %% asynchronous request + %% asynchronous event {log,Bin} -> Result = if Type == file -> write_to_dev(Fd, Bin, DevName, @@ -717,7 +743,7 @@ file_ctrl_loop(Fd, Type, DevName, Synced, file_ctrl_loop(Fd, Type, DevName, false, Result, PrevSyncResult, HandlerName); - %% synchronous request + %% synchronous event {{log,From,Bin,FileSync},MRef} -> if Type == file -> %% check that file hasn't been deleted @@ -790,7 +816,7 @@ sync_dev(Fd, DevName, PrevSyncResult, HandlerName) -> %% don't report same error twice PrevSyncResult; Error -> - logger_h_common:error_notify({HandlerName,filesync,DevName,Error}), + logger_h_common:error_notify({HandlerName,sync,DevName,Error}), Error end. diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl index 669adefdf8..c4e1a0ce1e 100644 --- a/lib/kernel/src/net_kernel.erl +++ b/lib/kernel/src/net_kernel.erl @@ -53,7 +53,7 @@ %% Documented API functions. --export([allow/1, +-export([allow/1, allowed/0, connect_node/1, monitor_nodes/1, monitor_nodes/2, @@ -171,6 +171,8 @@ kernel_apply(M,F,A) -> request({apply,M,F,A}). Nodes :: [node()]. allow(Nodes) -> request({allow, Nodes}). +allowed() -> request(allowed). + longnames() -> request(longnames). -spec stop() -> ok | {error, Reason} when @@ -528,6 +530,9 @@ handle_call({allow, Nodes}, From, State) -> async_reply({reply,error,State}, From) end; +handle_call(allowed, From, #state{allowed = Allowed} = State) -> + async_reply({reply,{ok,Allowed},State}, From); + %% %% authentication, used by auth. Simply works as this: %% if the message comes through, the other node IS authorized. diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile index 2ad1e3107c..0646395800 100644 --- a/lib/kernel/test/Makefile +++ b/lib/kernel/test/Makefile @@ -71,7 +71,6 @@ MODULES= \ init_SUITE \ kernel_config_SUITE \ logger_SUITE \ - logger_bench_SUITE \ logger_disk_log_h_SUITE \ logger_env_var_SUITE \ logger_filters_SUITE \ diff --git a/lib/kernel/test/error_logger_SUITE.erl b/lib/kernel/test/error_logger_SUITE.erl index 6c4526d0cf..895478f170 100644 --- a/lib/kernel/test/error_logger_SUITE.erl +++ b/lib/kernel/test/error_logger_SUITE.erl @@ -33,7 +33,7 @@ off_heap/1, error_report/1, info_report/1, error/1, info/1, emulator/1, via_logger_process/1, other_node/1, - tty/1, logfile/1, add/1, delete/1]). + tty/1, logfile/1, add/1, delete/1, format_depth/1]). -export([generate_error/2]). @@ -48,7 +48,8 @@ suite() -> all() -> [off_heap, error_report, info_report, error, info, emulator, - via_logger_process, other_node, tty, logfile, add, delete]. + via_logger_process, other_node, tty, logfile, add, delete, + format_depth]. groups() -> []. @@ -309,6 +310,21 @@ delete(Config) when is_list(Config) -> ok. %%----------------------------------------------------------------- + +format_depth(_Config) -> + ok = application:set_env(kernel,error_logger_format_depth,30), + 30 = error_logger:get_format_depth(), + ok = application:set_env(kernel,error_logger_format_depth,3), + 10 = error_logger:get_format_depth(), + ok = application:set_env(kernel,error_logger_format_depth,11), + 11 = error_logger:get_format_depth(), + ok = application:set_env(kernel,error_logger_format_depth,unlimited), + unlimited = error_logger:get_format_depth(), + ok = application:unset_env(kernel,error_logger_format_depth), + unlimited = error_logger:get_format_depth(), + ok. + +%%----------------------------------------------------------------- %% Check that the report has been received. %%----------------------------------------------------------------- reported(Tag, Type, Report) -> diff --git a/lib/kernel/test/kernel.spec b/lib/kernel/test/kernel.spec index 86d2155828..62afc9f97b 100644 --- a/lib/kernel/test/kernel.spec +++ b/lib/kernel/test/kernel.spec @@ -2,4 +2,3 @@ {config, "../test_server/ts.unix.config"}. {suites,"../kernel_test", all}. -{skip_suites,"../kernel_test",[logger_bench_SUITE],"Not ready"}. diff --git a/lib/kernel/test/logger_SUITE.erl b/lib/kernel/test/logger_SUITE.erl index f7ec59a7b7..f837c31e64 100644 --- a/lib/kernel/test/logger_SUITE.erl +++ b/lib/kernel/test/logger_SUITE.erl @@ -50,7 +50,7 @@ init_per_suite(Config) -> end_per_suite(Config) -> case ?config(default_handler,Config) of - {HMod,HConfig} -> + #{module:=HMod} = HConfig -> ok = logger:add_handler(?STANDARD_HANDLER,HMod,HConfig); _ -> ok @@ -63,8 +63,8 @@ end_per_group(_Group, _Config) -> ok. init_per_testcase(_TestCase, Config) -> - {ok,LC} = logger:get_logger_config(), - [{logger_config,LC}|Config]. + PC = logger:get_primary_config(), + [{logger_config,PC}|Config]. end_per_testcase(Case, Config) -> try apply(?MODULE,Case,[cleanup,Config]) @@ -82,11 +82,12 @@ all() -> add_remove_filter, change_config, set_formatter, + log_no_levels, log_all_levels_api, macros, set_level, - set_level_module, - cache_level_module, + set_module_level, + cache_module_level, format_report, filter_failed, handler_failed, @@ -105,29 +106,29 @@ start_stop(_Config) -> add_remove_handler(_Config) -> register(callback_receiver,self()), - #{handlers:=Hs0} = logger:i(), + Hs0 = logger:get_handler_config(), {error,{not_found,h1}} = logger:get_handler_config(h1), ok = logger:add_handler(h1,?MODULE,#{}), [add] = test_server:messages_get(), - #{handlers:=Hs} = logger:i(), - {value,_,Hs0} = lists:keytake(h1,1,Hs), - {ok,{?MODULE,#{level:=info,filters:=[],filter_default:=log}}} = % defaults + Hs = logger:get_handler_config(), + Hs0 = lists:filter(fun(#{id:=h1}) -> false; (_) -> true end, Hs), + {ok,#{module:=?MODULE,level:=all,filters:=[],filter_default:=log}} = %defaults logger:get_handler_config(h1), ok = logger:set_handler_config(h1,filter_default,stop), [changing_config] = test_server:messages_get(), - ?LOG_INFO("hello",[]), + ?LOG_NOTICE("hello",[]), ok = check_no_log(), ok = logger:set_handler_config(h1,filter_default,log), [changing_config] = test_server:messages_get(), - {ok,{?MODULE,#{filter_default:=log}}} = logger:get_handler_config(h1), - ?LOG_INFO("hello",[]), - ok = check_logged(info,"hello",[],?MY_LOC(1)), + {ok,#{filter_default:=log}} = logger:get_handler_config(h1), + ?LOG_NOTICE("hello",[]), + ok = check_logged(notice,"hello",[],?MY_LOC(1)), ok = logger:remove_handler(h1), [remove] = test_server:messages_get(), - #{handlers:=Hs0} = logger:i(), + Hs0 = logger:get_handler_config(), {error,{not_found,h1}} = logger:get_handler_config(h1), {error,{not_found,h1}} = logger:remove_handler(h1), - logger:info("hello",[]), + logger:notice("hello",[]), ok = check_no_log(), ok. @@ -136,13 +137,13 @@ add_remove_handler(cleanup,_Config) -> ok. multiple_handlers(_Config) -> - ok = logger:add_handler(h1,?MODULE,#{level=>info,filter_default=>log}), + ok = logger:add_handler(h1,?MODULE,#{level=>notice,filter_default=>log}), ok = logger:add_handler(h2,?MODULE,#{level=>error,filter_default=>log}), ?LOG_ERROR("hello",[]), ok = check_logged(error,"hello",[],?MY_LOC(1)), ok = check_logged(error,"hello",[],?MY_LOC(2)), - ?LOG_INFO("hello",[]), - ok = check_logged(info,"hello",[],?MY_LOC(1)), + ?LOG_NOTICE("hello",[]), + ok = check_logged(notice,"hello",[],?MY_LOC(1)), ok = check_no_log(), ok. @@ -152,18 +153,18 @@ multiple_handlers(cleanup,_Config) -> ok. add_remove_filter(_Config) -> - ok = logger:add_handler(h1,?MODULE,#{level=>info,filter_default=>log}), + ok = logger:add_handler(h1,?MODULE,#{level=>notice,filter_default=>log}), LF = {fun(Log,_) -> Log#{level=>error} end, []}, - ok = logger:add_logger_filter(lf,LF), - {error,{already_exist,lf}} = logger:add_logger_filter(lf,LF), - {error,{already_exist,lf}} = logger:add_logger_filter(lf,{fun(Log,_) -> - Log - end, []}), - ?LOG_INFO("hello",[]), + ok = logger:add_primary_filter(lf,LF), + {error,{already_exist,lf}} = logger:add_primary_filter(lf,LF), + {error,{already_exist,lf}} = logger:add_primary_filter(lf,{fun(Log,_) -> + Log + end, []}), + ?LOG_NOTICE("hello",[]), ok = check_logged(error,"hello",[],?MY_LOC(1)), ok = check_no_log(), - ok = logger:add_handler(h2,?MODULE,#{level=>info,filter_default=>log}), + ok = logger:add_handler(h2,?MODULE,#{level=>notice,filter_default=>log}), HF = {fun(#{level:=error}=Log,_) -> Log#{level=>mylevel}; (_,_) -> @@ -175,16 +176,16 @@ add_remove_filter(_Config) -> {error,{already_exist,hf}} = logger:add_handler_filter(h1,hf,{fun(Log,_) -> Log end, []}), - ?LOG_INFO("hello",[]), + ?LOG_NOTICE("hello",[]), ok = check_logged(mylevel,"hello",[],?MY_LOC(1)), ok = check_logged(error,"hello",[],?MY_LOC(2)), - ok = logger:remove_logger_filter(lf), - {error,{not_found,lf}} = logger:remove_logger_filter(lf), + ok = logger:remove_primary_filter(lf), + {error,{not_found,lf}} = logger:remove_primary_filter(lf), - ?LOG_INFO("hello",[]), - ok = check_logged(info,"hello",[],?MY_LOC(1)), - ok = check_logged(info,"hello",[],?MY_LOC(2)), + ?LOG_NOTICE("hello",[]), + ok = check_logged(notice,"hello",[],?MY_LOC(1)), + ok = check_logged(notice,"hello",[],?MY_LOC(2)), ?LOG_ERROR("hello",[]), ok = check_logged(mylevel,"hello",[],?MY_LOC(1)), @@ -192,9 +193,9 @@ add_remove_filter(_Config) -> ok = logger:remove_handler_filter(h1,hf), {error,{not_found,hf}} = logger:remove_handler_filter(h1,hf), - ?LOG_INFO("hello",[]), - ok = check_logged(info,"hello",[],?MY_LOC(1)), - ok = check_logged(info,"hello",[],?MY_LOC(2)), + ?LOG_NOTICE("hello",[]), + ok = check_logged(notice,"hello",[],?MY_LOC(1)), + ok = check_logged(notice,"hello",[],?MY_LOC(2)), ?LOG_ERROR("hello",[]), ok = check_logged(error,"hello",[],?MY_LOC(1)), @@ -202,20 +203,20 @@ add_remove_filter(_Config) -> ok. add_remove_filter(cleanup,_Config) -> - logger:remove_logger_filter(lf), + logger:remove_primary_filter(lf), logger:remove_handler(h1), logger:remove_handler(h2), ok. change_config(_Config) -> %% Overwrite handler config - check that defaults are added - ok = logger:add_handler(h1,?MODULE,#{level=>debug,custom=>custom}), - {ok,{?MODULE,#{level:=debug,filter_default:=log,custom:=custom}}} = + ok = logger:add_handler(h1,?MODULE,#{level=>notice,custom=>custom}), + {ok,#{module:=?MODULE,level:=notice,filter_default:=log,custom:=custom}} = logger:get_handler_config(h1), register(callback_receiver,self()), ok = logger:set_handler_config(h1,#{filter_default=>stop}), [changing_config] = test_server:messages_get(), - {ok,{?MODULE,#{level:=info,filter_default:=stop}=C2}} = + {ok,#{module:=?MODULE,level:=all,filter_default:=stop}=C2} = logger:get_handler_config(h1), false = maps:is_key(custom,C2), {error,fail} = logger:set_handler_config(h1,#{conf_call=>fun() -> {error,fail} end}), @@ -225,60 +226,60 @@ change_config(_Config) -> ok = logger:set_handler_config( h1,#{conf_call=>fun() -> logger:set_module_level(?MODULE,debug) end}), - {ok,{?MODULE,C2}} = logger:get_handler_config(h1), + {ok,C2} = logger:get_handler_config(h1), %% Change handler config: Single key {error,fail} = logger:set_handler_config(h1,conf_call,fun() -> {error,fail} end), ok = logger:set_handler_config(h1,custom,custom), [changing_config] = test_server:messages_get(), - {ok,{?MODULE,#{custom:=custom}=C3}} = logger:get_handler_config(h1), + {ok,#{custom:=custom}=C3} = logger:get_handler_config(h1), C2 = maps:remove(custom,C3), %% Change handler config: Map ok = logger:update_handler_config(h1,#{custom=>new_custom}), [changing_config] = test_server:messages_get(), - {ok,{_,C4}} = logger:get_handler_config(h1), + {ok,C4} = logger:get_handler_config(h1), C4 = C3#{custom:=new_custom}, - %% Change logger config: Single key - {ok,LConfig0} = logger:get_logger_config(), - ok = logger:set_logger_config(level,warning), - {ok,LConfig1} = logger:get_logger_config(), - LConfig1 = LConfig0#{level:=warning}, - - %% Change logger config: Map - ok = logger:update_logger_config(#{level=>error}), - {ok,LConfig2} = logger:get_logger_config(), - LConfig2 = LConfig1#{level:=error}, - - %% Overwrite logger config - check that defaults are added - ok = logger:set_logger_config(#{filter_default=>stop}), - {ok,#{level:=info,filters:=[],filter_default:=stop}=LC1} = - logger:get_logger_config(), - 3 = maps:size(LC1), + %% Change primary config: Single key + PConfig0 = logger:get_primary_config(), + ok = logger:set_primary_config(level,warning), + PConfig1 = logger:get_primary_config(), + PConfig1 = PConfig0#{level:=warning}, + + %% Change primary config: Map + ok = logger:update_primary_config(#{level=>error}), + PConfig2 = logger:get_primary_config(), + PConfig2 = PConfig1#{level:=error}, + + %% Overwrite primary config - check that defaults are added + ok = logger:set_primary_config(#{filter_default=>stop}), + #{level:=notice,filters:=[],filter_default:=stop}=PC1 = + logger:get_primary_config(), + 3 = maps:size(PC1), %% Check that internal 'handlers' field has not been changed - #{handlers:=HCs} = logger:i(), - HIds1 = [Id || {Id,_,_} <- HCs], - {ok,#{handlers:=HIds2}} = logger_config:get(?LOGGER_TABLE,logger), - HIds1 = lists:sort(HIds2), + MS = [{{{?HANDLER_KEY,'$1'},'_','_','_'},[],['$1']}], + HIds1 = lists:sort(ets:select(?LOGGER_TABLE,MS)), % dirty, internal data + HIds2 = lists:sort(logger:get_handler_ids()), + HIds1 = HIds2, %% Cleanup - ok = logger:set_logger_config(LConfig0), + ok = logger:set_primary_config(PConfig0), [] = test_server:messages_get(), ok. change_config(cleanup,Config) -> logger:remove_handler(h1), - LC = ?config(logger_config,Config), - logger:set_logger_config(LC), + PC = ?config(logger_config,Config), + logger:set_primary_config(PC), ok. set_formatter(_Config) -> {error,{not_found,h1}}=logger:set_handler_config(h1,formatter,{?MODULE,[]}), - ok = logger:add_handler(h1,?MODULE,#{level=>info,filter_default=>log}), + ok = logger:add_handler(h1,?MODULE,#{level=>notice,filter_default=>log}), ok = logger:set_handler_config(h1,formatter,{?MODULE,[]}), - logger:info("hello",[]), + logger:notice("hello",[]), receive {_Log,#{formatter:={?MODULE,[]}}} -> ok @@ -291,9 +292,50 @@ set_formatter(cleanup,_Config) -> logger:remove_handler(h1), ok. +log_no_levels(_Config) -> + ok = logger:add_handler(h1,?MODULE,#{level=>all,filter_default=>log}), + logger:notice(M1=?map_rep), + ok = check_logged(notice,M1,#{}), + + Levels = [emergency,alert,critical,error,warning,notice,info,debug], + ok = logger:set_primary_config(level,none), + [logger:Level(#{Level=>rep}) || Level <- Levels], + ok = check_no_log(), + + ok = logger:set_primary_config(level,all), + M2 = ?map_rep, + ?LOG_NOTICE(M2), + ok = check_logged(notice,M2,#{}), + + ok = logger:set_module_level(?MODULE,none), + ?LOG_EMERGENCY(?map_rep), + ?LOG_ALERT(?map_rep), + ?LOG_CRITICAL(?map_rep), + ?LOG_ERROR(?map_rep), + ?LOG_WARNING(?map_rep), + ?LOG_NOTICE(?map_rep), + ?LOG_INFO(?map_rep), + ?LOG_DEBUG(?map_rep), + ok = check_no_log(), + + ok = logger:unset_module_level(?MODULE), + logger:notice(M3=?map_rep), + ok = check_logged(notice,M3,#{}), + + ok = logger:set_handler_config(h1,level,none), + [logger:Level(#{Level=>rep}) || Level <- Levels], + ok = check_no_log(), + + ok. +log_no_levels(cleanup,_Config) -> + logger:remove_handler(h1), + logger:set_primary_config(level,info), + logger:unset_module_level(?MODULE), + ok. + log_all_levels_api(_Config) -> - ok = logger:set_logger_config(level,debug), - ok = logger:add_handler(h1,?MODULE,#{level=>debug,filter_default=>log}), + ok = logger:set_primary_config(level,all), + ok = logger:add_handler(h1,?MODULE,#{level=>all,filter_default=>log}), test_api(emergency), test_api(alert), test_api(critical), @@ -307,12 +349,11 @@ log_all_levels_api(_Config) -> log_all_levels_api(cleanup,_Config) -> logger:remove_handler(h1), - logger:set_logger_config(level,info), + logger:set_primary_config(level,notice), ok. macros(_Config) -> - ok = logger:set_module_level(?MODULE,debug), - ok = logger:add_handler(h1,?MODULE,#{level=>debug,filter_default=>log}), + ok = logger:add_handler(h1,?MODULE,#{level=>all,filter_default=>log}), test_macros(emergency), ok. @@ -322,56 +363,77 @@ macros(cleanup,_Config) -> ok. set_level(_Config) -> - ok = logger:add_handler(h1,?MODULE,#{level=>debug,filter_default=>log}), + ok = logger:add_handler(h1,?MODULE,#{level=>all,filter_default=>log}), logger:debug(?map_rep), ok = check_no_log(), - logger:info(M1=?map_rep), - ok = check_logged(info,M1,#{}), - ok = logger:set_logger_config(level,debug), + logger:notice(M1=?map_rep), + ok = check_logged(notice,M1,#{}), + ok = logger:set_primary_config(level,debug), logger:debug(M2=?map_rep), ok = check_logged(debug,M2,#{}), ok. set_level(cleanup,_Config) -> logger:remove_handler(h1), - logger:set_logger_config(level,info), + logger:set_primary_config(level,notice), ok. -set_level_module(_Config) -> - ok = logger:add_handler(h1,?MODULE,#{level=>info,filter_default=>log}), +set_module_level(_Config) -> + [] = logger:get_module_level([?MODULE,other]), + [] = logger:get_module_level(?MODULE), + [] = logger:get_module_level(), + + ok = logger:add_handler(h1,?MODULE,#{level=>notice,filter_default=>log}), {error,{invalid_level,bad}} = logger:set_module_level(?MODULE,bad), - {error,{not_a_module,{bad}}} = logger:set_module_level({bad},warning), + {error,{not_a_list_of_modules,{bad}}} = + logger:set_module_level({bad},warning), ok = logger:set_module_level(?MODULE,warning), - logger:info(?map_rep,?MY_LOC(0)), + [{?MODULE,warning}] = logger:get_module_level([?MODULE,other]), + [{?MODULE,warning}] = logger:get_module_level(?MODULE), + [{?MODULE,warning}] = logger:get_module_level(), + logger:notice(?map_rep,?MY_LOC(0)), ok = check_no_log(), logger:warning(M1=?map_rep,?MY_LOC(0)), ok = check_logged(warning,M1,?MY_LOC(1)), - ok = logger:set_module_level(?MODULE,info), - logger:info(M2=?map_rep,?MY_LOC(0)), - ok = check_logged(info,M2,?MY_LOC(1)), - - {error,{not_a_module,{bad}}} = logger:unset_module_level({bad}), + ok = logger:set_module_level(?MODULE,notice), + [{?MODULE,notice}] = logger:get_module_level([?MODULE,other]), + [{?MODULE,notice}] = logger:get_module_level(?MODULE), + [{?MODULE,notice}] = logger:get_module_level(), + logger:notice(M2=?map_rep,?MY_LOC(0)), + ok = check_logged(notice,M2,?MY_LOC(1)), + + {error,{not_a_list_of_modules,{bad}}} = logger:unset_module_level({bad}), ok = logger:unset_module_level(?MODULE), + [] = logger:get_module_level([?MODULE,other]), + [] = logger:get_module_level(?MODULE), + [] = logger:get_module_level(), + + ok = logger:set_module_level([m1,m2,m3],notice), + [{m1,notice},{m2,notice},{m3,notice}] = logger:get_module_level(), + ok = logger:unset_module_level(m2), + [{m1,notice},{m3,notice}] = logger:get_module_level(), + ok = logger:unset_module_level(), + [] = logger:get_module_level(), ok. -set_level_module(cleanup,_Config) -> +set_module_level(cleanup,_Config) -> logger:remove_handler(h1), logger:unset_module_level(?MODULE), ok. -cache_level_module(_Config) -> +cache_module_level(_Config) -> ok = logger:unset_module_level(?MODULE), - [] = ets:lookup(logger,?MODULE), %dirty - add API in logger_config? - ?LOG_INFO(?map_rep), + [] = ets:lookup(?LOGGER_TABLE,?MODULE), %dirty - add API in logger_config? + ?LOG_NOTICE(?map_rep), %% Caching is done asynchronously, so wait a bit for the update timer:sleep(100), - [_] = ets:lookup(logger,?MODULE), %dirty - add API in logger_config? + [_] = ets:lookup(?LOGGER_TABLE,?MODULE), %dirty - add API in logger_config? ok = logger:unset_module_level(?MODULE), - [] = ets:lookup(logger,?MODULE), %dirty - add API in logger_config? + [] = ets:lookup(?LOGGER_TABLE,?MODULE), %dirty - add API in logger_config? ok. -cache_level_module(cleanup,_Config) -> +cache_module_level(cleanup,_Config) -> logger:unset_module_level(?MODULE), ok. @@ -402,22 +464,22 @@ format_report(_Config) -> ok. filter_failed(_Config) -> - ok = logger:add_handler(h1,?MODULE,#{level=>info,filter_default=>log}), + ok = logger:add_handler(h1,?MODULE,#{level=>notice,filter_default=>log}), %% Logger filters {error,{invalid_filter,_}} = - logger:add_logger_filter(lf,{fun(_) -> ok end,args}), - ok = logger:add_logger_filter(lf,{fun(_,_) -> a=b end,args}), - {ok,#{filters:=[_]}} = logger:get_logger_config(), - ok = logger:info(M1=?map_rep), - ok = check_logged(info,M1,#{}), - {error,{not_found,lf}} = logger:remove_logger_filter(lf), - - ok = logger:add_logger_filter(lf,{fun(_,_) -> faulty_return end,args}), - {ok,#{filters:=[_]}} = logger:get_logger_config(), - ok = logger:info(M2=?map_rep), - ok = check_logged(info,M2,#{}), - {error,{not_found,lf}} = logger:remove_logger_filter(lf), + logger:add_primary_filter(lf,{fun(_) -> ok end,args}), + ok = logger:add_primary_filter(lf,{fun(_,_) -> a=b end,args}), + #{filters:=[_]} = logger:get_primary_config(), + ok = logger:notice(M1=?map_rep), + ok = check_logged(notice,M1,#{}), + {error,{not_found,lf}} = logger:remove_primary_filter(lf), + + ok = logger:add_primary_filter(lf,{fun(_,_) -> faulty_return end,args}), + #{filters:=[_]} = logger:get_primary_config(), + ok = logger:notice(M2=?map_rep), + ok = check_logged(notice,M2,#{}), + {error,{not_found,lf}} = logger:remove_primary_filter(lf), %% Handler filters {error,{not_found,h0}} = @@ -426,15 +488,15 @@ filter_failed(_Config) -> {error,{invalid_filter,_}} = logger:add_handler_filter(h1,hf,{fun(_) -> ok end,args}), ok = logger:add_handler_filter(h1,hf,{fun(_,_) -> a=b end,args}), - {ok,{?MODULE,#{filters:=[_]}}} = logger:get_handler_config(h1), - ok = logger:info(M3=?map_rep), - ok = check_logged(info,M3,#{}), + {ok,#{filters:=[_]}} = logger:get_handler_config(h1), + ok = logger:notice(M3=?map_rep), + ok = check_logged(notice,M3,#{}), {error,{not_found,hf}} = logger:remove_handler_filter(h1,hf), ok = logger:add_handler_filter(h1,hf,{fun(_,_) -> faulty_return end,args}), - {ok,{?MODULE,#{filters:=[_]}}} = logger:get_handler_config(h1), - ok = logger:info(M4=?map_rep), - ok = check_logged(info,M4,#{}), + {ok,#{filters:=[_]}} = logger:get_handler_config(h1), + ok = logger:notice(M4=?map_rep), + ok = check_logged(notice,M4,#{}), {error,{not_found,hf}} = logger:remove_handler_filter(h1,hf), ok. @@ -455,20 +517,20 @@ handler_failed(_Config) -> {error,{invalid_formatter,[]}} = logger:add_handler(h1,?MODULE,#{formatter=>[]}), {error,{invalid_handler,_}} = logger:add_handler(h1,nomodule,#{filter_default=>log}), - logger:info(?map_rep), + logger:notice(?map_rep), check_no_log(), - #{handlers:=H1} = logger:i(), - false = lists:keymember(h1,1,H1), + H1 = logger:get_handler_config(), + false = lists:search(fun(#{id:=h1}) -> true; (_) -> false end,H1), {error,{not_found,h1}} = logger:remove_handler(h1), ok = logger:add_handler(h2,?MODULE,#{filter_default=>log,log_call=>fun() -> a = b end}), {error,{already_exist,h2}} = logger:add_handler(h2,othermodule,#{}), [add] = test_server:messages_get(), - logger:info(?map_rep), + logger:notice(?map_rep), [remove] = test_server:messages_get(), - #{handlers:=H2} = logger:i(), - false = lists:keymember(h2,1,H2), + H2 = logger:get_handler_config(), + false = lists:search(fun(#{id:=h2}) -> true; (_) -> false end,H2), {error,{not_found,h2}} = logger:remove_handler(h2), CallAddHandler = fun() -> logger:add_handler(h2,?MODULE,#{}) end, @@ -520,18 +582,18 @@ handler_failed(cleanup,_Config) -> config_sanity_check(_Config) -> %% Logger config {error,{invalid_filter_default,bad}} = - logger:set_logger_config(filter_default,bad), - {error,{invalid_level,bad}} = logger:set_logger_config(level,bad), - {error,{invalid_filters,bad}} = logger:set_logger_config(filters,bad), - {error,{invalid_filter,bad}} = logger:set_logger_config(filters,[bad]), + logger:set_primary_config(filter_default,bad), + {error,{invalid_level,bad}} = logger:set_primary_config(level,bad), + {error,{invalid_filters,bad}} = logger:set_primary_config(filters,bad), + {error,{invalid_filter,bad}} = logger:set_primary_config(filters,[bad]), {error,{invalid_filter,{_,_}}} = - logger:set_logger_config(filters,[{id,bad}]), + logger:set_primary_config(filters,[{id,bad}]), {error,{invalid_filter,{_,{_,_}}}} = - logger:set_logger_config(filters,[{id,{bad,args}}]), + logger:set_primary_config(filters,[{id,{bad,args}}]), {error,{invalid_filter,{_,{_,_}}}} = - logger:set_logger_config(filters,[{id,{fun() -> ok end,args}}]), - {error,{invalid_logger_config,{bad,bad}}} = - logger:set_logger_config(bad,bad), + logger:set_primary_config(filters,[{id,{fun() -> ok end,args}}]), + {error,{invalid_primary_config,{bad,bad}}} = + logger:set_primary_config(bad,bad), %% Handler config {error,{not_found,h1}} = logger:set_handler_config(h1,a,b), @@ -555,7 +617,7 @@ config_sanity_check(_Config) -> logger:set_handler_config(h1,formatter,{logger_formatter,bad}), {error,{invalid_formatter_config,logger_formatter,{bad,bad}}} = logger:set_handler_config(h1,formatter,{logger_formatter,#{bad=>bad}}), - {error,{invalid_formatter_config,logger_formatter,{template,bad}}} = + {error,{invalid_formatter_template,logger_formatter,bad}} = logger:set_handler_config(h1,formatter,{logger_formatter, #{template=>bad}}), {error,{invalid_formatter_template,logger_formatter,[1]}} = @@ -648,30 +710,30 @@ config_sanity_check(cleanup,_Config) -> ok. log_failed(_Config) -> - ok = logger:add_handler(h1,?MODULE,#{level=>info,filter_default=>log}), + ok = logger:add_handler(h1,?MODULE,#{level=>notice,filter_default=>log}), {error,function_clause} = ?TRY(logger:log(bad,?map_rep)), - {error,function_clause} = ?TRY(logger:log(info,?map_rep,bad)), - {error,function_clause} = ?TRY(logger:log(info,fun() -> ?map_rep end,bad)), - {error,function_clause} = ?TRY(logger:log(info,fun() -> ?map_rep end,bad,#{})), - {error,function_clause} = ?TRY(logger:log(info,bad,bad,bad)), - {error,function_clause} = ?TRY(logger:log(info,bad,bad,#{})), + {error,function_clause} = ?TRY(logger:log(notice,?map_rep,bad)), + {error,function_clause} = ?TRY(logger:log(notice,fun() -> ?map_rep end,bad)), + {error,function_clause} = ?TRY(logger:log(notice,fun() -> ?map_rep end,bad,#{})), + {error,function_clause} = ?TRY(logger:log(notice,bad,bad,bad)), + {error,function_clause} = ?TRY(logger:log(notice,bad,bad,#{})), check_no_log(), - ok = logger:log(info,M1=?str,#{}), - check_logged(info,M1,#{}), - ok = logger:log(info,M2=?map_rep,#{}), - check_logged(info,M2,#{}), - ok = logger:log(info,M3=?keyval_rep,#{}), - check_logged(info,M3,#{}), + ok = logger:log(notice,M1=?str,#{}), + check_logged(notice,M1,#{}), + ok = logger:log(notice,M2=?map_rep,#{}), + check_logged(notice,M2,#{}), + ok = logger:log(notice,M3=?keyval_rep,#{}), + check_logged(notice,M3,#{}), %% Should we check report input more thoroughly? - ok = logger:log(info,M4=?keyval_rep++[other,stuff,in,list],#{}), - check_logged(info,M4,#{}), + ok = logger:log(notice,M4=?keyval_rep++[other,stuff,in,list],#{}), + check_logged(notice,M4,#{}), %% This might break a handler since it is assumed to be a format %% string and args, so it depends how the handler protects itself %% against something like io_lib:format("ok","ok") - ok = logger:log(info,"ok","ok",#{}), - check_logged(info,"ok","ok",#{}), + ok = logger:log(notice,"ok","ok",#{}), + check_logged(notice,"ok","ok",#{}), ok. @@ -680,7 +742,7 @@ log_failed(cleanup,_Config) -> ok. emulator(_Config) -> - ok = logger:add_handler(h1,?MODULE,#{level=>info,filter_default=>log, + ok = logger:add_handler(h1,?MODULE,#{level=>notice,filter_default=>log, tc_proc=>self()}), Msg = "Error in process ~p on node ~p with exit value:~n~p~n", Error = {badmatch,4}, @@ -699,7 +761,7 @@ generate_error(Error, Stack) -> erlang:raise(error, Error, Stack). via_logger_process(Config) -> - ok = logger:add_handler(h1,?MODULE,#{level=>info,filter_default=>log, + ok = logger:add_handler(h1,?MODULE,#{level=>notice,filter_default=>log, tc_proc=>self()}), %% Explicitly send a message to the logger process @@ -736,7 +798,7 @@ via_logger_process(cleanup, Config) -> ok. other_node(_Config) -> - ok = logger:add_handler(h1,?MODULE,#{level=>info,filter_default=>log, + ok = logger:add_handler(h1,?MODULE,#{level=>notice,filter_default=>log, tc_proc=>self()}), {ok,Node} = test_server:start_node(?FUNCTION_NAME,slave,[]), rpc:call(Node,logger,error,[Msg=?str,#{}]), @@ -753,8 +815,8 @@ compare_levels(_Config) -> Levels = [emergency,alert,critical,error,warning,notice,info,debug], ok = compare(Levels), {error,badarg} = ?TRY(logger:compare_levels(bad,bad)), - {error,badarg} = ?TRY(logger:compare_levels({bad},info)), - {error,badarg} = ?TRY(logger:compare_levels(info,"bad")), + {error,badarg} = ?TRY(logger:compare_levels({bad},notice)), + {error,badarg} = ?TRY(logger:compare_levels(notice,"bad")), ok. compare([L|Rest]) -> @@ -768,21 +830,21 @@ compare([]) -> process_metadata(_Config) -> undefined = logger:get_process_metadata(), {error,badarg} = ?TRY(logger:set_process_metadata(bad)), - ok = logger:add_handler(h1,?MODULE,#{level=>info,filter_default=>log}), + ok = logger:add_handler(h1,?MODULE,#{level=>notice,filter_default=>log}), Time = erlang:system_time(microsecond), ProcMeta = #{time=>Time,line=>0,custom=>proc}, ok = logger:set_process_metadata(ProcMeta), S1 = ?str, - ?LOG_INFO(S1,#{custom=>macro}), - check_logged(info,S1,#{time=>Time,line=>0,custom=>macro}), + ?LOG_NOTICE(S1,#{custom=>macro}), + check_logged(notice,S1,#{time=>Time,line=>0,custom=>macro}), Time2 = erlang:system_time(microsecond), S2 = ?str, - ?LOG_INFO(S2,#{time=>Time2,line=>1,custom=>macro}), - check_logged(info,S2,#{time=>Time2,line=>1,custom=>macro}), + ?LOG_NOTICE(S2,#{time=>Time2,line=>1,custom=>macro}), + check_logged(notice,S2,#{time=>Time2,line=>1,custom=>macro}), - logger:info(S3=?str,#{custom=>func}), - check_logged(info,S3,#{time=>Time,line=>0,custom=>func}), + logger:notice(S3=?str,#{custom=>func}), + check_logged(notice,S3,#{time=>Time,line=>0,custom=>func}), ProcMeta = logger:get_process_metadata(), ok = logger:update_process_metadata(#{custom=>changed,custom2=>added}), diff --git a/lib/kernel/test/logger_bench_SUITE.erl b/lib/kernel/test/logger_bench_SUITE.erl deleted file mode 100644 index d47122ea9d..0000000000 --- a/lib/kernel/test/logger_bench_SUITE.erl +++ /dev/null @@ -1,500 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2018. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% --module(logger_bench_SUITE). - --compile(export_all). - -%%%----------------------------------------------------------------- -%%% To include lager tests, add paths to lager and goldrush -%%% (goldrush is a dependency inside the lager repo) -%%% -%%% To print data to .csv files, add the following to a config file: -%%% {print_csv,[{console_handler,[{path,"/some/dir/"}]}]}. -%%% -%%%----------------------------------------------------------------- - --include_lib("common_test/include/ct.hrl"). --include_lib("common_test/include/ct_event.hrl"). --include_lib("kernel/include/logger.hrl"). --include_lib("kernel/src/logger_internal.hrl"). - --define(msg,lists:flatten(string:pad("Log from "++atom_to_list(?FUNCTION_NAME)++ - ":"++integer_to_list(?LINE), - 80,trailing,$*))). --define(meta,#{mfa=>{?MODULE,?FUNCTION_NAME,?FUNCTION_ARITY}, - pid=>self()}). - --define(NO_COMPARE,[profile]). - --define(TIMES,100000). - -suite() -> - [{timetrap,{seconds,120}}]. - -init_per_suite(Config) -> - DataDir = ?config(data_dir,Config), - have_lager() andalso make(DataDir), - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(Group, Config) -> - H = remove_all_handlers(), - do_init_per_group(Group), - [{handlers,H}|Config]. - -do_init_per_group(minimal_handler) -> - ok = logger:add_handler(?MODULE,?MODULE,#{level=>error,filter_default=>log}); -do_init_per_group(console_handler) -> - ok = logger:add_handler(?MODULE,logger_std_h, - #{filter_default=>stop, - filters=>?DEFAULT_HANDLER_FILTERS, - logger_std_h=>#{type=>standard_io, - toggle_sync_qlen => ?TIMES+1, - drop_new_reqs_qlen => ?TIMES+2, - flush_reqs_qlen => ?TIMES+3, - enable_burst_limit => false}}), - have_lager() andalso lager_helper:start(), - ok. - -end_per_group(Group, Config) -> - case ?config(saved_config,Config) of - {_,[{bench,Bench}]} -> - print_compare_chart(Group,Bench); - _ -> - ok - end, - add_all_handlers(?config(handlers,Config)), - do_end_per_group(Group). - -do_end_per_group(minimal_handler) -> - ok = logger:remove_handler(?MODULE); -do_end_per_group(console_handler) -> - ok = logger:remove_handler(?MODULE), - have_lager() andalso lager_helper:stop(), - ok. - -init_per_testcase(_TestCase, Config) -> - Config. - -end_per_testcase(Case, Config) -> - try apply(?MODULE,Case,[cleanup,Config]) - catch error:undef -> ok - end, - wait_for_handlers(), - ok. - -wait_for_handlers() -> - wait_for_handler(?MODULE), - wait_for_handler(lager_event). - -wait_for_handler(Handler) -> - case whereis(Handler) of - undefined -> - io:format("~p: noproc1",[Handler]), - ok; - Pid -> - case process_info(Pid,message_queue_len) of - {_,0} -> - io:format("~p: queue=~p",[Handler,0]), - ok; - {_,Q} -> - io:format("~p: queue=~p",[Handler,Q]), - timer:sleep(2000), - wait_for_handler(Handler); - undefined -> - io:format("~p: noproc2",[Handler]), - ok - end - end. - -groups() -> - [{minimal_handler,[],[log, - log_drop, - log_drop_by_handler, - macro, - macro_drop, - macro_drop_by_handler, - error_logger, - error_logger_drop, - error_logger_drop_by_handler - ]}, - {console_handler,[],[%profile, - log, - log_drop, - log_drop_by_handler, - %% log_handler_complete, - macro, - macro_drop, - macro_drop_by_handler, - %% macro_handler_complete, - error_logger, - error_logger_drop, - error_logger_drop_by_handler%% , - %% error_logger_handler_complete - ] ++ lager_cases()} - ]. - -lager_cases() -> - case have_lager() of - true -> - [lager_log, - lager_log_drop, - lager_log_drop_by_handler, - %% lager_log_handler_complete, - lager_parsetrans, - lager_parsetrans_drop, - lager_parsetrans_drop_by_handler%% , - %% lager_parsetrans_handler_complete - ]; - false -> - [] - end. - - -all() -> - [{group,minimal_handler}, - {group,console_handler} - ]. - -log(Config) -> - Times = ?TIMES, - run_benchmark(Config,?FUNCTION_NAME,fun do_log_func/2, [error,?msg], Times). - -log_drop(Config) -> - Times = ?TIMES*100, - ok = logger:set_logger_config(level,error), - run_benchmark(Config,?FUNCTION_NAME,fun do_log_func/2, [info,?msg], Times). - -log_drop(cleanup,_Config) -> - ok = logger:set_logger_config(level,info). - -log_drop_by_handler(Config) -> - Times = ?TIMES, - %% just ensure correct levels - ok = logger:set_logger_config(level,info), - ok = logger:set_handler_config(?MODULE,level,error), - run_benchmark(Config,?FUNCTION_NAME,fun do_log_func/2, [info,?msg], Times). - -log_handler_complete(Config) -> - ok = logger:set_handler_config(?MODULE,formatter, - {?MODULE,?DEFAULT_FORMAT_CONFIG}), - handler_complete(Config, ?FUNCTION_NAME, fun do_log_func/2, [error,?msg]). - -log_handler_complete(cleanup,_Config) -> - ok=logger:set_handler_config(?MODULE,formatter, - {?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}). - -macro(Config) -> - Times = ?TIMES, - run_benchmark(Config,?FUNCTION_NAME,fun do_log_macro/2,[error,?msg], Times). - -macro_drop(Config) -> - Times = ?TIMES*100, - ok = logger:set_logger_config(level,error), - run_benchmark(Config,?FUNCTION_NAME,fun do_log_macro/2,[info,?msg], Times). - -macro_drop(cleanup,_Config) -> - ok = logger:set_logger_config(level,info). - -macro_drop_by_handler(Config) -> - Times = ?TIMES, - %% just ensure correct levels - ok = logger:set_logger_config(level,info), - ok = logger:set_handler_config(?MODULE,level,error), - run_benchmark(Config,?FUNCTION_NAME,fun do_log_macro/2, [info,?msg], Times). - -macro_handler_complete(Config) -> - ok = logger:set_handler_config(?MODULE,formatter, - {?MODULE,?DEFAULT_FORMAT_CONFIG}), - handler_complete(Config, ?FUNCTION_NAME, fun do_log_macro/2, [error,?msg]). - -macro_handler_complete(cleanup,_Config) -> - ok=logger:set_handler_config(?MODULE,formatter, - {?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}). - -error_logger(Config) -> - Times = ?TIMES, - run_benchmark(Config,?FUNCTION_NAME,fun do_error_logger/2, [error,?msg], Times). - -error_logger_drop(Config) -> - Times = ?TIMES*100, - ok = logger:set_logger_config(level,error), - run_benchmark(Config,?FUNCTION_NAME,fun do_error_logger/2, [info,?msg], Times). - -error_logger_drop(cleanup,_Config) -> - ok = logger:set_logger_config(level,info). - -error_logger_drop_by_handler(Config) -> - Times = ?TIMES, - %% just ensure correct levels - ok = logger:set_logger_config(level,info), - ok = logger:set_handler_config(?MODULE,level,error), - run_benchmark(Config,?FUNCTION_NAME,fun do_log_func/2, [info,?msg], Times). - -error_logger_handler_complete(Config) -> - ok = logger:set_handler_config(?MODULE,formatter, - {?MODULE,?DEFAULT_FORMAT_CONFIG}), - handler_complete(Config, ?FUNCTION_NAME, fun do_error_logger/2, [error,?msg]). - -error_logger_handler_complete(cleanup,_Config) -> - ok=logger:set_handler_config(?MODULE,formatter, - {?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}). - -lager_log(Config) -> - Times = ?TIMES, - run_benchmark(Config,?FUNCTION_NAME,fun lager_helper:do_func/2, [error,?msg], Times). - -lager_log_drop(Config) -> - Times = ?TIMES*100, - run_benchmark(Config,?FUNCTION_NAME,fun lager_helper:do_func/2, [info,?msg], Times). - -lager_log_drop_by_handler(Config) -> - %% This concept does not exist, so doing same as lager_log_drop/1 - Times = ?TIMES, - run_benchmark(Config,?FUNCTION_NAME,fun lager_helper:do_func/2, [info,?msg], Times). - -lager_log_handler_complete(Config) -> - handler_complete(Config, ?FUNCTION_NAME, fun lager_helper:do_func/2, [error,?msg]). - -lager_parsetrans(Config) -> - Times = ?TIMES, - run_benchmark(Config,?FUNCTION_NAME,fun lager_helper:do_parsetrans/2, [error,?msg], Times). - -lager_parsetrans_drop(Config) -> - Times = ?TIMES*100, - run_benchmark(Config,?FUNCTION_NAME,fun lager_helper:do_parsetrans/2, [info,?msg], Times). - -lager_parsetrans_drop_by_handler(Config) -> - %% This concept does not exist, so doing same as lager_parsetrans_drop/1 - Times = ?TIMES, - run_benchmark(Config,?FUNCTION_NAME,fun lager_helper:do_parsetrans/2, [info,?msg], Times). - -lager_parsetrans_handler_complete(Config) -> - handler_complete(Config, ?FUNCTION_NAME, fun lager_helper:do_parsetrans/2, [error,?msg]). - - -profile(Config) -> - Times = ?TIMES, - %% fprof:apply(fun repeated_apply/3,[fun lager_helper:do_func/2,[error,?msg],Times]), - fprof:apply(fun repeated_apply/3,[fun do_log_func/2,[error,?msg],Times]), - ok = fprof:profile(), - ok = fprof:analyse(dest,"../fprof.analyse"), - ok. - -%%%----------------------------------------------------------------- -%%% Internal -%% Handler -log(_Log,_Config) -> - ok. - -format(Log=#{meta:=#{pid:=Pid}},Config) when is_pid(Pid) -> - String = ?DEFAULT_FORMATTER:format(Log,Config), - Pid ! done, - String; -format(Log=#{meta:=#{pid:=PidStr}},Config) when is_list(PidStr) -> - String = ?DEFAULT_FORMATTER:format(Log,Config), - list_to_pid(PidStr) ! done, - String. - -handler_complete(Config, TC, Fun, Args) -> - Times = ?TIMES, - Start = os:perf_counter(microsecond), - repeated_apply(Fun, Args, Times), - MSecs = wait_for_done(Start,Times), - calc_and_report(Config,TC,MSecs,Times). - -wait_for_done(Start,0) -> - os:perf_counter(microsecond) - Start; -wait_for_done(Start,N) -> - receive - done -> - wait_for_done(Start,N-1) - after 20000 -> - ct:fail("missing " ++ integer_to_list(N) ++ " replys") - end. - -%%%----------------------------------------------------------------- -%%% Benchmark stuff -run_benchmark(Config,Tag,Fun,Args,Times) -> - _ = erlang:apply(Fun, Args), % apply once to ensure level is cached - MSecs = measure_repeated_op(Fun, Args, Times), - %% fprof:profile(), - %% fprof:analyse(dest,"../"++atom_to_list(Tag)++".prof"), - calc_and_report(Config,Tag,MSecs,Times). - -measure_repeated_op(Fun, Args, Times) -> - Start = os:perf_counter(microsecond), - %% fprof:apply(fun repeated_apply/3, [Fun, Args, Times]), - repeated_apply(Fun, Args, Times), - os:perf_counter(microsecond) - Start. - -repeated_apply(_F, _Args, Times) when Times =< 0 -> - ok; -repeated_apply(F, Args, Times) -> - erlang:apply(F, Args), - repeated_apply(F, Args, Times - 1). - -calc_and_report(Config,Tag,MSecs,Times) -> - IOPS = trunc(Times * (1000000 / MSecs)), - ct_event:notify(#event{ name = benchmark_data, data = [{value,IOPS}] }), - ct:print("~p:~n~p IOPS, ~p us", [Tag, IOPS, MSecs]), - ct:comment("~p IOPS, ~p us", [IOPS, MSecs]), - Bench = case ?config(saved_config,Config) of - {_,[{bench,B}]} -> B; - undefined -> [] - end, - {save_config,[{bench,[{Tag,IOPS,MSecs}|Bench]}]}. - -remove_all_handlers() -> - #{handlers:=Hs} = logger:i(), - [logger:remove_handler(Id) || {Id,_,_} <- Hs], - Hs. - -add_all_handlers(Hs) -> - [logger:add_handler(Id,Mod,Config) || {Id,Mod,Config} <- Hs], - ok. - -%%%----------------------------------------------------------------- -%%% Call logger in different ways -do_log_func(Level,Msg) -> - logger:Level(Msg,[],?meta). - -do_log_macro(error,Msg) -> - ?LOG_ERROR(Msg,[]); -do_log_macro(info,Msg) -> - ?LOG_INFO(Msg,[]); -do_log_macro(debug,Msg) -> - ?LOG_DEBUG(Msg,[]). - -do_error_logger(error,Msg) -> - error_logger:error_msg(Msg,[]); -do_error_logger(info,Msg) -> - error_logger:info_msg(Msg,[]). - -%%%----------------------------------------------------------------- -%%% -print_compare_chart(Group,Bench) -> - io:format("~-20s~12s~12s~12s~12s", - ["Microseconds:","Log","Drop","HDrop","Complete"]), - io:format(user,"~-20s~12s~12s~12s~12s~n", - ["Microseconds:","Log","Drop","HDrop","Complete"]), - {Log,Drop,HDrop,Comp} = sort_bench(Bench,[],[],[],[]), - print_compare_chart(Log,Drop,HDrop,Comp), - io:format(user,"~n",[]), - maybe_print_csv_files(Group, - [{log,Log},{drop,Drop},{hdrop,HDrop},{comp,Comp}]). - -print_compare_chart([{What,LIOPS,LMSecs}|Log], - [{What,DIOPS,DMSecs}|Drop], - [{What,HIOPS,HMSecs}|HDrop], - [{What,CIOPS,CMSecs}|Comp]) -> - io:format("~-20w~12w~12w~12w~12w",[What,LMSecs,DMSecs,HMSecs,CMSecs]), - io:format(user,"~-20w~12w~12w~12w~12w~n",[What,LMSecs,DMSecs,HMSecs,CMSecs]), - print_compare_chart(Log,Drop,HDrop,Comp); -print_compare_chart([{What,LIOPS,LMSecs}|Log], - [{What,DIOPS,DMSecs}|Drop], - [{What,HIOPS,HMSecs}|HDrop], - []=Comp) -> - io:format("~-20w~12w~12w~12w",[What,LMSecs,DMSecs,HMSecs]), - io:format(user,"~-20w~12w~12w~12w~n",[What,LMSecs,DMSecs,HMSecs]), - print_compare_chart(Log,Drop,HDrop,Comp); -print_compare_chart([],[],[],[]) -> - ok; -print_compare_chart(Log,Drop,HDrop,Comp) -> - ct:fail({Log,Drop,HDrop,Comp}). - -sort_bench([{TC,IOPS,MSecs}|Bench],Log,Drop,HDrop,Comp) -> - case lists:member(TC,?NO_COMPARE) of - true -> - sort_bench(Bench,Log,Drop,HDrop,Comp); - false -> - TCStr = atom_to_list(TC), - {What,Type} = - case re:run(TCStr,"(.*)_(drop.*)", - [{capture,all_but_first,list}]) of - {match,[WhatStr,TypeStr]} -> - {list_to_atom(WhatStr),list_to_atom(TypeStr)}; - nomatch -> - case re:run(TCStr,"(.*)_(handler_complete.*)", - [{capture,all_but_first,list}]) of - {match,[WhatStr,TypeStr]} -> - {list_to_atom(WhatStr),list_to_atom(TypeStr)}; - nomatch -> - {TC,log} - end - end, - case Type of - log -> - sort_bench(Bench,[{What,IOPS,MSecs}|Log],Drop,HDrop,Comp); - drop -> - sort_bench(Bench,Log,[{What,IOPS,MSecs}|Drop],HDrop,Comp); - drop_by_handler -> - sort_bench(Bench,Log,Drop,[{What,IOPS,MSecs}|HDrop],Comp); - handler_complete -> - sort_bench(Bench,Log,Drop,HDrop,[{What,IOPS,MSecs}|Comp]) - end - end; -sort_bench([],Log,Drop,HDrop,Comp) -> - {lists:keysort(1,Log), - lists:keysort(1,Drop), - lists:keysort(1,HDrop), - lists:keysort(1,Comp)}. - -maybe_print_csv_files(Group,Data) -> - case ct:get_config({print_csv,Group}) of - undefined -> - ok; - Cfg -> - Path = proplists:get_value(path,Cfg,".."), - Files = [begin - File = filename:join(Path,F)++".csv", - case filelib:is_regular(File) of - true -> - {ok,Fd} = file:open(File,[append]), - Fd; - false -> - {ok,Fd} = file:open(File,[write]), - ok = file:write(Fd, - "error_logger,lager_log," - "lager_parsetrans,logger_log," - "logger_macro\n"), - Fd - end - end || {F,_} <- Data], - [print_csv_file(F,D) || {F,D} <- lists:zip(Files,Data)], - [file:close(Fd) || Fd <- Files], - ok - end. - -print_csv_file(Fd,{_,Data}) -> - AllIOPS = [integer_to_list(IOPS) || {_,IOPS,_} <- Data], - ok = file:write(Fd,lists:join(",",AllIOPS)++"\n"). - -have_lager() -> - code:ensure_loaded(lager) == {module,lager}. - -make(Dir) -> - {ok,Cwd} = file:get_cwd(), - ok = file:set_cwd(Dir), - up_to_date = make:all([load]), - ok = file:set_cwd(Cwd), - code:add_path(Dir). diff --git a/lib/kernel/test/logger_bench_SUITE_data/Emakefile b/lib/kernel/test/logger_bench_SUITE_data/Emakefile deleted file mode 100644 index 85c82bdaab..0000000000 --- a/lib/kernel/test/logger_bench_SUITE_data/Emakefile +++ /dev/null @@ -1 +0,0 @@ -{['lager_helper'],[{outdir,"."},debug_info,{i,"/home/uabshan/Work/git/otp/lib/kernel/src"},{i,"/home/uabshan/Work/git/otp/lib/kernel/include"}]}. diff --git a/lib/kernel/test/logger_bench_SUITE_data/lager_helper.erl b/lib/kernel/test/logger_bench_SUITE_data/lager_helper.erl deleted file mode 100644 index 296ced4276..0000000000 --- a/lib/kernel/test/logger_bench_SUITE_data/lager_helper.erl +++ /dev/null @@ -1,73 +0,0 @@ --module(lager_helper). - --compile(export_all). --compile({parse_transform,lager_transform}). - --include_lib("kernel/src/logger_internal.hrl"). - -start() -> - application:load(lager), - application:set_env(lager, error_logger_redirect, false), - application:set_env(lager, async_threshold, 100010), - application:set_env(lager, async_threshold_window, 100), - application:set_env(lager,handlers,[{?MODULE,[{level,error}]}]), - lager:start(). - -stop() -> - application:stop(lager). - -do_func(Level,Msg) -> - lager:log(Level,[{pid,self()}],Msg,[]). - -do_parsetrans(error,Msg) -> - lager:error(Msg,[]); -do_parsetrans(info,Msg) -> - lager:info(Msg,[]). - -%%%----------------------------------------------------------------- -%%% Dummy handler for lager --record(state, {level :: {'mask', integer()}, - formatter :: atom(), - format_config :: any()}). -init(Opts) -> - Level = proplists:get_value(level,Opts,info), - Formatter = proplists:get_value(formatter,Opts,logger_bench_SUITE), - FormatConfig = proplists:get_value(format_config,Opts,?DEFAULT_FORMAT_CONFIG), - {ok,#state{level=lager_util:config_to_mask(Level), - formatter=Formatter, - format_config=FormatConfig}}. - -handle_call(get_loglevel, #state{level=Level} = State) -> - {ok, Level, State}; -handle_call({set_loglevel, Level}, State) -> - try lager_util:config_to_mask(Level) of - Levels -> - {ok, ok, State#state{level=Levels}} - catch - _:_ -> - {ok, {error, bad_log_level}, State} - end; -handle_call(_Request, State) -> - {ok, ok, State}. - -handle_event({log, Message}, - #state{level=L,formatter=Formatter,format_config=FormatConfig} = State) -> - case lager_util:is_loggable(Message, L, ?MODULE) of - true -> - Metadata = - case maps:from_list(lager_msg:metadata(Message)) of - Meta = #{pid:=Pid} when is_pid(Pid) -> - Meta; - Meta = #{pid:=PidStr} when is_list(PidStr) -> - Meta - end, - Log = #{level=>lager_msg:severity(Message), - msg=>{report,lager_msg:message(Message)}, - meta=>Metadata}, - io:put_chars(user, Formatter:format(Log,FormatConfig)), - {ok, State}; - false -> - {ok, State} - end; -handle_event(_Event, State) -> - {ok, State}. diff --git a/lib/kernel/test/logger_disk_log_h_SUITE.erl b/lib/kernel/test/logger_disk_log_h_SUITE.erl index 7a1736c814..5f7b505ecb 100644 --- a/lib/kernel/test/logger_disk_log_h_SUITE.erl +++ b/lib/kernel/test/logger_disk_log_h_SUITE.erl @@ -82,7 +82,7 @@ all() -> bad_input, info_and_reset, reconfig, - disk_log_sync, + sync, disk_log_full, disk_log_wrap, disk_log_events, @@ -107,10 +107,10 @@ start_stop_handler(_Config) -> ok = logger:add_handler(?MODULE, logger_disk_log_h, #{}), {error,{already_exist,?MODULE}} = logger:add_handler(?MODULE, logger_disk_log_h, #{}), - true = is_pid(whereis(?MODULE)), + true = is_pid(whereis(h_proc_name())), ok = logger:remove_handler(?MODULE), timer:sleep(500), - undefined = whereis(?MODULE). + undefined = whereis(h_proc_name()). start_stop_handler(cleanup, _Config) -> logger:remove_handler(?MODULE). @@ -123,8 +123,8 @@ create_log(Config) -> filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}}, #{file=>LogFile1}), - logger:info("hello", ?domain), - logger_disk_log_h:disk_log_sync(Name1), + logger:notice("hello", ?domain), + logger_disk_log_h:sync(Name1), ct:pal("Checking contents of ~p", [?log_no(LogFile1,1)]), try_read_file(?log_no(LogFile1,1), {ok,<<"hello\n">>}, 5000), @@ -136,8 +136,8 @@ create_log(Config) -> filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}}, #{file=>LogFile2}), - logger:info("dummy", ?domain), - logger_disk_log_h:disk_log_sync(Name2), + logger:notice("dummy", ?domain), + logger_disk_log_h:sync(Name2), ct:pal("Checking contents of ~p", [?log_no(LogFile2,1)]), try_read_file(?log_no(LogFile2,1), {ok,<<"dummy\n">>}, 5000), @@ -157,22 +157,22 @@ open_existing_log(Config) -> filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}}, #{file=>LogFile1}), - logger:info("one", ?domain), - logger_disk_log_h:disk_log_sync(HName), + logger:notice("one", ?domain), + logger_disk_log_h:sync(HName), ct:pal("Checking contents of ~p", [?log_no(LogFile1,1)]), try_read_file(?log_no(LogFile1,1), {ok,<<"one\n">>}, 5000), - logger:info("two", ?domain), + logger:notice("two", ?domain), ok = remove_and_stop(HName), try_read_file(?log_no(LogFile1,1), {ok,<<"one\ntwo\n">>}, 5000), - logger:info("two and a half", ?domain), + logger:notice("two and a half", ?domain), ok = start_and_add(HName, #{filter_default=>stop, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}}, #{file=>LogFile1}), - logger:info("three", ?domain), - logger_disk_log_h:disk_log_sync(HName), + logger:notice("three", ?domain), + logger_disk_log_h:sync(HName), try_read_file(?log_no(LogFile1,1), {ok,<<"one\ntwo\nthree\n">>}, 5000), remove_and_stop(HName), try_read_file(?log_no(LogFile1,1), {ok,<<"one\ntwo\nthree\n">>}, 5000). @@ -196,23 +196,23 @@ disk_log_opts(Config) -> ct:log("Fullname = ~s", [WFileFull]), {WFileFull,wrap,{Size,2},1} = {Get(file,WInfo1),Get(type,WInfo1), Get(size,WInfo1),Get(current_file,WInfo1)}, - logger:info("123", ?domain), - logger_disk_log_h:disk_log_sync(WName), + logger:notice("123", ?domain), + logger_disk_log_h:sync(WName), timer:sleep(500), 1 = Get(current_file, disk_log:info(WName)), - logger:info("45", ?domain), - logger_disk_log_h:disk_log_sync(WName), + logger:notice("45", ?domain), + logger_disk_log_h:sync(WName), timer:sleep(500), 1 = Get(current_file, disk_log:info(WName)), - logger:info("6", ?domain), - logger_disk_log_h:disk_log_sync(WName), + logger:notice("6", ?domain), + logger_disk_log_h:sync(WName), timer:sleep(500), 2 = Get(current_file, disk_log:info(WName)), - logger:info("7890", ?domain), - logger_disk_log_h:disk_log_sync(WName), + logger:notice("7890", ?domain), + logger_disk_log_h:sync(WName), timer:sleep(500), 2 = Get(current_file, disk_log:info(WName)), @@ -229,8 +229,8 @@ disk_log_opts(Config) -> ct:log("Fullname = ~s", [HFile1Full]), {HFile1Full,halt,infinity} = {Get(file,HInfo1),Get(type,HInfo1), Get(size,HInfo1)}, - logger:info("12345", ?domain), - logger_disk_log_h:disk_log_sync(HName1), + logger:notice("12345", ?domain), + logger_disk_log_h:sync(HName1), timer:sleep(500), 1 = Get(no_written_items, disk_log:info(HName1)), @@ -253,17 +253,17 @@ disk_log_opts(Config) -> default_formatter(Config) -> PrivDir = ?config(priv_dir,Config), LogFile = filename:join(PrivDir,atom_to_list(?FUNCTION_NAME)), - HConfig = #{disk_log_opts => #{file=>LogFile}, - filter_default=>log}, + HandlerConfig = #{config => #{file=>LogFile}, + filter_default=>log}, ct:pal("Log: ~p", [LogFile]), - ok = logger:add_handler(?MODULE, logger_disk_log_h, HConfig), + ok = logger:add_handler(?MODULE, logger_disk_log_h, HandlerConfig), ok = logger:set_handler_config(?MODULE,formatter, {?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}), LogName = lists:concat([LogFile, ".1"]), - logger:info("dummy"), + logger:notice("dummy"), wait_until_written(LogName), {ok,Bin} = file:read_file(LogName), - match = re:run(Bin, "=INFO REPORT====.*\ndummy", [{capture,none}]), + match = re:run(Bin, "=NOTICE REPORT====.*\ndummy", [{capture,none}]), ok. default_formatter(cleanup, _Config) -> logger:remove_handler(?MODULE). @@ -277,8 +277,8 @@ logging(Config) -> formatter=>{?MODULE,self()}}, #{file => LogFile}), MsgFormatter = fun(Term) -> {io_lib:format("Term:~p",[Term]),[]} end, - logger:info([{x,y}], #{report_cb => MsgFormatter}), - logger:info([{x,y}], #{}), + logger:notice([{x,y}], #{report_cb => MsgFormatter}), + logger:notice([{x,y}], #{}), ct:pal("Checking contents of ~p", [?log_no(LogFile,1)]), try_read_file(?log_no(LogFile,1), {ok,<<"Term:[{x,y}]\n x: y\n">>}, 5000). @@ -290,10 +290,10 @@ errors(Config) -> PrivDir = ?config(priv_dir,Config), Name1 = list_to_atom(lists:concat([?FUNCTION_NAME,"_1"])), LogFile1 = filename:join(PrivDir,Name1), - HConfig = #{disk_log_opts=>#{file=>LogFile1}, - filter_default=>log, - formatter=>{?MODULE,self()}}, - ok = logger:add_handler(Name1, logger_disk_log_h, HConfig), + HandlerConfig = #{config=>#{file=>LogFile1}, + filter_default=>log, + formatter=>{?MODULE,self()}}, + ok = logger:add_handler(Name1, logger_disk_log_h, HandlerConfig), {error,{already_exist,Name1}} = logger:add_handler(Name1, logger_disk_log_h, #{}), @@ -302,7 +302,7 @@ errors(Config) -> {error,{illegal_config_change,_,_}} = logger:set_handler_config(Name1, - disk_log_opts, + config, #{file=>LogFile1, type=>halt}), {error,{illegal_config_change,_,_}} = @@ -321,45 +321,42 @@ formatter_fail(Config) -> Name = ?FUNCTION_NAME, LogFile = filename:join(PrivDir,Name), ct:pal("Log = ~p", [LogFile]), - HConfig = #{disk_log_opts => #{file=>LogFile}, - filter_default=>stop, - filters=>?DEFAULT_HANDLER_FILTERS([?MODULE])}, + HandlerConfig = #{config => #{file=>LogFile}, + filter_default=>stop, + filters=>?DEFAULT_HANDLER_FILTERS([?MODULE])}, %% no formatter! - logger:add_handler(Name, logger_disk_log_h, HConfig), - Pid = whereis(Name), + logger:add_handler(Name, logger_disk_log_h, HandlerConfig), + Pid = whereis(h_proc_name(Name)), true = is_pid(Pid), - #{handlers:=HC1} = logger:i(), - H = [Id || {Id,_,_} <- HC1], + H = logger:get_handler_ids(), true = lists:member(Name,H), %% Formatter is added automatically - {ok,{_,#{formatter:={logger_formatter,_}}}} = - logger:get_handler_config(Name), - logger:info(M1=?msg,?domain), - Got1 = try_match_file(?log_no(LogFile,1),"[0-9\\+\\-T:\\.]* info: "++M1,5000), + {ok,#{formatter:={logger_formatter,_}}} = logger:get_handler_config(Name), + logger:notice(M1=?msg,?domain), + Got1 = try_match_file(?log_no(LogFile,1),"[0-9\\+\\-T:\\.]* notice: "++M1,5000), ok = logger:set_handler_config(Name,formatter,{nonexistingmodule,#{}}), - logger:info(M2=?msg,?domain), + logger:notice(M2=?msg,?domain), Got2 = try_match_file(?log_no(LogFile,1), - escape(Got1)++"[0-9\\+\\-T:\\.]* info: FORMATTER CRASH: .*"++M2, + escape(Got1)++"[0-9\\+\\-T:\\.]* notice: FORMATTER CRASH: .*"++M2, 5000), ok = logger:set_handler_config(Name,formatter,{?MODULE,crash}), - logger:info(M3=?msg,?domain), + logger:notice(M3=?msg,?domain), Got3 = try_match_file(?log_no(LogFile,1), - escape(Got2)++"[0-9\\+\\-T:\\.]* info: FORMATTER CRASH: .*"++M3, + escape(Got2)++"[0-9\\+\\-T:\\.]* notice: FORMATTER CRASH: .*"++M3, 5000), ok = logger:set_handler_config(Name,formatter,{?MODULE,bad_return}), - logger:info(?msg,?domain), + logger:notice(?msg,?domain), try_match_file(?log_no(LogFile,1), escape(Got3)++"FORMATTER ERROR: bad_return_value", 5000), %% Check that handler is still alive and was never dead - Pid = whereis(Name), - #{handlers:=HC2} = logger:i(), - H = [Id || {Id,_,_} <- HC2], + Pid = whereis(h_proc_name(Name)), + H = logger:get_handler_ids(), ok. formatter_fail(cleanup,_Config) -> @@ -369,48 +366,49 @@ formatter_fail(cleanup,_Config) -> config_fail(_Config) -> {error,{handler_not_added,{invalid_config,logger_disk_log_h,{bad,bad}}}} = logger:add_handler(?MODULE,logger_disk_log_h, - #{logger_disk_log_h => #{bad => bad}, + #{config => #{bad => bad}, filter_default=>log, formatter=>{?MODULE,self()}}), {error,{handler_not_added,{invalid_levels,{_,1,_}}}} = logger:add_handler(?MODULE,logger_disk_log_h, - #{logger_disk_log_h => #{drop_new_reqs_qlen=>1}}), + #{config => #{drop_mode_qlen=>1}}), {error,{handler_not_added,{invalid_levels,{43,42,_}}}} = logger:add_handler(?MODULE,logger_disk_log_h, - #{logger_disk_log_h => #{toggle_sync_qlen=>43, - drop_new_reqs_qlen=>42}}), + #{config => #{sync_mode_qlen=>43, + drop_mode_qlen=>42}}), {error,{handler_not_added,{invalid_levels,{_,43,42}}}} = logger:add_handler(?MODULE,logger_disk_log_h, - #{logger_disk_log_h => #{drop_new_reqs_qlen=>43, - flush_reqs_qlen=>42}}), + #{config => #{drop_mode_qlen=>43, + flush_qlen=>42}}), ok = logger:add_handler(?MODULE,logger_disk_log_h, #{filter_default=>log, formatter=>{?MODULE,self()}}), %% can't change the disk log options for a log already in use {error,{illegal_config_change,_,_}} = - logger:set_handler_config(?MODULE,disk_log_opts, + logger:set_handler_config(?MODULE,config, #{max_no_files=>2}), %% can't change name of an existing handler {error,{illegal_config_change,_,_}} = logger:set_handler_config(?MODULE,id,bad), - %% incorrect values of OP params + %% incorrect values of OP params + {ok,#{config := HConfig}} = logger:get_handler_config(?MODULE), {error,{invalid_levels,_}} = - logger:set_handler_config(?MODULE,logger_disk_log_h, - #{toggle_sync_qlen=>100, - flush_reqs_qlen=>99}), + logger:set_handler_config(?MODULE,config, + HConfig#{sync_mode_qlen=>100, + flush_qlen=>99}), %% invalid name of config parameter {error,{invalid_config,logger_disk_log_h,{filesync_rep_int,2000}}} = - logger:set_handler_config(?MODULE, logger_disk_log_h, - #{filesync_rep_int => 2000}), + logger:set_handler_config(?MODULE, config, + HConfig#{filesync_rep_int => 2000}), ok. config_fail(cleanup,_Config) -> logger:remove_handler(?MODULE). bad_input(_Config) -> - {error,{badarg,{disk_log_sync,["BadType"]}}} = - logger_disk_log_h:disk_log_sync("BadType"), + {error,{badarg,{sync,["BadType"]}}} = + logger_disk_log_h:sync("BadType"), {error,{badarg,{info,["BadType"]}}} = logger_disk_log_h:info("BadType"), {error,{badarg,{reset,["BadType"]}}} = logger_disk_log_h:reset("BadType"). @@ -431,16 +429,16 @@ reconfig(Config) -> filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}}), #{id := ?MODULE, - toggle_sync_qlen := ?TOGGLE_SYNC_QLEN, - drop_new_reqs_qlen := ?DROP_NEW_REQS_QLEN, - flush_reqs_qlen := ?FLUSH_REQS_QLEN, - enable_burst_limit := ?ENABLE_BURST_LIMIT, - burst_limit_size := ?BURST_LIMIT_SIZE, - burst_window_time := ?BURST_WINDOW_TIME, - enable_kill_overloaded := ?ENABLE_KILL_OVERLOADED, - handler_overloaded_qlen := ?HANDLER_OVERLOADED_QLEN, - handler_overloaded_mem := ?HANDLER_OVERLOADED_MEM, - handler_restart_after := ?HANDLER_RESTART_AFTER, + sync_mode_qlen := ?SYNC_MODE_QLEN, + drop_mode_qlen := ?DROP_MODE_QLEN, + flush_qlen := ?FLUSH_QLEN, + burst_limit_enable := ?BURST_LIMIT_ENABLE, + burst_limit_max_count := ?BURST_LIMIT_MAX_COUNT, + burst_limit_window_time := ?BURST_LIMIT_WINDOW_TIME, + overload_kill_enable := ?OVERLOAD_KILL_ENABLE, + overload_kill_qlen := ?OVERLOAD_KILL_QLEN, + overload_kill_mem_size := ?OVERLOAD_KILL_MEM_SIZE, + overload_kill_restart_after := ?OVERLOAD_KILL_RESTART_AFTER, filesync_repeat_interval := ?FILESYNC_REPEAT_INTERVAL, log_opts := #{type := ?DISK_LOG_TYPE, max_no_files := ?DISK_LOG_MAX_NO_FILES, @@ -448,29 +446,30 @@ reconfig(Config) -> file := _DiskLogFile}} = logger_disk_log_h:info(?MODULE), - ok = logger:set_handler_config(?MODULE, logger_disk_log_h, - #{toggle_sync_qlen => 1, - drop_new_reqs_qlen => 2, - flush_reqs_qlen => 3, - enable_burst_limit => false, - burst_limit_size => 10, - burst_window_time => 10, - enable_kill_overloaded => true, - handler_overloaded_qlen => 100000, - handler_overloaded_mem => 10000000, - handler_restart_after => never, - filesync_repeat_interval => no_repeat}), + {ok,#{config := HConfig0}} = logger:get_handler_config(?MODULE), + HConfig1 = HConfig0#{sync_mode_qlen => 1, + drop_mode_qlen => 2, + flush_qlen => 3, + burst_limit_enable => false, + burst_limit_max_count => 10, + burst_limit_window_time => 10, + overload_kill_enable => true, + overload_kill_qlen => 100000, + overload_kill_mem_size => 10000000, + overload_kill_restart_after => never, + filesync_repeat_interval => no_repeat}, + ok = logger:set_handler_config(?MODULE, config, HConfig1), #{id := ?MODULE, - toggle_sync_qlen := 1, - drop_new_reqs_qlen := 2, - flush_reqs_qlen := 3, - enable_burst_limit := false, - burst_limit_size := 10, - burst_window_time := 10, - enable_kill_overloaded := true, - handler_overloaded_qlen := 100000, - handler_overloaded_mem := 10000000, - handler_restart_after := never, + sync_mode_qlen := 1, + drop_mode_qlen := 2, + flush_qlen := 3, + burst_limit_enable := false, + burst_limit_max_count := 10, + burst_limit_window_time := 10, + overload_kill_enable := true, + overload_kill_qlen := 100000, + overload_kill_mem_size := 10000000, + overload_kill_restart_after := never, filesync_repeat_interval := no_repeat} = logger_disk_log_h:info(?MODULE), @@ -482,7 +481,7 @@ reconfig(Config) -> #{filter_default=>log, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}, - disk_log_opts=> + config=> #{type => halt, max_no_files => 1, max_no_bytes => 1024, @@ -497,13 +496,13 @@ reconfig(Config) -> reconfig(cleanup, _Config) -> logger:remove_handler(?MODULE). -disk_log_sync(Config) -> +sync(Config) -> Dir = ?config(priv_dir,Config), File = filename:join(Dir, ?FUNCTION_NAME), Log = lists:concat([File,".1"]), ok = logger:add_handler(?MODULE, logger_disk_log_h, - #{disk_log_opts => #{file => File}, + #{config => #{file => File}, filter_default=>log, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,nl}}), @@ -513,7 +512,7 @@ disk_log_sync(Config) -> [{disk_log,blog,<<"first\n">>}, {disk_log,sync}]), - logger:info("first", ?domain), + logger:notice("first", ?domain), %% wait for automatic disk_log_sync check_tracer(?FILESYNC_REPEAT_INTERVAL*2), @@ -524,16 +523,18 @@ disk_log_sync(Config) -> {disk_log,sync}]), %% two log requests in fast succession will make the handler skip %% an automatic disk log sync - logger:info("second", ?domain), - logger:info("third", ?domain), - %% do explicit disk_log_sync - logger_disk_log_h:disk_log_sync(?MODULE), + logger:notice("second", ?domain), + logger:notice("third", ?domain), + %% do explicit sync + logger_disk_log_h:sync(?MODULE), check_tracer(100), %% check that if there's no repeated disk_log_sync active, %% a disk_log_sync is still performed when handler goes idle - logger:set_handler_config(?MODULE, logger_disk_log_h, - #{filesync_repeat_interval => no_repeat}), + {ok,#{config := HConfig}} = logger:get_handler_config(?MODULE), + HConfig1 = HConfig#{filesync_repeat_interval => no_repeat}, + ok = logger:set_handler_config(?MODULE, config, HConfig1), + no_repeat = maps:get(filesync_repeat_interval, logger_disk_log_h:info(?MODULE)), @@ -543,9 +544,9 @@ disk_log_sync(Config) -> {disk_log,blog,<<"fifth\n">>}, {disk_log,sync}]), - logger:info("fourth", ?domain), + logger:notice("fourth", ?domain), timer:sleep(?IDLE_DETECT_TIME_MSEC*2), - logger:info("fifth", ?domain), + logger:notice("fifth", ?domain), %% wait for automatic disk_log_sync check_tracer(?IDLE_DETECT_TIME_MSEC*2), @@ -559,16 +560,17 @@ disk_log_sync(Config) -> start_tracer([{logger_disk_log_h,handle_cast,2}], [OneSync || _ <- lists:seq(1, 1 + trunc(WaitT/SyncInt))]), - logger:set_handler_config(?MODULE, logger_disk_log_h, - #{filesync_repeat_interval => SyncInt}), + HConfig2 = HConfig#{filesync_repeat_interval => SyncInt}, + ok = logger:set_handler_config(?MODULE, config, HConfig2), + SyncInt = maps:get(filesync_repeat_interval, logger_disk_log_h:info(?MODULE)), timer:sleep(WaitT), - logger:set_handler_config(?MODULE, logger_disk_log_h, - #{filesync_repeat_interval => no_repeat}), + HConfig3 = HConfig#{filesync_repeat_interval => no_repeat}, + ok = logger:set_handler_config(?MODULE, config, HConfig3), check_tracer(100), ok. -disk_log_sync(cleanup,_Config) -> +sync(cleanup,_Config) -> dbg:stop_clear(), logger:remove_handler(?MODULE). @@ -584,7 +586,7 @@ disk_log_wrap(Config) -> #{filter_default=>log, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}, - disk_log_opts=> + config=> #{type => wrap, max_no_files => MaxFiles, max_no_bytes => MaxBytes, @@ -598,7 +600,7 @@ disk_log_wrap(Config) -> Pid end, {ok,_} = dbg:tracer(process, {TraceFun, Tester}), - {ok,_} = dbg:p(whereis(?MODULE), [c]), + {ok,_} = dbg:p(whereis(h_proc_name()), [c]), {ok,_} = dbg:tp(logger_disk_log_h, handle_info, 2, []), Text = [34 + rand:uniform(126-34) || _ <- lists:seq(1,MaxBytes)], @@ -606,7 +608,7 @@ disk_log_wrap(Config) -> %% fill first file lists:foreach(fun(N) -> Log = lists:concat([File,".",N]), - logger:info(Text, ?domain), + logger:notice(Text, ?domain), wait_until_written(Log), ct:pal("N = ~w", [N = Get(current_file, @@ -640,7 +642,7 @@ disk_log_full(Config) -> #{filter_default=>log, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}, - disk_log_opts=> + config=> #{type => halt, max_no_files => 1, max_no_bytes => MaxBytes, @@ -652,12 +654,12 @@ disk_log_full(Config) -> Pid end, {ok,_} = dbg:tracer(process, {TraceFun, Tester}), - {ok,_} = dbg:p(whereis(?MODULE), [c]), + {ok,_} = dbg:p(whereis(h_proc_name()), [c]), {ok,_} = dbg:tp(logger_disk_log_h, handle_info, 2, []), NoOfChars = 5, Text = [34 + rand:uniform(126-34) || _ <- lists:seq(1,NoOfChars)], - [logger:info(Text, ?domain) || _ <- lists:seq(1,trunc(MaxBytes/NoOfChars)+1)], + [logger:notice(Text, ?domain) || _ <- lists:seq(1,trunc(MaxBytes/NoOfChars)+1)], %% wait for trace messages timer:sleep(2000), @@ -701,10 +703,10 @@ disk_log_events(Config) -> Pid end, {ok,_} = dbg:tracer(process, {TraceFun, Tester}), - {ok,_} = dbg:p(whereis(?MODULE), [c]), + {ok,_} = dbg:p(whereis(h_proc_name()), [c]), {ok,_} = dbg:tp(logger_disk_log_h, handle_info, 2, []), - [whereis(?MODULE) ! E || E <- Events], + [whereis(h_proc_name()) ! E || E <- Events], %% wait for trace messages timer:sleep(2000), dbg:stop_clear(), @@ -737,7 +739,7 @@ write_failure(Config) -> ct:pal("LogOpts = ~p", [LogOpts = maps:get(log_opts, HState)]), ok = log_on_remote_node(Node, "Logged1"), - rpc:call(Node, logger_disk_log_h, disk_log_sync, [?STANDARD_HANDLER]), + rpc:call(Node, logger_disk_log_h, sync, [?STANDARD_HANDLER]), ?check_no_log, try_read_file(Log, {ok,<<"Logged1\n">>}, ?SYNC_REP_INT), @@ -757,7 +759,7 @@ write_failure(Config) -> rpc:call(Node, ?MODULE, set_result, [disk_log_blog,ok]), ok = log_on_remote_node(Node, "Logged2"), - rpc:call(Node, logger_disk_log_h, disk_log_sync, [?STANDARD_HANDLER]), + rpc:call(Node, logger_disk_log_h, sync, [?STANDARD_HANDLER]), ?check_no_log, try_read_file(Log, {ok,<<"Logged1\nLogged2\n">>}, ?SYNC_REP_INT), ok. @@ -782,7 +784,7 @@ sync_failure(Config) -> SyncInt = 500, ok = rpc:call(Node, logger, set_handler_config, - [?STANDARD_HANDLER, logger_disk_log_h, + [?STANDARD_HANDLER, config, #{filesync_repeat_interval => SyncInt}]), Info = rpc:call(Node, logger_disk_log_h, info, [?STANDARD_HANDLER]), SyncInt = maps:get(filesync_repeat_interval, Info), @@ -817,7 +819,7 @@ start_h_on_new_node(Config, File) -> logger_test_lib:setup( Config, [{logger,[{handler,default,logger_disk_log_h, - #{ disk_log_opts => #{ file => File }}}]}]), + #{ config => #{ file => File }}}]}]), ok = rpc:call(Node,logger,set_handler_config,[?STANDARD_HANDLER,formatter, {?MODULE,nl}]), Node. @@ -825,7 +827,7 @@ start_h_on_new_node(Config, File) -> log_on_remote_node(Node,Msg) -> _ = spawn_link(Node, fun() -> erlang:group_leader(whereis(user),self()), - logger:info(Msg) + logger:notice(Msg) end), ok. @@ -852,14 +854,14 @@ op_switch_to_sync(Config) -> {Log,HConfig,DLHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NumOfReqs = 500, NewHConfig = - HConfig#{logger_disk_log_h => DLHConfig#{toggle_sync_qlen => 2, - drop_new_reqs_qlen => NumOfReqs+1, - flush_reqs_qlen => 2*NumOfReqs, - enable_burst_limit => false}}, + HConfig#{config => DLHConfig#{sync_mode_qlen => 2, + drop_mode_qlen => NumOfReqs+1, + flush_qlen => 2*NumOfReqs, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), - send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Lines = count_lines(Log), - ok = file:delete(Log), + ok = file_delete(Log), NumOfReqs = Lines, ok. op_switch_to_sync(cleanup, _Config) -> @@ -876,21 +878,21 @@ op_switch_to_drop(Config) -> Procs = 2, Bursts = 10, NewHConfig = - HConfig#{logger_disk_log_h => - DLHConfig#{toggle_sync_qlen => 1, - drop_new_reqs_qlen => 2, - flush_reqs_qlen => Procs*NumOfReqs*Bursts, - enable_burst_limit => false}}, + HConfig#{config => + DLHConfig#{sync_mode_qlen => 1, + drop_mode_qlen => 2, + flush_qlen => Procs*NumOfReqs*Bursts, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), %% It sometimes happens that the handler either gets %% the requests in a slow enough pace so that dropping %% never occurs. Therefore, lets generate a number of %% bursts to increase the chance of message buildup. - [send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, info) || + [send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice) || _ <- lists:seq(1, Bursts)], Logged = count_lines(Log), - ok= stop_handler(?MODULE), - _ = file:delete(Log), + ok = stop_handler(?MODULE), + _ = file_delete(Log), ct:pal("Number of messages dropped = ~w (~w)", [Procs*NumOfReqs*Bursts-Logged,Procs*NumOfReqs*Bursts]), true = (Logged < (Procs*NumOfReqs*Bursts)), @@ -921,12 +923,12 @@ op_switch_to_flush(Config) -> %% (verify with coverage of flush_log_requests/2) NewHConfig = - HConfig#{logger_disk_log_h => - DLHConfig#{toggle_sync_qlen => 2, + HConfig#{config => + DLHConfig#{sync_mode_qlen => 2, %% disable drop mode - drop_new_reqs_qlen => 300, - flush_reqs_qlen => 300, - enable_burst_limit => false}}, + drop_mode_qlen => 300, + flush_qlen => 300, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), NumOfReqs = 1500, Procs = 10, @@ -938,11 +940,11 @@ op_switch_to_flush(Config) -> %% sync messages gets tested). Therefore, lets %% generate a number of bursts to increase the chance %% of message buildup in some random fashion. - [send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, info) || + [send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice) || _ <- lists:seq(1,Bursts)], Logged = count_lines(Log), ok= stop_handler(?MODULE), - _ = file:delete(Log), + _ = file_delete(Log), ct:pal("Number of messages flushed/dropped = ~w (~w)", [NumOfReqs*Procs*Bursts-Logged,NumOfReqs*Procs*Bursts]), true = (Logged < (NumOfReqs*Procs*Bursts)), @@ -964,17 +966,17 @@ op_switch_to_flush(cleanup, _Config) -> limit_burst_disabled(Config) -> {Log,HConfig,DLHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NewHConfig = - HConfig#{logger_disk_log_h => DLHConfig#{enable_burst_limit => false, - burst_limit_size => 10, - burst_window_time => 2000, - drop_new_reqs_qlen => 200, - flush_reqs_qlen => 300}}, + HConfig#{config => DLHConfig#{burst_limit_enable => false, + burst_limit_max_count => 10, + burst_limit_window_time => 2000, + drop_mode_qlen => 200, + flush_qlen => 300}}, ok = logger:set_handler_config(?MODULE, NewHConfig), NumOfReqs = 100, - send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages logged = ~w", [Logged]), - ok = file:delete(Log), + ok = file_delete(Log), NumOfReqs = Logged. limit_burst_disabled(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -983,17 +985,17 @@ limit_burst_enabled_one(Config) -> {Log,HConfig,DLHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), ReqLimit = 10, NewHConfig = - HConfig#{logger_disk_log_h => DLHConfig#{enable_burst_limit => true, - burst_limit_size => ReqLimit, - burst_window_time => 2000, - drop_new_reqs_qlen => 200, - flush_reqs_qlen => 300}}, + HConfig#{config => DLHConfig#{burst_limit_enable => true, + burst_limit_max_count => ReqLimit, + burst_limit_window_time => 2000, + drop_mode_qlen => 200, + flush_qlen => 300}}, ok = logger:set_handler_config(?MODULE, NewHConfig), NumOfReqs = 100, - send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages logged = ~w", [Logged]), - ok = file:delete(Log), + ok = file_delete(Log), ReqLimit = Logged. limit_burst_enabled_one(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -1003,19 +1005,19 @@ limit_burst_enabled_period(Config) -> ReqLimit = 10, BurstTWin = 1000, NewHConfig = - HConfig#{logger_disk_log_h => DLHConfig#{enable_burst_limit => true, - burst_limit_size => ReqLimit, - burst_window_time => BurstTWin, - drop_new_reqs_qlen => 20000, - flush_reqs_qlen => 20001}}, + HConfig#{config => DLHConfig#{burst_limit_enable => true, + burst_limit_max_count => ReqLimit, + burst_limit_window_time => BurstTWin, + drop_mode_qlen => 20000, + flush_qlen => 20001}}, ok = logger:set_handler_config(?MODULE, NewHConfig), Windows = 3, - Sent = send_burst({t,BurstTWin*Windows}, seq, {chars,79}, info), + Sent = send_burst({t,BurstTWin*Windows}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages sent = ~w~nNumber of messages logged = ~w", [Sent,Logged]), - ok = file:delete(Log), + ok = file_delete(Log), true = (Logged > (ReqLimit*Windows)) andalso (Logged < (ReqLimit*(Windows+2))). limit_burst_enabled_period(cleanup, _Config) -> @@ -1024,37 +1026,37 @@ limit_burst_enabled_period(cleanup, _Config) -> kill_disabled(Config) -> {Log,HConfig,DLHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NewHConfig = - HConfig#{logger_disk_log_h=>DLHConfig#{enable_kill_overloaded=>false, - handler_overloaded_qlen=>10, - handler_overloaded_mem=>100}}, + HConfig#{config=>DLHConfig#{overload_kill_enable=>false, + overload_kill_qlen=>10, + overload_kill_mem_size=>100}}, ok = logger:set_handler_config(?MODULE, NewHConfig), NumOfReqs = 100, - send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages logged = ~w", [Logged]), - ok = file:delete(Log), - true = is_pid(whereis(?MODULE)), + ok = file_delete(Log), + true = is_pid(whereis(h_proc_name())), ok. kill_disabled(cleanup, _Config) -> ok = stop_handler(?MODULE). qlen_kill_new(Config) -> {_Log,HConfig,DLHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), - Pid0 = whereis(?MODULE), + Pid0 = whereis(h_proc_name()), {_,Mem0} = process_info(Pid0, memory), - RestartAfter = ?HANDLER_RESTART_AFTER, + RestartAfter = ?OVERLOAD_KILL_RESTART_AFTER, NewHConfig = - HConfig#{logger_disk_log_h => - DLHConfig#{enable_kill_overloaded=>true, - handler_overloaded_qlen=>10, - handler_overloaded_mem=>Mem0+50000, - handler_restart_after=>RestartAfter}}, + HConfig#{config => + DLHConfig#{overload_kill_enable=>true, + overload_kill_qlen=>10, + overload_kill_mem_size=>Mem0+50000, + overload_kill_restart_after=>RestartAfter}}, ok = logger:set_handler_config(?MODULE, NewHConfig), MRef = erlang:monitor(process, Pid0), NumOfReqs = 100, Procs = 2, - send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, info), - %% send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice), + %% send_burst({n,NumOfReqs}, seq, {chars,79}, notice), receive {'DOWN', MRef, _, _, Info} -> case Info of @@ -1064,7 +1066,7 @@ qlen_kill_new(Config) -> ct:pal("Slow shutdown, handler process was killed!", []) end, timer:sleep(RestartAfter + 2000), - true = is_pid(whereis(?MODULE)), + true = is_pid(whereis(h_proc_name())), ok after 5000 -> @@ -1077,21 +1079,21 @@ qlen_kill_new(cleanup, _Config) -> mem_kill_new(Config) -> {_Log,HConfig,DLHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), - Pid0 = whereis(?MODULE), + Pid0 = whereis(h_proc_name()), {_,Mem0} = process_info(Pid0, memory), - RestartAfter = ?HANDLER_RESTART_AFTER, + RestartAfter = ?OVERLOAD_KILL_RESTART_AFTER, NewHConfig = - HConfig#{logger_disk_log_h => - DLHConfig#{enable_kill_overloaded=>true, - handler_overloaded_qlen=>50000, - handler_overloaded_mem=>Mem0+500, - handler_restart_after=>RestartAfter}}, + HConfig#{config => + DLHConfig#{overload_kill_enable=>true, + overload_kill_qlen=>50000, + overload_kill_mem_size=>Mem0+500, + overload_kill_restart_after=>RestartAfter}}, ok = logger:set_handler_config(?MODULE, NewHConfig), MRef = erlang:monitor(process, Pid0), NumOfReqs = 100, Procs = 2, - send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, info), - %% send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice), + %% send_burst({n,NumOfReqs}, seq, {chars,79}, notice), receive {'DOWN', MRef, _, _, Info} -> case Info of @@ -1101,7 +1103,7 @@ mem_kill_new(Config) -> ct:pal("Slow shutdown, handler process was killed!", []) end, timer:sleep(RestartAfter + 2000), - true = is_pid(whereis(?MODULE)), + true = is_pid(whereis(h_proc_name())), ok after 5000 -> @@ -1115,17 +1117,17 @@ mem_kill_new(cleanup, _Config) -> restart_after(Config) -> {Log,HConfig,DLHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NewHConfig1 = - HConfig#{logger_disk_log_h=>DLHConfig#{enable_kill_overloaded=>true, - handler_overloaded_qlen=>10, - handler_restart_after=>never}}, + HConfig#{config=>DLHConfig#{overload_kill_enable=>true, + overload_kill_qlen=>10, + overload_kill_restart_after=>never}}, ok = logger:set_handler_config(?MODULE, NewHConfig1), - MRef1 = erlang:monitor(process, whereis(?MODULE)), + MRef1 = erlang:monitor(process, whereis(h_proc_name())), %% kill handler - send_burst({n,100}, {spawn,2,0}, {chars,79}, info), + send_burst({n,100}, {spawn,2,0}, {chars,79}, notice), receive {'DOWN', MRef1, _, _, _Info1} -> - timer:sleep(?HANDLER_RESTART_AFTER + 1000), - undefined = whereis(?MODULE), + timer:sleep(?OVERLOAD_KILL_RESTART_AFTER + 1000), + undefined = whereis(h_proc_name()), ok after 5000 -> @@ -1133,20 +1135,20 @@ restart_after(Config) -> end, {Log,_,_} = start_handler(?MODULE, ?FUNCTION_NAME, Config), - RestartAfter = ?HANDLER_RESTART_AFTER, + RestartAfter = ?OVERLOAD_KILL_RESTART_AFTER, NewHConfig2 = - HConfig#{logger_disk_log_h=>DLHConfig#{enable_kill_overloaded=>true, - handler_overloaded_qlen=>10, - handler_restart_after=>RestartAfter}}, + HConfig#{config=>DLHConfig#{overload_kill_enable=>true, + overload_kill_qlen=>10, + overload_kill_restart_after=>RestartAfter}}, ok = logger:set_handler_config(?MODULE, NewHConfig2), - Pid0 = whereis(?MODULE), + Pid0 = whereis(h_proc_name()), MRef2 = erlang:monitor(process, Pid0), %% kill handler - send_burst({n,100}, {spawn,2,0}, {chars,79}, info), + send_burst({n,100}, {spawn,2,0}, {chars,79}, notice), receive {'DOWN', MRef2, _, _, _Info2} -> timer:sleep(RestartAfter + 2000), - Pid1 = whereis(?MODULE), + Pid1 = whereis(h_proc_name()), true = is_pid(Pid1), false = (Pid1 == Pid0), ok @@ -1158,7 +1160,7 @@ restart_after(Config) -> restart_after(cleanup, _Config) -> ok = stop_handler(?MODULE). -%% send handler requests (filesync, info, reset, change_config) +%% send handler requests (sync, info, reset, change_config) %% during high load to verify that sync, dropping and flushing is %% handled correctly. handler_requests_under_load() -> @@ -1166,18 +1168,18 @@ handler_requests_under_load() -> handler_requests_under_load(Config) -> {Log,HConfig,DLHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NewHConfig = - HConfig#{logger_disk_log_h => DLHConfig#{toggle_sync_qlen => 2, - drop_new_reqs_qlen => 1000, - flush_reqs_qlen => 2000, - enable_burst_limit => false}}, + HConfig#{config => DLHConfig#{sync_mode_qlen => 2, + drop_mode_qlen => 1000, + flush_qlen => 2000, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), - Pid = spawn_link(fun() -> send_requests(?MODULE, 1, [{disk_log_sync,[]}, + Pid = spawn_link(fun() -> send_requests(?MODULE, 1, [{sync,[]}, {info,[]}, {reset,[]}, {change_config,[]}]) end), Procs = 100, - Sent = Procs * send_burst({n,5000}, {spawn,Procs,10}, {chars,79}, info), + Sent = Procs * send_burst({n,5000}, {spawn,Procs,10}, {chars,79}, notice), Pid ! {self(),finish}, ReqResult = receive {Pid,Result} -> Result end, Logged = count_lines(Log), @@ -1190,7 +1192,7 @@ handler_requests_under_load(Config) -> Errors = [{Req,FindError(Res)} || {Req,Res} <- ReqResult], NoOfReqs = lists:foldl(fun({_,Res}, N) -> N + length(Res) end, 0, ReqResult), ct:pal("~w requests made. Errors: ~n~p", [NoOfReqs,Errors]), - ok = file:delete(Log). + ok = file_delete(Log). handler_requests_under_load(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -1204,7 +1206,7 @@ send_requests(HName, TO, Reqs = [{Req,Res}|Rs]) -> case Req of change_config -> logger:set_handler_config(HName, logger_disk_log_h, - #{enable_kill_overloaded => + #{overload_kill_enable => false}); Func -> logger_disk_log_h:Func(HName) @@ -1220,19 +1222,18 @@ start_handler(Name, FuncName, Config) -> ct:pal("Logging to ~tp", [File]), ok = logger:add_handler(Name, logger_disk_log_h, - #{disk_log_opts=>#{file => File, - max_no_files => 1, - max_no_bytes => 100000000}, + #{config=>#{file => File, + max_no_files => 1, + max_no_bytes => 100000000}, filter_default=>log, filters=>?DEFAULT_HANDLER_FILTERS([Name]), formatter=>{?MODULE,op}}), - {ok,{_,HConfig = #{logger_disk_log_h := DLHConfig}}} = - logger:get_handler_config(Name), + {ok,HConfig = #{config := DLHConfig}} = logger:get_handler_config(Name), {lists:concat([File,".1"]),HConfig,DLHConfig}. stop_handler(Name) -> - ok = logger:remove_handler(Name), - ct:pal("Handler ~p stopped!", [Name]). + ct:pal("Stopping handler ~p!", [Name]), + logger:remove_handler(Name). send_burst(NorT, Type, {chars,Sz}, Class) -> Text = [34 + rand:uniform(126-34) || _ <- lists:seq(1,Sz)], @@ -1304,9 +1305,11 @@ format(#{msg:={report,#{label:={gen_server,terminate}}}},op) -> ""; format(#{msg:={report,#{label:={proc_lib,crash}}}},op) -> ""; -format(#{msg:={F,A}},Pid) when is_list(F), is_list(A) -> +format(#{msg:={F,A}},OpOrPid) when is_list(F), is_list(A) -> String = lists:flatten(io_lib:format(F,A)), - Pid ! {log,String}, + if is_pid(OpOrPid) -> OpOrPid ! {log,String}; + true -> ok + end, String++"\n"; format(#{msg:={string,String0}},Pid) -> String = unicode:characters_to_list(String0), @@ -1322,16 +1325,17 @@ remove(Handler, LogName) -> HState = #{log_names := Logs} = logger_disk_log_h:info(), false = maps:is_key(LogName, HState), false = lists:member(LogName, Logs), - false = logger_config:exist(logger, LogName), + false = logger_config:exist(?LOGGER_TABLE, LogName), {error,no_such_log} = disk_log:info(LogName), ok. start_and_add(Name, Config, LogOpts) -> - ct:pal("Adding handler ~w with: ~p", - [Name,Config#{disk_log_opts=>LogOpts}]), - ok = logger:add_handler(Name, logger_disk_log_h, - Config#{disk_log_opts=>LogOpts}), - Pid = whereis(Name), + HConfig = maps:get(config, Config, #{}), + HConfig1 = maps:merge(HConfig, LogOpts), + Config1 = Config#{config=>HConfig1}, + ct:pal("Adding handler ~w with: ~p", [Name,Config1]), + ok = logger:add_handler(Name, logger_disk_log_h, Config1), + Pid = whereis(h_proc_name(Name)), true = is_pid(Pid), Name = proplists:get_value(name, disk_log:info(Name)), ok. @@ -1339,7 +1343,7 @@ start_and_add(Name, Config, LogOpts) -> remove_and_stop(Handler) -> ok = logger:remove_handler(Handler), timer:sleep(500), - undefined = whereis(Handler), + undefined = whereis(h_proc_name(Handler)), ok. try_read_file(FileName, Expected, Time) -> @@ -1405,17 +1409,21 @@ wait_until_written(File, Sz) -> end. count_lines1(File) -> - Counter = fun Cnt(Dev,LC) -> - case file:read_line(Dev) of - eof -> LC; - _ -> Cnt(Dev,LC+1) - end - end, {_,Dev} = file:open(File, [read]), - Lines = Counter(Dev, 0), + Lines = count_lines2(Dev, 0), file:close(Dev), Lines. +count_lines2(Dev, LC) -> + case file:read_line(Dev) of + {ok,"Handler logger_disk_log_h_SUITE " ++_} -> + %% Not counting handler info + count_lines2(Dev,LC); + {ok,_} -> + count_lines2(Dev,LC+1); + eof -> LC + end. + repeat_until_ok(Fun, N) -> repeat_until_ok(Fun, 0, N, undefined). @@ -1442,7 +1450,7 @@ repeat_until_ok(Fun, C, Stop, FirstReason) -> start_tracer(Trace,Expected) -> Pid = self(), dbg:tracer(process,{fun tracer/2,{Pid,Expected}}), - dbg:p(whereis(?MODULE),[c]), + dbg:p(h_proc_name(),[c]), tpl(Trace), ok. @@ -1498,3 +1506,11 @@ escape([H|T]) -> [H|escape(T)]; escape([]) -> []. + +h_proc_name() -> + h_proc_name(?MODULE). +h_proc_name(Name) -> + list_to_atom(lists:concat([logger_disk_log_h,"_",Name])). + +file_delete(Log) -> + file:delete(Log). diff --git a/lib/kernel/test/logger_env_var_SUITE.erl b/lib/kernel/test/logger_env_var_SUITE.erl index 601d331fb0..6e182d4bca 100644 --- a/lib/kernel/test/logger_env_var_SUITE.erl +++ b/lib/kernel/test/logger_env_var_SUITE.erl @@ -63,8 +63,7 @@ groups() -> ]}, {bad,[],[bad_error_logger, bad_level, - bad_sasl_compatibility, - bad_progress]}]. + bad_sasl_compatibility]}]. all() -> [default, @@ -78,128 +77,126 @@ all() -> ]. default(Config) -> - {ok,#{handlers:=Hs},_Node} = setup(Config,[]), - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + {ok,#{primary:=P,handlers:=Hs,module_levels:=ML},_Node} = setup(Config,[]), + notice = maps:get(level,P), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), - {domain,{_,{log,super,[beam,erlang,otp,sasl]}}} = - lists:keyfind(domain,1,StdFilters), - true = lists:keymember(stop_progress,1,StdFilters), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), + {domain,{_,{log,super,[otp,sasl]}}} = lists:keyfind(domain,1,StdFilters), + false = exists(simple,Hs), + false = exists(sasl,Hs), + [] = ML, ok. default_sasl_compatible(Config) -> - {ok,#{handlers:=Hs},_Node} = setup(Config, - [{logger_sasl_compatible,true}]), - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + {ok,#{primary:=P,handlers:=Hs,module_levels:=ML},_Node} = + setup(Config,[{logger_sasl_compatible,true}]), + info = maps:get(level,P), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), - {domain,{_,{log,super,[beam,erlang,otp]}}} = - lists:keyfind(domain,1,StdFilters), - false = lists:keymember(stop_progress,1,StdFilters), - false = lists:keymember(simple,1,Hs), - true = lists:keymember(sasl,1,Hs), + {domain,{_,{log,super,[otp]}}} = lists:keyfind(domain,1,StdFilters), + false = exists(simple,Hs), + true = exists(sasl,Hs), + [] = ML, ok. error_logger_tty(Config) -> - {ok,#{handlers:=Hs},_Node} = setup(Config,[{error_logger,tty}]), - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + {ok,#{primary:=P,handlers:=Hs,module_levels:=ML},_Node} = + setup(Config,[{error_logger,tty}]), + notice = maps:get(level,P), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), - {domain,{_,{log,super,[beam,erlang,otp,sasl]}}} = - lists:keyfind(domain,1,StdFilters), - true = lists:keymember(stop_progress,1,StdFilters), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), + {domain,{_,{log,super,[otp,sasl]}}} = lists:keyfind(domain,1,StdFilters), + false = exists(simple,Hs), + false = exists(sasl,Hs), + [] = ML, ok. error_logger_tty_sasl_compatible(Config) -> - {ok,#{handlers:=Hs},_Node} = setup(Config, - [{error_logger,tty}, - {logger_sasl_compatible,true}]), - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + {ok,#{primary:=P,handlers:=Hs,module_levels:=ML},_Node} = + setup(Config, + [{error_logger,tty}, + {logger_sasl_compatible,true}]), + info = maps:get(level,P), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), - {domain,{_,{log,super,[beam,erlang,otp]}}} = - lists:keyfind(domain,1,StdFilters), - false = lists:keymember(stop_progress,1,StdFilters), - false = lists:keymember(simple,1,Hs), - true = lists:keymember(sasl,1,Hs), + {domain,{_,{log,super,[otp]}}} = lists:keyfind(domain,1,StdFilters), + false = exists(simple,Hs), + true = exists(sasl,Hs), + [] = ML, ok. error_logger_false(Config) -> - {ok,#{handlers:=Hs,logger:=L},_Node} = + {ok,#{handlers:=Hs,primary:=P,module_levels:=ML},_Node} = setup(Config, [{error_logger,false}, {logger_level,notice}]), - false = lists:keymember(?STANDARD_HANDLER,1,Hs), - {simple,logger_simple_h,SimpleC} = lists:keyfind(simple,1,Hs), - info = maps:get(level,SimpleC), - notice = maps:get(level,L), + false = exists(?STANDARD_HANDLER,Hs), + #{module:=logger_simple_h} = SimpleC = find(simple,Hs), + all = maps:get(level,SimpleC), + notice = maps:get(level,P), SimpleFilters = maps:get(filters,SimpleC), - {domain,{_,{log,super,[beam,erlang,otp,sasl]}}} = - lists:keyfind(domain,1,SimpleFilters), - true = lists:keymember(stop_progress,1,SimpleFilters), - false = lists:keymember(sasl,1,Hs), + {domain,{_,{log,super,[otp,sasl]}}} = lists:keyfind(domain,1,SimpleFilters), + false = exists(sasl,Hs), + [] = ML, ok. error_logger_false_progress(Config) -> - {ok,#{handlers:=Hs,logger:=L},_Node} = + {ok,#{handlers:=Hs,primary:=P,module_levels:=ML},_Node} = setup(Config, [{error_logger,false}, - {logger_level,notice}, - {logger_progress_reports,log}]), - false = lists:keymember(?STANDARD_HANDLER,1,Hs), - {simple,logger_simple_h,SimpleC} = lists:keyfind(simple,1,Hs), - info = maps:get(level,SimpleC), - notice = maps:get(level,L), + {logger_level,notice}]), + false = exists(?STANDARD_HANDLER,Hs), + #{module:=logger_simple_h} = SimpleC = find(simple,Hs), + all = maps:get(level,SimpleC), + notice = maps:get(level,P), SimpleFilters = maps:get(filters,SimpleC), - {domain,{_,{log,super,[beam,erlang,otp,sasl]}}} = - lists:keyfind(domain,1,SimpleFilters), - false = lists:keymember(stop_progress,1,SimpleFilters), - false = lists:keymember(sasl,1,Hs), + {domain,{_,{log,super,[otp,sasl]}}} = lists:keyfind(domain,1,SimpleFilters), + false = exists(sasl,Hs), + [] = ML, ok. error_logger_false_sasl_compatible(Config) -> - {ok,#{handlers:=Hs,logger:=L},_Node} = + {ok,#{handlers:=Hs,primary:=P,module_levels:=ML},_Node} = setup(Config, [{error_logger,false}, {logger_level,notice}, {logger_sasl_compatible,true}]), - false = lists:keymember(?STANDARD_HANDLER,1,Hs), - {simple,logger_simple_h,SimpleC} = lists:keyfind(simple,1,Hs), - info = maps:get(level,SimpleC), - notice = maps:get(level,L), + false = exists(?STANDARD_HANDLER,Hs), + #{module:=logger_simple_h} = SimpleC = find(simple,Hs), + all = maps:get(level,SimpleC), + info = maps:get(level,P), SimpleFilters = maps:get(filters,SimpleC), - {domain,{_,{log,super,[beam,erlang,otp]}}} = - lists:keyfind(domain,1,SimpleFilters), - false = lists:keymember(stop_progress,1,SimpleFilters), - true = lists:keymember(sasl,1,Hs), + {domain,{_,{log,super,[otp]}}} = lists:keyfind(domain,1,SimpleFilters), + true = exists(sasl,Hs), + [] = ML, ok. error_logger_silent(Config) -> {ok,#{handlers:=Hs},_Node} = setup(Config, [{error_logger,silent}]), - false = lists:keymember(?STANDARD_HANDLER,1,Hs), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), + false = exists(?STANDARD_HANDLER,Hs), + false = exists(simple,Hs), + false = exists(sasl,Hs), ok. error_logger_silent_sasl_compatible(Config) -> {ok,#{handlers:=Hs},_Node} = setup(Config, [{error_logger,silent}, {logger_sasl_compatible,true}]), - false = lists:keymember(?STANDARD_HANDLER,1,Hs), - false = lists:keymember(simple,1,Hs), - true = lists:keymember(sasl,1,Hs), + false = exists(?STANDARD_HANDLER,Hs), + false = exists(simple,Hs), + true = exists(sasl,Hs), ok. error_logger_file(Config) -> Log = file(Config,?FUNCTION_NAME), - {ok,_Hs,Node} = setup(Config, - [{error_logger,{file,Log}}]), + {ok,_,Node} = setup(Config, + [{error_logger,{file,Log}}]), check_default_log(Node,Log, file,% dest 0),% progress in std logger @@ -208,70 +205,67 @@ error_logger_file(Config) -> logger_file(Config) -> Log = file(Config,?FUNCTION_NAME), - {ok,#{handlers:=Hs},Node} + {ok,#{primary:=P,handlers:=Hs,module_levels:=ML},Node} = setup(Config, [{logger, [{handler,?STANDARD_HANDLER,logger_std_h, - #{logger_std_h=>#{type=>{file,Log}}}}]}]), + #{config=>#{type=>{file,Log}}}}]}]), check_default_log(Node,Log, file,% dest 0),% progress in std logger - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), - {domain,{_,{log,super,[beam,erlang,otp,sasl]}}} = - lists:keyfind(domain,1,StdFilters), - true = lists:keymember(stop_progress,1,StdFilters), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), - + {domain,{_,{log,super,[otp,sasl]}}} = lists:keyfind(domain,1,StdFilters), + false = exists(simple,Hs), + false = exists(sasl,Hs), + [] = ML, ok. logger_file_sasl_compatible(Config) -> Log = file(Config,?FUNCTION_NAME), - {ok,#{handlers:=Hs},Node} + {ok,#{primary:=P,handlers:=Hs,module_levels:=ML},Node} = setup(Config, [{logger_sasl_compatible,true}, {logger, [{handler,?STANDARD_HANDLER,logger_std_h, - #{logger_std_h=>#{type=>{file,Log}}}}]}]), + #{config=>#{type=>{file,Log}}}}]}]), check_default_log(Node,Log, file,% dest 0),% progress in std logger - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + info = maps:get(level,P), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), - {domain,{_,{log,super,[beam,erlang,otp]}}} = - lists:keyfind(domain,1,StdFilters), - false = lists:keymember(stop_progress,1,StdFilters), - false = lists:keymember(simple,1,Hs), - true = lists:keymember(sasl,1,Hs), - + {domain,{_,{log,super,[otp]}}} = lists:keyfind(domain,1,StdFilters), + false = exists(simple,Hs), + true = exists(sasl,Hs), + [] = ML, ok. logger_file_log_progress(Config) -> Log = file(Config,?FUNCTION_NAME), - {ok,#{handlers:=Hs},Node} + {ok,#{primary:=P,handlers:=Hs,module_levels:=ML},Node} = setup(Config, - [{logger_progress_reports,log}, + [{logger_level,info}, {logger, [{handler,?STANDARD_HANDLER,logger_std_h, - #{logger_std_h=>#{type=>{file,Log}}}}]}]), + #{config=>#{type=>{file,Log}}}}]}]), check_default_log(Node,Log, file,% dest - 6),% progress in std logger + 6,% progress in std logger + info), - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + info = maps:get(level,P), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), - {domain,{_,{log,super,[beam,erlang,otp,sasl]}}} = - lists:keyfind(domain,1,StdFilters), - false = lists:keymember(stop_progress,1,StdFilters), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), - + {domain,{_,{log,super,[otp,sasl]}}} = lists:keyfind(domain,1,StdFilters), + false = exists(simple,Hs), + false = exists(sasl,Hs), + [] = ML, ok. logger_file_no_filter(Config) -> @@ -281,16 +275,16 @@ logger_file_no_filter(Config) -> [{logger, [{handler,?STANDARD_HANDLER,logger_std_h, #{filter_default=>log,filters=>[], - logger_std_h=>#{type=>{file,Log}}}}]}]), + config=>#{type=>{file,Log}}}}]}]), check_default_log(Node,Log, file,% dest 6),% progress in std logger - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), [] = maps:get(filters,StdC), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), + false = exists(simple,Hs), + false = exists(sasl,Hs), ok. @@ -301,17 +295,17 @@ logger_file_no_filter_level(Config) -> [{logger, [{handler,?STANDARD_HANDLER,logger_std_h, #{filters=>[],level=>error, - logger_std_h=>#{type=>{file,Log}}}}]}]), + config=>#{type=>{file,Log}}}}]}]), check_default_log(Node,Log, file,% dest 0,% progress in std logger error),% level - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), error = maps:get(level,StdC), [] = maps:get(filters,StdC), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), + false = exists(simple,Hs), + false = exists(sasl,Hs), ok. @@ -323,68 +317,67 @@ logger_file_formatter(Config) -> [{handler,?STANDARD_HANDLER,logger_std_h, #{filters=>[], formatter=>{logger_formatter,#{}}, - logger_std_h=>#{type=>{file,Log}}}}]}]), + config=>#{type=>{file,Log}}}}]}]), check_single_log(Node,Log, file,% dest 6),% progress in std logger - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), [] = maps:get(filters,StdC), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), + false = exists(simple,Hs), + false = exists(sasl,Hs), ok. logger_filters(Config) -> Log = file(Config,?FUNCTION_NAME), - {ok,#{handlers:=Hs,logger:=Logger},Node} + {ok,#{handlers:=Hs,primary:=P},Node} = setup(Config, - [{logger_progress_reports,log}, + [{logger_level,info}, {logger, [{handler,?STANDARD_HANDLER,logger_std_h, - #{logger_std_h=>#{type=>{file,Log}}}}, + #{config=>#{type=>{file,Log}}}}, {filters,log,[{stop_progress,{fun logger_filters:progress/2,stop}}]} ]}]), check_default_log(Node,Log, file,% dest - 0),% progress in std logger + 0,% progress in std logger + info), - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), - {domain,{_,{log,super,[beam,erlang,otp,sasl]}}} = - lists:keyfind(domain,1,StdFilters), - false = lists:keymember(stop_progress,1,StdFilters), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), - LoggerFilters = maps:get(filters,Logger), + {domain,{_,{log,super,[otp,sasl]}}} = lists:keyfind(domain,1,StdFilters), + false = exists(simple,Hs), + false = exists(sasl,Hs), + LoggerFilters = maps:get(filters,P), true = lists:keymember(stop_progress,1,LoggerFilters), ok. logger_filters_stop(Config) -> Log = file(Config,?FUNCTION_NAME), - {ok,#{handlers:=Hs,logger:=Logger},Node} + {ok,#{handlers:=Hs,primary:=P},Node} = setup(Config, - [{logger_progress_reports,log}, + [{logger_level,info}, {logger, [{handler,?STANDARD_HANDLER,logger_std_h, #{filters=>[], - logger_std_h=>#{type=>{file,Log}}}}, + config=>#{type=>{file,Log}}}}, {filters,stop,[{log_error,{fun logger_filters:level/2,{log,gt,info}}}]} ]}]), check_default_log(Node,Log, file,% dest - 0, - notice),% progress in std logger + 0,% progress in std logger + info), - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), [] = maps:get(filters,StdC), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), - LoggerFilters = maps:get(filters,Logger), + false = exists(simple,Hs), + false = exists(sasl,Hs), + LoggerFilters = maps:get(filters,P), true = lists:keymember(log_error,1,LoggerFilters), ok. @@ -393,24 +386,23 @@ logger_module_level(Config) -> Log = file(Config,?FUNCTION_NAME), {ok,#{handlers:=Hs,module_levels:=ModuleLevels},Node} = setup(Config, - [{logger_progress_reports,log}, + [{logger_level,info}, {logger, [{handler,?STANDARD_HANDLER,logger_std_h, - #{logger_std_h=>#{type=>{file,Log}}}}, + #{config=>#{type=>{file,Log}}}}, {module_level,error,[supervisor]} ]}]), check_default_log(Node,Log, file,% dest - 3),% progress in std logger + 3,% progress in std logger + info), - {?STANDARD_HANDLER,logger_std_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), - {domain,{_,{log,super,[beam,erlang,otp,sasl]}}} = - lists:keyfind(domain,1,StdFilters), - false = lists:keymember(stop_progress,1,StdFilters), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), + {domain,{_,{log,super,[otp,sasl]}}} = lists:keyfind(domain,1,StdFilters), + false = exists(simple,Hs), + false = exists(sasl,Hs), [{supervisor,error}] = ModuleLevels, ok. @@ -420,19 +412,17 @@ logger_disk_log(Config) -> = setup(Config, [{logger, [{handler,?STANDARD_HANDLER,logger_disk_log_h, - #{disk_log_opts=>#{file=>Log}}}]}]), + #{config=>#{file=>Log}}}]}]), check_default_log(Node,Log, disk_log,% dest 0),% progress in std logger - {?STANDARD_HANDLER,logger_disk_log_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + #{module:=logger_disk_log_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), - {domain,{_,{log,super,[beam,erlang,otp,sasl]}}} = - lists:keyfind(domain,1,StdFilters), - true = lists:keymember(stop_progress,1,StdFilters), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), + {domain,{_,{log,super,[otp,sasl]}}} = lists:keyfind(domain,1,StdFilters), + false = exists(simple,Hs), + false = exists(sasl,Hs), ok. @@ -444,31 +434,29 @@ logger_disk_log_formatter(Config) -> [{handler,?STANDARD_HANDLER,logger_disk_log_h, #{filters=>[], formatter=>{logger_formatter,#{}}, - disk_log_opts=>#{file=>Log}}}]}]), + config=>#{file=>Log}}}]}]), check_single_log(Node,Log, disk_log,% dest 6),% progress in std logger - {?STANDARD_HANDLER,logger_disk_log_h,StdC} = lists:keyfind(?STANDARD_HANDLER,1,Hs), - info = maps:get(level,StdC), + #{module:=logger_disk_log_h} = StdC = find(?STANDARD_HANDLER,Hs), + all = maps:get(level,StdC), [] = maps:get(filters,StdC), - false = lists:keymember(simple,1,Hs), - false = lists:keymember(sasl,1,Hs), + false = exists(simple,Hs), + false = exists(sasl,Hs), ok. logger_undefined(Config) -> - {ok,#{handlers:=Hs,logger:=L},_Node} = + {ok,#{handlers:=Hs,primary:=P},_Node} = setup(Config,[{logger,[{handler,?STANDARD_HANDLER,undefined}]}]), - false = lists:keymember(?STANDARD_HANDLER,1,Hs), - {simple,logger_simple_h,SimpleC} = lists:keyfind(simple,1,Hs), - info = maps:get(level,SimpleC), - info = maps:get(level,L), + false = exists(?STANDARD_HANDLER,Hs), + #{module:=logger_simple_h} = SimpleC = find(simple,Hs), + all = maps:get(level,SimpleC), + notice = maps:get(level,P), SimpleFilters = maps:get(filters,SimpleC), - {domain,{_,{log,super,[beam,erlang,otp,sasl]}}} = - lists:keyfind(domain,1,SimpleFilters), - true = lists:keymember(stop_progress,1,SimpleFilters), - false = lists:keymember(sasl,1,Hs), + {domain,{_,{log,super,[otp,sasl]}}} = lists:keyfind(domain,1,SimpleFilters), + false = exists(sasl,Hs), ok. @@ -483,14 +471,15 @@ logger_many_handlers_default_first(Config) -> #{level=>error, filters=>[], formatter=>{logger_formatter,#{}}, - logger_std_h=>#{type=>{file,LogErr}}} + config=>#{type=>{file,LogErr}}} }, {handler,info,logger_std_h, #{level=>info, filters=>[{level,{fun logger_filters:level/2,{stop,gteq,error}}}], - logger_std_h=>#{type=>{file,LogInfo}}} + config=>#{type=>{file,LogInfo}}} } - ]}], LogErr, LogInfo, 6). + ]}, + {logger_level,info}], LogErr, LogInfo, 6). %% Test that we can add multiple handlers with the default last logger_many_handlers_default_last(Config) -> @@ -501,15 +490,16 @@ logger_many_handlers_default_last(Config) -> [{handler,info,logger_std_h, #{level=>info, filters=>[{level,{fun logger_filters:level/2,{stop,gteq,error}}}], - logger_std_h=>#{type=>{file,LogInfo}}} + config=>#{type=>{file,LogInfo}}} }, {handler,?STANDARD_HANDLER,logger_std_h, #{level=>error, filters=>[], formatter=>{logger_formatter,#{}}, - logger_std_h=>#{type=>{file,LogErr}}} + config=>#{type=>{file,LogErr}}} } - ]}], LogErr, LogInfo, 7). + ]}, + {logger_level,info}], LogErr, LogInfo, 7). %% Check that we can handle that an added logger has a broken filter %% This used to cause a deadlock. @@ -523,15 +513,16 @@ logger_many_handlers_default_last_broken_filter(Config) -> #{level=>info, filters=>[{broken,{fun logger_filters:level/2,broken_state}}, {level,{fun logger_filters:level/2,{stop,gteq,error}}}], - logger_std_h=>#{type=>{file,LogInfo}}} + config=>#{type=>{file,LogInfo}}} }, {handler,?STANDARD_HANDLER,logger_std_h, #{level=>error, filters=>[], formatter=>{logger_formatter,#{}}, - logger_std_h=>#{type=>{file,LogErr}}} + config=>#{type=>{file,LogErr}}} } - ]}], LogErr, LogInfo, 7). + ]}, + {logger_level,info}], LogErr, LogInfo, 7). logger_many_handlers(Config, Env, LogErr, LogInfo, NumProgress) -> {ok,#{handlers:=Hs},Node} = setup(Config,Env), @@ -539,31 +530,32 @@ logger_many_handlers(Config, Env, LogErr, LogInfo, NumProgress) -> file,% dest 0,% progress in std logger error), % level - ok = rpc:call(Node,logger_std_h,filesync,[info]), + ok = rpc:call(Node,logger_std_h,sync,[info]), {ok, Bin} = file:read_file(LogInfo), ct:log("Log content:~n~s",[Bin]), - match(Bin,<<"info:">>,NumProgress+1,info,info), + match(Bin,<<"info:">>,NumProgress,info,info), + match(Bin,<<"notice:">>,1,notice,info), match(Bin,<<"alert:">>,0,alert,info), ok. sasl_compatible_false(Config) -> Log = file(Config,?FUNCTION_NAME), - {ok,_Hs,Node} = setup(Config, - [{error_logger,{file,Log}}, - {logger_sasl_compatible,false}, - {logger_progress_reports,log}]), + {ok,_,Node} = setup(Config, + [{error_logger,{file,Log}}, + {logger_sasl_compatible,false}, + {logger_level,info}]), % to get progress check_default_log(Node,Log, file,% dest - 6),% progress in std logger + 6,% progress in std logger + info), ok. sasl_compatible_false_no_progress(Config) -> Log = file(Config,?FUNCTION_NAME), - {ok,_Hs,Node} = setup(Config, - [{error_logger,{file,Log}}, - {logger_sasl_compatible,false}, - {logger_progress_reports,stop}]), + {ok,_,Node} = setup(Config, + [{error_logger,{file,Log}}, + {logger_sasl_compatible,false}]), check_default_log(Node,Log, file,% dest 0),% progress in std logger @@ -571,9 +563,9 @@ sasl_compatible_false_no_progress(Config) -> sasl_compatible(Config) -> Log = file(Config,?FUNCTION_NAME), - {ok,_Hs,Node} = setup(Config, - [{error_logger,{file,Log}}, - {sasl_compatible,true}]), + {ok,_,Node} = setup(Config, + [{error_logger,{file,Log}}, + {sasl_compatible,true}]), check_default_log(Node,Log, file,% dest 0),% progress in std logger @@ -588,9 +580,6 @@ bad_level(Config) -> bad_sasl_compatibility(Config) -> error = setup(Config,[{logger_sasl_compatible,badcomp}]). -bad_progress(Config) -> - error = setup(Config,[{logger_progress_reports,badprogress}]). - %%%----------------------------------------------------------------- %%% Internal file(Config,Func) -> @@ -598,22 +587,22 @@ file(Config,Func) -> lists:concat([Func,".log"])). check_default_log(Node,Log,Dest,NumProgress) -> - check_default_log(Node,Log,Dest,NumProgress,info). + check_default_log(Node,Log,Dest,NumProgress,notice). check_default_log(Node,Log,Dest,NumProgress,Level) -> {ok,Bin1,Bin2} = check_log(Node,Log,Dest), match(Bin1,<<"PROGRESS REPORT">>,NumProgress,info,Level), match(Bin1,<<"ALERT REPORT">>,1,alert,Level), - match(Bin1,<<"INFO REPORT">>,0,info,Level), + match(Bin1,<<"INFO REPORT">>,0,notice,Level), match(Bin1,<<"DEBUG REPORT">>,0,debug,Level), - match(Bin2,<<"INFO REPORT">>,1,info,Level), + match(Bin2,<<"INFO REPORT">>,1,notice,Level), match(Bin2,<<"DEBUG REPORT">>,0,debug,Level), ok. check_single_log(Node,Log,Dest,NumProgress) -> - check_single_log(Node,Log,Dest,NumProgress,info). + check_single_log(Node,Log,Dest,NumProgress,notice). check_single_log(Node,Log,Dest,NumProgress,Level) -> {ok,Bin1,Bin2} = check_log(Node,Log,Dest), @@ -654,3 +643,21 @@ match(Bin,Pattern,N,LogLevel,ConfLevel) -> {match,M} = re:run(Bin,Pattern,[{capture,all},global]), N = length(M) end. + +find(Id,Handlers) -> + case lists:search(fun(#{id:=Id0}) when Id0=:=Id-> true; + (_) -> false end, + Handlers) of + {value,Config} -> + Config; + false -> + false + end. + +exists(Id,Handlers) -> + case find(Id,Handlers) of + false -> + false; + _ -> + true + end. diff --git a/lib/kernel/test/logger_formatter_SUITE.erl b/lib/kernel/test/logger_formatter_SUITE.erl index 7a93f2ca79..864a40b618 100644 --- a/lib/kernel/test/logger_formatter_SUITE.erl +++ b/lib/kernel/test/logger_formatter_SUITE.erl @@ -56,6 +56,7 @@ groups() -> all() -> [default, legacy_header, + error_logger_notice_header, single_line, template, format_msg, @@ -69,6 +70,7 @@ all() -> faulty_log, faulty_config, faulty_msg, + check_config, update_config]. default(_Config) -> @@ -124,6 +126,34 @@ legacy_header(_Config) -> "=INFO REPORT==== "++_ = String5, ok. +error_logger_notice_header(_Config) -> + Meta1 = #{error_logger=>#{tag => info_report,type => std_info}}, + String1 = format(notice,{"~p",[term]},Meta1, + #{legacy_header=>true, + error_logger_notice_header=>notice}), + ct:log(String1), + "=NOTICE REPORT==== "++_ = String1, + + String2 = format(notice,{"~p",[term]},Meta1, + #{legacy_header=>true, + error_logger_notice_header=>info}), + ct:log(String2), + "=INFO REPORT==== "++_ = String2, + + String3 = format(notice,{"~p",[term]},#{}, + #{legacy_header=>true, + error_logger_notice_header=>notice}), + ct:log(String3), + "=NOTICE REPORT==== "++_ = String3, + + String4 = format(notice,{"~p",[term]},#{}, + #{legacy_header=>true, + error_logger_notice_header=>info}), + ct:log(String4), + "=NOTICE REPORT==== "++_ = String4, + + ok. + single_line(_Config) -> Time = timestamp(), ExpectedTimestamp = default_time_format(Time), @@ -158,7 +188,7 @@ template(_Config) -> Template4 = ["string\nnewline"], String4 = format(info,{"~p",[term]},#{time=>Time},#{template=>Template4, - single_line=>true}), + single_line=>true}), ct:log(String4), "string\nnewline" = String4, @@ -179,7 +209,7 @@ template(_Config) -> tuple=>{1,atom,"list"}, nested=>#{subkey=>subvalue}}, Template6 = lists:join(";",maps:keys(maps:remove(nested,Meta6)) ++ - [{nested,subkey}]), + [[nested,subkey]]), String6 = format(info,{"~p",[term]},Meta6,#{template=>Template6, single_line=>true}), ct:log(String6), @@ -202,16 +232,16 @@ template(_Config) -> nested=>#{key1=>#{subkey1=>value1}, key2=>value2}}, Template7 = lists:join(";",[nested, - {nested,key1}, - {nested,key1,subkey1}, - {nested,key2}, - {nested,key2,subkey2}, - {nested,key3}, - {nested,key3,subkey3}]), + [nested,key1], + [nested,key1,subkey1], + [nested,key2], + [nested,key2,subkey2], + [nested,key3], + [nested,key3,subkey3]]), String7 = format(info,{"~p",[term]},Meta7,#{template=>Template7, single_line=>true}), ct:log(String7), - [MultipleKeysStr, + [MultipleKeysStr7, "#{subkey1 => value1}", "value1", "value2", @@ -219,11 +249,42 @@ template(_Config) -> "", ""] = string:split(String7,";",all), %% Order of keys is not fixed - case MultipleKeysStr of + case MultipleKeysStr7 of "#{key2 => value2,key1 => #{subkey1 => value1}}" -> ok; "#{key1 => #{subkey1 => value1},key2 => value2}" -> ok; - _ -> ct:fail({full_nested_map_unexpected,MultipleKeysStr}) + _ -> ct:fail({full_nested_map_unexpected,MultipleKeysStr7}) + end, + + Meta8 = #{time=>Time, + nested=>#{key1=>#{subkey1=>value1}, + key2=>value2}}, + Template8 = + lists:join( + ";", + [{nested,["exist:",nested],["noexist"]}, + {[nested,key1],["exist:",[nested,key1]],["noexist"]}, + {[nested,key1,subkey1],["exist:",[nested,key1,subkey1]],["noexist"]}, + {[nested,key2],["exist:",[nested,key2]],["noexist"]}, + {[nested,key2,subkey2],["exist:",[nested,key2,subkey2]],["noexist"]}, + {[nested,key3],["exist:",[nested,key3]],["noexist"]}, + {[nested,key3,subkey3],["exist:",[nested,key3,subkey3]],["noexist"]}]), + String8 = format(info,{"~p",[term]},Meta8,#{template=>Template8, + single_line=>true}), + ct:log(String8), + [MultipleKeysStr8, + "exist:#{subkey1 => value1}", + "exist:value1", + "exist:value2", + "noexist", + "noexist", + "noexist"] = string:split(String8,";",all), + %% Order of keys is not fixed + case MultipleKeysStr8 of + "exist:#{key2 => value2,key1 => #{subkey1 => value1}}" -> ok; + "exist:#{key1 => #{subkey1 => value1},key2 => value2}" -> ok; + _ -> ct:fail({full_nested_map_unexpected,MultipleKeysStr8}) end, + ok. format_msg(_Config) -> @@ -541,23 +602,113 @@ faulty_msg(_Config) -> #{})), ok. +-define(cfgerr(X), {error,{invalid_formatter_config,logger_formatter,X}}). +check_config(_Config) -> + ok = logger_formatter:check_config(#{}), + ?cfgerr(bad) = logger_formatter:check_config(bad), + + C1 = #{chars_limit => 1, + depth => 1, + legacy_header => true, + error_logger_notice_header => info, + max_size => 1, + report_cb => fun(R) -> {"~p",[R]} end, + single_line => false, + template => [], + time_designator => $T, + time_offset => 0}, + ok = logger_formatter:check_config(C1), + + ok = logger_formatter:check_config(#{chars_limit => unlimited}), + ?cfgerr({chars_limit,bad}) = + logger_formatter:check_config(#{chars_limit => bad}), + + ok = logger_formatter:check_config(#{depth => unlimited}), + ?cfgerr({depth,bad}) = + logger_formatter:check_config(#{depth => bad}), + + ok = logger_formatter:check_config(#{legacy_header => false}), + ?cfgerr({legacy_header,bad}) = + logger_formatter:check_config(#{legacy_header => bad}), + + ok = logger_formatter:check_config(#{error_logger_notice_header => notice}), + ?cfgerr({error_logger_notice_header,bad}) = + logger_formatter:check_config(#{error_logger_notice_header => bad}), + + ok = logger_formatter:check_config(#{max_size => unlimited}), + ?cfgerr({max_size,bad}) = + logger_formatter:check_config(#{max_size => bad}), + + ?cfgerr({report_cb,F}) = + logger_formatter:check_config(#{report_cb => F=fun(_,_) -> {"",[]} end}), + ?cfgerr({report_cb,bad}) = + logger_formatter:check_config(#{report_cb => bad}), + + ok = logger_formatter:check_config(#{single_line => true}), + ?cfgerr({single_line,bad}) = + logger_formatter:check_config(#{single_line => bad}), + + Ts = [[key], + [[key1,key2]], + [{key,[key],[]}], + [{[key1,key2],[[key1,key2]],["noexist"]}], + ["string"]], + [begin + ct:log("check template: ~p",[T]), + ok = logger_formatter:check_config(#{template => T}) + end + || T <- Ts], + + ETs = [bad, + [{key,bad}], + [{key,[key],bad}], + [{key,[key],"bad"}], + "bad", + [[key,$a,$b,$c]], + [[$a,$b,$c,key]]], + [begin + ct:log("check template: ~p",[T]), + {error,{invalid_formatter_template,logger_formatter,T}} = + logger_formatter:check_config(#{template => T}) + end + || T <- ETs], + + ?cfgerr({time_designator,bad}) = + logger_formatter:check_config(#{time_designator => bad}), + ?cfgerr({time_designator,"b"}) = + logger_formatter:check_config(#{time_designator => "b"}), + + ok = logger_formatter:check_config(#{time_offset => -1}), + ok = logger_formatter:check_config(#{time_offset => "+02:00"}), + ok = logger_formatter:check_config(#{time_offset => "-23:59"}), + ok = logger_formatter:check_config(#{time_offset => "+24:00"}), + ok = logger_formatter:check_config(#{time_offset => "-25:00"}), + ?cfgerr({time_offset,bad}) = + logger_formatter:check_config(#{time_offset => bad}), + ?cfgerr({time_offset,"02:00"}) = + logger_formatter:check_config(#{time_offset => "02:00"}), + ?cfgerr({time_offset,"+02"}) = + logger_formatter:check_config(#{time_offset => "+02"}), + + ok. + %% Test that formatter config can be changed, and that the default %% template is updated accordingly update_config(_Config) -> logger:add_handler_filter(default,silence,{fun(_,_) -> stop end,ok}), ok = logger:add_handler(?MODULE,?MODULE,#{}), D = lists:seq(1,1000), - logger:info("~p~n",[D]), + logger:notice("~p~n",[D]), {Lines1,C1} = check_log(), [ct:log(L) || L <- Lines1], ct:log("~p",[C1]), [Line1] = Lines1, - [_Time,"info: "++D1] = string:split(Line1," "), + [_Time,"notice: "++D1] = string:split(Line1," "), true = length(D1)>3000, true = #{}==C1, ok = logger:update_formatter_config(?MODULE,single_line,false), - logger:info("~p~n",[D]), + logger:notice("~p~n",[D]), {Lines2,C2} = check_log(), [ct:log(L) || L <- Lines2], ct:log("~p",[C2]), @@ -565,23 +716,37 @@ update_config(_Config) -> true = #{single_line=>false}==C2, ok = logger:update_formatter_config(?MODULE,#{legacy_header=>true}), - logger:info("~p~n",[D]), + logger:notice("~p~n",[D]), {Lines3,C3} = check_log(), [ct:log(L) || L <- Lines3], ct:log("~p",[C3]), - ["=INFO REPORT==== "++_|D3] = Lines3, + ["=NOTICE REPORT==== "++_|D3] = Lines3, true = length(D3)>50, true = #{legacy_header=>true,single_line=>false}==C3, ok = logger:update_formatter_config(?MODULE,single_line,true), - logger:info("~p~n",[D]), + logger:notice("~p~n",[D]), {Lines4,C4} = check_log(), [ct:log(L) || L <- Lines4], ct:log("~p",[C4]), - ["=INFO REPORT==== "++_,D4] = Lines4, + ["=NOTICE REPORT==== "++_,D4] = Lines4, true = length(D4)>3000, true = #{legacy_header=>true,single_line=>true}==C4, + %% Finally, check that error_logger_notice_header works, default=info + error_logger:info_msg("~p",[D]), + {Lines5,C5} = check_log(), + [ct:log(L) || L <- Lines5], + ct:log("~p",[C5]), + ["=INFO REPORT==== "++_,_D5] = Lines5, + + ok=logger:update_formatter_config(?MODULE,error_logger_notice_header,notice), + error_logger:info_msg("~p",[D]), + {Lines6,C6} = check_log(), + [ct:log(L) || L <- Lines6], + ct:log("~p",[C6]), + ["=NOTICE REPORT==== "++_,_D6] = Lines6, + ok. update_config(cleanup,_Config) -> diff --git a/lib/kernel/test/logger_legacy_SUITE.erl b/lib/kernel/test/logger_legacy_SUITE.erl index cfba35e43f..de73b6152a 100644 --- a/lib/kernel/test/logger_legacy_SUITE.erl +++ b/lib/kernel/test/logger_legacy_SUITE.erl @@ -67,25 +67,28 @@ end_per_suite(_Config) -> init_per_group(std, Config) -> ok = logger:set_handler_config( error_logger,filters, - [{domain,{fun logger_filters:domain/2, - {log,super,[beam,erlang,otp]}}}]), + [{domain,{fun logger_filters:domain/2,{log,super,[otp]}}}]), Config; init_per_group(sasl, Config) -> + %% Since default level is notice, and progress reports are info, + %% we need to raise the global logger level to info in order to + %% receive these. + ok = logger:set_primary_config(level,info), ok = logger:set_handler_config( error_logger,filters, - [{domain,{fun logger_filters:domain/2, - {log,super,[beam,erlang,otp,sasl]}}}]), + [{domain,{fun logger_filters:domain/2,{log,super,[otp,sasl]}}}]), %% cth_log_redirect checks if sasl is started before displaying %% any sasl reports - so just to see the real sasl reports in tc %% log: - application:start(sasl), - Config; + {ok,Apps} = application:ensure_all_started(sasl), + [{stop_apps,Apps}|Config]; init_per_group(_Group, Config) -> Config. -end_per_group(sasl, _Config) -> - application:stop(sasl), +end_per_group(sasl, Config) -> + Apps = ?config(stop_apps,Config), + [application:stop(App) || App <- Apps], ok; end_per_group(_Group, _Config) -> ok. diff --git a/lib/kernel/test/logger_simple_h_SUITE.erl b/lib/kernel/test/logger_simple_h_SUITE.erl index 271a2126de..e4e48b538a 100644 --- a/lib/kernel/test/logger_simple_h_SUITE.erl +++ b/lib/kernel/test/logger_simple_h_SUITE.erl @@ -48,7 +48,7 @@ suite() -> {ct_hooks, [logger_test_lib]}]. init_per_suite(Config) -> - #{handlers:=Hs0} = logger:i(), + Hs0 = logger:get_handler_config(), Hs = lists:keydelete(cth_log_redirect,1,Hs0), [ok = logger:remove_handler(Id) || {Id,_,_} <- Hs], Env = [{App,Key,application:get_env(App,Key)} || @@ -128,8 +128,8 @@ replace_file(Config) -> log(Node, emergency, [M1=?str]), log(Node, alert, [M2=?str,[]]), log(Node, error, [M3=?map_rep]), - log(Node, info, [M4=?keyval_rep]), - log(Node, info, [M41=?keyval_rep++[not_key_val]]), + log(Node, warning, [M4=?keyval_rep]), + log(Node, warning, [M41=?keyval_rep++[not_key_val]]), log(Node, critical, [M7=?str,[A7=?keyval_rep]]), log(Node, notice, [M8=["fake",string,"line:",?LINE]]), @@ -138,7 +138,7 @@ replace_file(Config) -> ok = rpc:call(Node, logger, add_handlers, [[{handler, default, logger_std_h, - #{ logger_std_h => #{ type => {file, File} }, + #{ config => #{ type => {file, File} }, formatter => {?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}}}]]), {ok,Bin} = sync_and_read(Node, file, File), @@ -151,10 +151,10 @@ replace_file(Config) -> "=ERROR REPORT===="++_, _, _, - "=INFO REPORT===="++_, + "=WARNING REPORT===="++_, _, _, - "=INFO REPORT===="++_, + "=WARNING REPORT===="++_, _, _, _, @@ -172,8 +172,8 @@ replace_disk_log(Config) -> log(Node, emergency, [M1=?str]), log(Node, alert, [M2=?str,[]]), log(Node, error, [M3=?map_rep]), - log(Node, info, [M4=?keyval_rep]), - log(Node, info, [M41=?keyval_rep++[not_key_val]]), + log(Node, warning, [M4=?keyval_rep]), + log(Node, warning, [M41=?keyval_rep++[not_key_val]]), log(Node, critical, [M7=?str,[A7=?keyval_rep]]), log(Node, notice, [M8=["fake",string,"line:",?LINE]]), @@ -182,7 +182,7 @@ replace_disk_log(Config) -> ok = rpc:call(Node, logger, add_handlers, [[{handler, default, logger_disk_log_h, - #{ disk_log_opts => #{ file => File }, + #{ config => #{ file => File }, formatter => {?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}}}]]), {ok,Bin} = sync_and_read(Node, disk_log, File), Lines = [unicode:characters_to_list(L) || @@ -194,10 +194,10 @@ replace_disk_log(Config) -> "=ERROR REPORT===="++_, _, _, - "=INFO REPORT===="++_, + "=WARNING REPORT===="++_, _, _, - "=INFO REPORT===="++_, + "=WARNING REPORT===="++_, _, _, _, diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl index 5764abd063..36b123b07d 100644 --- a/lib/kernel/test/logger_std_h_SUITE.erl +++ b/lib/kernel/test/logger_std_h_SUITE.erl @@ -55,7 +55,7 @@ suite() -> init_per_suite(Config) -> timer:start(), % to avoid progress report - {ok,{logger_std_h,#{formatter:=OrigFormatter}}} = + {ok,#{formatter:=OrigFormatter}} = logger:get_handler_config(?STANDARD_HANDLER), [{formatter,OrigFormatter}|Config]. @@ -108,7 +108,7 @@ all() -> info_and_reset, reconfig, file_opts, - filesync, + sync, write_failure, sync_failure, op_switch_to_sync_file, @@ -132,7 +132,7 @@ all() -> add_remove_instance_tty(_Config) -> {error,{handler_not_added,{invalid_config,logger_std_h,{type,tty}}}} = logger:add_handler(?MODULE,logger_std_h, - #{logger_std_h => #{type => tty}, + #{config => #{type => tty}, filter_default=>log, formatter=>{?MODULE,self()}}), ok. @@ -166,20 +166,20 @@ add_remove_instance_file2(cleanup,_Config) -> add_remove_instance_file(Log, Type) -> ok = logger:add_handler(?MODULE, logger_std_h, - #{logger_std_h => #{type => Type}, + #{config => #{type => Type}, filter_default=>stop, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}}), - Pid = whereis(?MODULE), + Pid = whereis(h_proc_name()), true = is_pid(Pid), - logger:info(M1=?msg,?domain), + logger:notice(M1=?msg,?domain), ?check(M1), B1 = ?bin(M1), try_read_file(Log, {ok,B1}, ?FILESYNC_REP_INT), ok = logger:remove_handler(?MODULE), timer:sleep(500), - undefined = whereis(?MODULE), - logger:info(?msg,?domain), + undefined = whereis(h_proc_name()), + logger:notice(?msg,?domain), ?check_no_log, try_read_file(Log, {ok,B1}, ?FILESYNC_REP_INT), ok. @@ -188,11 +188,11 @@ default_formatter(_Config) -> ok = logger:set_handler_config(?STANDARD_HANDLER,formatter, {?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}), ct:capture_start(), - logger:info(M1=?msg), + logger:notice(M1=?msg), timer:sleep(100), ct:capture_stop(), [Msg] = ct:capture_get(), - match = re:run(Msg,"=INFO REPORT====.*\n"++M1,[{capture,none}]), + match = re:run(Msg,"=NOTICE REPORT====.*\n"++M1,[{capture,none}]), ok. errors(Config) -> @@ -212,20 +212,20 @@ errors(Config) -> {handler_not_added, {invalid_config,logger_std_h,{type,faulty_type}}}} = logger:add_handler(?MODULE,logger_std_h, - #{logger_std_h => #{type => faulty_type}}), + #{config => #{type => faulty_type}}), NoDir = lists:concat(["/",?MODULE,"_dir"]), {error, {handler_not_added,{{open_failed,NoDir,eacces},_}}} = logger:add_handler(myh2,logger_std_h, - #{logger_std_h=>#{type=>{file,NoDir}}}), + #{config=>#{type=>{file,NoDir}}}), {error, {handler_not_added,{{open_failed,Log,_},_}}} = logger:add_handler(myh3,logger_std_h, - #{logger_std_h=>#{type=>{file,Log,[bad_file_opt]}}}), + #{config=>#{type=>{file,Log,[bad_file_opt]}}}), - ok = logger:info(?msg). + ok = logger:notice(?msg). errors(cleanup,_Config) -> logger:remove_handler(?MODULE). @@ -237,43 +237,40 @@ formatter_fail(Config) -> %% no formatter ok = logger:add_handler(?MODULE, logger_std_h, - #{logger_std_h => #{type => {file,Log}}, + #{config => #{type => {file,Log}}, filter_default=>stop, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE])}), - Pid = whereis(?MODULE), + Pid = whereis(h_proc_name()), true = is_pid(Pid), - #{handlers:=HC1} = logger:i(), - H = [Id || {Id,_,_} <- HC1], + H = logger:get_handler_ids(), true = lists:member(?MODULE,H), %% Formatter is added automatically - {ok,{_,#{formatter:={logger_formatter,_}}}} = - logger:get_handler_config(?MODULE), - logger:info(M1=?msg,?domain), - Got1 = try_match_file(Log,"[0-9\\+\\-T:\\.]* info: "++M1,5000), + {ok,#{formatter:={logger_formatter,_}}} = logger:get_handler_config(?MODULE), + logger:notice(M1=?msg,?domain), + Got1 = try_match_file(Log,"[0-9\\+\\-T:\\.]* notice: "++M1,5000), ok = logger:set_handler_config(?MODULE,formatter,{nonexistingmodule,#{}}), - logger:info(M2=?msg,?domain), + logger:notice(M2=?msg,?domain), Got2 = try_match_file(Log, - escape(Got1)++"[0-9\\+\\-T:\\.]* info: FORMATTER CRASH: .*"++M2, + escape(Got1)++"[0-9\\+\\-T:\\.]* notice: FORMATTER CRASH: .*"++M2, 5000), ok = logger:set_handler_config(?MODULE,formatter,{?MODULE,crash}), - logger:info(M3=?msg,?domain), + logger:notice(M3=?msg,?domain), Got3 = try_match_file(Log, - escape(Got2)++"[0-9\\+\\-T:\\.]* info: FORMATTER CRASH: .*"++M3, + escape(Got2)++"[0-9\\+\\-T:\\.]* notice: FORMATTER CRASH: .*"++M3, 5000), ok = logger:set_handler_config(?MODULE,formatter,{?MODULE,bad_return}), - logger:info(?msg,?domain), + logger:notice(?msg,?domain), try_match_file(Log, escape(Got3)++"FORMATTER ERROR: bad_return_value", 5000), %% Check that handler is still alive and was never dead - Pid = whereis(?MODULE), - #{handlers:=HC2} = logger:i(), - H = [Id || {Id,_,_} <- HC2], + Pid = whereis(h_proc_name()), + H = logger:get_handler_ids(), ok. @@ -283,41 +280,41 @@ formatter_fail(cleanup,_Config) -> config_fail(_Config) -> {error,{handler_not_added,{invalid_config,logger_std_h,{bad,bad}}}} = logger:add_handler(?MODULE,logger_std_h, - #{logger_std_h => #{bad => bad}, + #{config => #{bad => bad}, filter_default=>log, formatter=>{?MODULE,self()}}), {error,{handler_not_added,{invalid_config,logger_std_h, {restart_type,bad}}}} = logger:add_handler(?MODULE,logger_std_h, - #{logger_std_h => #{restart_type => bad}, + #{config => #{restart_type => bad}, filter_default=>log, formatter=>{?MODULE,self()}}), {error,{handler_not_added,{invalid_levels,{_,1,_}}}} = logger:add_handler(?MODULE,logger_std_h, - #{logger_std_h => #{drop_new_reqs_qlen=>1}}), + #{config => #{drop_mode_qlen=>1}}), {error,{handler_not_added,{invalid_levels,{43,42,_}}}} = logger:add_handler(?MODULE,logger_std_h, - #{logger_std_h => #{toggle_sync_qlen=>43, - drop_new_reqs_qlen=>42}}), + #{config => #{sync_mode_qlen=>43, + drop_mode_qlen=>42}}), {error,{handler_not_added,{invalid_levels,{_,43,42}}}} = logger:add_handler(?MODULE,logger_std_h, - #{logger_std_h => #{drop_new_reqs_qlen=>43, - flush_reqs_qlen=>42}}), + #{config => #{drop_mode_qlen=>43, + flush_qlen=>42}}), ok = logger:add_handler(?MODULE,logger_std_h, #{filter_default=>log, formatter=>{?MODULE,self()}}), {error,{illegal_config_change,_,_}} = - logger:set_handler_config(?MODULE,logger_std_h, + logger:set_handler_config(?MODULE,config, #{type=>{file,"file"}}), {error,{illegal_config_change,_,_}} = logger:set_handler_config(?MODULE,id,bad), {error,{invalid_levels,_}} = - logger:set_handler_config(?MODULE,logger_std_h, - #{toggle_sync_qlen=>100, - flush_reqs_qlen=>99}), + logger:set_handler_config(?MODULE,config, + #{sync_mode_qlen=>100, + flush_qlen=>99}), {error,{invalid_config,logger_std_h,{filesync_rep_int,2000}}} = - logger:set_handler_config(?MODULE, logger_std_h, + logger:set_handler_config(?MODULE, config, #{filesync_rep_int => 2000}), ok. @@ -329,7 +326,7 @@ crash_std_h_to_file(Config) -> Log = filename:join(Dir,lists:concat([?MODULE,"_",?FUNCTION_NAME,".log"])), crash_std_h(Config,?FUNCTION_NAME, [{handler,default,logger_std_h, - #{ logger_std_h => #{ type => {file, Log} }}}], + #{ config => #{ type => {file, Log} }}}], file, Log). crash_std_h_to_file(cleanup,_Config) -> crash_std_h(cleanup). @@ -339,7 +336,7 @@ crash_std_h_to_disk_log(Config) -> Log = filename:join(Dir,lists:concat([?MODULE,"_",?FUNCTION_NAME,".log"])), crash_std_h(Config,?FUNCTION_NAME, [{handler,default,logger_disk_log_h, - #{ disk_log_opts => #{ file => Log }}}], + #{ config => #{ file => Log }}}], disk_log,Log). crash_std_h_to_disk_log(cleanup,_Config) -> crash_std_h(cleanup). @@ -354,7 +351,12 @@ crash_std_h(Config,Func,Var,Type,Log) -> ct:pal("Starting ~p with ~tp", [Name,Args]), %% Start a node which prints kernel logs to the destination specified by Type {ok,Node} = test_server:start_node(Name, peer, [{args, Args}]), - Pid = rpc:call(Node,erlang,whereis,[?STANDARD_HANDLER]), + HProcName = + case Type of + file -> ?name_to_reg_name(logger_std_h,?STANDARD_HANDLER); + disk_log -> ?name_to_reg_name(logger_disk_log_h,?STANDARD_HANDLER) + end, + Pid = rpc:call(Node,erlang,whereis,[HProcName]), ok = rpc:call(Node,logger,set_handler_config,[?STANDARD_HANDLER,formatter, {?MODULE,self()}]), ok = log_on_remote_node(Node,"dummy1"), @@ -367,7 +369,7 @@ crash_std_h(Config,Func,Var,Type,Log) -> %% Wait a bit, then check that it is gone timer:sleep(2000), - undefined = rpc:call(Node,erlang,whereis,[?STANDARD_HANDLER]), + undefined = rpc:call(Node,erlang,whereis,[HProcName]), %% Check that file is not empty {ok,Bin2} = sync_and_read(Node,Type,Log), @@ -381,7 +383,7 @@ crash_std_h(Config,Func,Var,Type,Log) -> log_on_remote_node(Node,Msg) -> _ = spawn_link(Node, fun() -> erlang:group_leader(whereis(user),self()), - logger:info(Msg) + logger:notice(Msg) end), ok. @@ -391,7 +393,7 @@ crash_std_h(cleanup) -> [test_server:stop_node(Node) || Node <- Nodes]. sync_and_read(Node,disk_log,Log) -> - rpc:call(Node,logger_disk_log_h,disk_log_sync,[?STANDARD_HANDLER]), + rpc:call(Node,logger_disk_log_h,sync,[?STANDARD_HANDLER]), case file:read_file(Log ++ ".1") of {ok,<<>>} -> timer:sleep(5000), @@ -400,7 +402,7 @@ sync_and_read(Node,disk_log,Log) -> Ok end; sync_and_read(Node,file,Log) -> - rpc:call(Node,logger_std_h,filesync,[?STANDARD_HANDLER]), + rpc:call(Node,logger_std_h,sync,[?STANDARD_HANDLER]), case file:read_file(Log) of {ok,<<>>} -> timer:sleep(5000), @@ -410,7 +412,7 @@ sync_and_read(Node,file,Log) -> end. bad_input(_Config) -> - {error,{badarg,{filesync,["BadType"]}}} = logger_std_h:filesync("BadType"), + {error,{badarg,{sync,["BadType"]}}} = logger_std_h:sync("BadType"), {error,{badarg,{info,["BadType"]}}} = logger_std_h:info("BadType"), {error,{badarg,{reset,["BadType"]}}} = logger_std_h:reset("BadType"). @@ -423,51 +425,51 @@ reconfig(Config) -> Dir = ?config(priv_dir,Config), ok = logger:add_handler(?MODULE, logger_std_h, - #{logger_std_h => #{type => standard_io}, + #{config => #{type => standard_io}, filter_default=>log, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}}), #{id := ?MODULE, type := standard_io, file_ctrl_pid := FileCtrlPid, - toggle_sync_qlen := ?TOGGLE_SYNC_QLEN, - drop_new_reqs_qlen := ?DROP_NEW_REQS_QLEN, - flush_reqs_qlen := ?FLUSH_REQS_QLEN, - enable_burst_limit := ?ENABLE_BURST_LIMIT, - burst_limit_size := ?BURST_LIMIT_SIZE, - burst_window_time := ?BURST_WINDOW_TIME, - enable_kill_overloaded := ?ENABLE_KILL_OVERLOADED, - handler_overloaded_qlen := ?HANDLER_OVERLOADED_QLEN, - handler_overloaded_mem := ?HANDLER_OVERLOADED_MEM, - handler_restart_after := ?HANDLER_RESTART_AFTER, + sync_mode_qlen := ?SYNC_MODE_QLEN, + drop_mode_qlen := ?DROP_MODE_QLEN, + flush_qlen := ?FLUSH_QLEN, + burst_limit_enable := ?BURST_LIMIT_ENABLE, + burst_limit_max_count := ?BURST_LIMIT_MAX_COUNT, + burst_limit_window_time := ?BURST_LIMIT_WINDOW_TIME, + overload_kill_enable := ?OVERLOAD_KILL_ENABLE, + overload_kill_qlen := ?OVERLOAD_KILL_QLEN, + overload_kill_mem_size := ?OVERLOAD_KILL_MEM_SIZE, + overload_kill_restart_after := ?OVERLOAD_KILL_RESTART_AFTER, filesync_repeat_interval := ?FILESYNC_REPEAT_INTERVAL} = logger_std_h:info(?MODULE), - ok = logger:set_handler_config(?MODULE, logger_std_h, - #{toggle_sync_qlen => 1, - drop_new_reqs_qlen => 2, - flush_reqs_qlen => 3, - enable_burst_limit => false, - burst_limit_size => 10, - burst_window_time => 10, - enable_kill_overloaded => true, - handler_overloaded_qlen => 100000, - handler_overloaded_mem => 10000000, - handler_restart_after => never, + ok = logger:set_handler_config(?MODULE, config, + #{sync_mode_qlen => 1, + drop_mode_qlen => 2, + flush_qlen => 3, + burst_limit_enable => false, + burst_limit_max_count => 10, + burst_limit_window_time => 10, + overload_kill_enable => true, + overload_kill_qlen => 100000, + overload_kill_mem_size => 10000000, + overload_kill_restart_after => never, filesync_repeat_interval => no_repeat}), #{id := ?MODULE, type := standard_io, file_ctrl_pid := FileCtrlPid, - toggle_sync_qlen := 1, - drop_new_reqs_qlen := 2, - flush_reqs_qlen := 3, - enable_burst_limit := false, - burst_limit_size := 10, - burst_window_time := 10, - enable_kill_overloaded := true, - handler_overloaded_qlen := 100000, - handler_overloaded_mem := 10000000, - handler_restart_after := never, + sync_mode_qlen := 1, + drop_mode_qlen := 2, + flush_qlen := 3, + burst_limit_enable := false, + burst_limit_max_count := 10, + burst_limit_window_time := 10, + overload_kill_enable := true, + overload_kill_qlen := 100000, + overload_kill_mem_size := 10000000, + overload_kill_restart_after := never, filesync_repeat_interval := no_repeat} = logger_std_h:info(?MODULE), ok. @@ -482,19 +484,19 @@ file_opts(Config) -> BadType = {file,Log,BadFileOpts}, {error,{handler_not_added,{{open_failed,Log,enoent},_}}} = logger:add_handler(?MODULE, logger_std_h, - #{logger_std_h => #{type => BadType}}), + #{config => #{type => BadType}}), OkFileOpts = [raw,append], OkType = {file,Log,OkFileOpts}, ok = logger:add_handler(?MODULE, logger_std_h, - #{logger_std_h => #{type => OkType}, + #{config => #{type => OkType}, filter_default=>log, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}}), #{type := OkType} = logger_std_h:info(?MODULE), - logger:info(M1=?msg,?domain), + logger:notice(M1=?msg,?domain), ?check(M1), B1 = ?bin(M1), try_read_file(Log, {ok,B1}, ?FILESYNC_REP_INT), @@ -503,13 +505,13 @@ file_opts(cleanup, _Config) -> logger:remove_handler(?MODULE). -filesync(Config) -> +sync(Config) -> Dir = ?config(priv_dir,Config), Log = filename:join(Dir, lists:concat([?FUNCTION_NAME,".log"])), Type = {file,Log}, ok = logger:add_handler(?MODULE, logger_std_h, - #{logger_std_h => #{type => Type}, + #{config => #{type => Type}, filter_default=>log, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,nl}}), @@ -522,7 +524,7 @@ filesync(Config) -> {logger_std_h, sync_dev}, {file,datasync}]), - logger:info("first", ?domain), + logger:notice("first", ?domain), %% wait for automatic filesync check_tracer(?FILESYNC_REP_INT*2), @@ -535,16 +537,16 @@ filesync(Config) -> {file,datasync}, {no_more,500} ]), - logger:info("second", ?domain), - %% do explicit filesync - logger_std_h:filesync(?MODULE), - %% a second filesync should be ignored - logger_std_h:filesync(?MODULE), + logger:notice("second", ?domain), + %% do explicit sync + logger_std_h:sync(?MODULE), + %% a second sync should be ignored + logger_std_h:sync(?MODULE), check_tracer(100), %% check that if there's no repeated filesync active, %% a filesync is still performed when handler goes idle - logger:set_handler_config(?MODULE, logger_std_h, + logger:set_handler_config(?MODULE, config, #{filesync_repeat_interval => no_repeat}), no_repeat = maps:get(filesync_repeat_interval, logger_std_h:info(?MODULE)), %% The following timer is to make sure the time from last log @@ -560,10 +562,10 @@ filesync(Config) -> {logger_std_h, write_to_dev, <<"fourth\n">>}, {logger_std_h, sync_dev}, {file,datasync}]), - logger:info("third", ?domain), + logger:notice("third", ?domain), %% wait for automatic filesync timer:sleep(?IDLE_DETECT_TIME_MSEC*2), - logger:info("fourth", ?domain), + logger:notice("fourth", ?domain), %% wait for automatic filesync check_tracer(?IDLE_DETECT_TIME_MSEC*2), @@ -575,15 +577,15 @@ filesync(Config) -> start_tracer([{logger_std_h,handle_cast,2}], [OneSync || _ <- lists:seq(1, 1 + trunc(WaitT/SyncInt))]), - logger:set_handler_config(?MODULE, logger_std_h, + logger:set_handler_config(?MODULE, config, #{filesync_repeat_interval => SyncInt}), SyncInt = maps:get(filesync_repeat_interval, logger_std_h:info(?MODULE)), timer:sleep(WaitT), - logger:set_handler_config(?MODULE, logger_std_h, + logger:set_handler_config(?MODULE, config, #{filesync_repeat_interval => no_repeat}), check_tracer(100), ok. -filesync(cleanup, _Config) -> +sync(cleanup, _Config) -> dbg:stop_clear(), logger:remove_handler(?MODULE). @@ -598,7 +600,7 @@ write_failure(Config) -> rpc:call(Node, ?MODULE, set_result, [file_write,ok]), ok = log_on_remote_node(Node, "Logged1"), - rpc:call(Node, logger_std_h, filesync, [?STANDARD_HANDLER]), + rpc:call(Node, logger_std_h, sync, [?STANDARD_HANDLER]), ?check_no_log, try_read_file(Log, {ok,<<"Logged1\n">>}, ?FILESYNC_REP_INT), @@ -616,7 +618,7 @@ write_failure(Config) -> rpc:call(Node, ?MODULE, set_result, [file_write,ok]), ok = log_on_remote_node(Node, "Logged2"), - rpc:call(Node, logger_std_h, filesync, [?STANDARD_HANDLER]), + rpc:call(Node, logger_std_h, sync, [?STANDARD_HANDLER]), ?check_no_log, try_read_file(Log, {ok,<<"Logged1\nLogged2\n">>}, ?FILESYNC_REP_INT), ok. @@ -636,7 +638,7 @@ sync_failure(Config) -> SyncInt = 500, ok = rpc:call(Node, logger, set_handler_config, - [?STANDARD_HANDLER, logger_std_h, + [?STANDARD_HANDLER, config, #{filesync_repeat_interval => SyncInt}]), Info = rpc:call(Node, logger_std_h, info, [?STANDARD_HANDLER]), SyncInt = maps:get(filesync_repeat_interval, Info), @@ -647,14 +649,14 @@ sync_failure(Config) -> rpc:call(Node, ?MODULE, set_result, [file_datasync,{error,terminated}]), ok = log_on_remote_node(Node, "Cause simple error printout"), - ?check({error,{?STANDARD_HANDLER,filesync,Log,{error,terminated}}}), + ?check({error,{?STANDARD_HANDLER,sync,Log,{error,terminated}}}), ok = log_on_remote_node(Node, "No second error printout"), ?check_no_log, rpc:call(Node, ?MODULE, set_result, [file_datasync,{error,eacces}]), ok = log_on_remote_node(Node, "Cause simple error printout"), - ?check({error,{?STANDARD_HANDLER,filesync,Log,{error,eacces}}}), + ?check({error,{?STANDARD_HANDLER,sync,Log,{error,eacces}}}), rpc:call(Node, ?MODULE, set_result, [file_datasync,ok]), ok = log_on_remote_node(Node, "Logged2"), @@ -669,7 +671,7 @@ start_std_h_on_new_node(Config, Log) -> logger_test_lib:setup( Config, [{logger,[{handler,default,logger_std_h, - #{ logger_std_h => #{ type => {file,Log}}}}]}]), + #{ config => #{ type => {file,Log}}}}]}]), ok = rpc:call(Node,logger,set_handler_config,[?STANDARD_HANDLER,formatter, {?MODULE,nl}]), Node. @@ -697,15 +699,15 @@ op_switch_to_sync_file(Config) -> {Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NumOfReqs = 500, NewHConfig = - HConfig#{logger_std_h => StdHConfig#{toggle_sync_qlen => 2, - drop_new_reqs_qlen => NumOfReqs+1, - flush_reqs_qlen => 2*NumOfReqs, - enable_burst_limit => false}}, + HConfig#{config => StdHConfig#{sync_mode_qlen => 2, + drop_mode_qlen => NumOfReqs+1, + flush_qlen => 2*NumOfReqs, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), %% TRecvPid = start_op_trace(), - send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Lines = count_lines(Log), - ok = file:delete(Log), + ok = file_delete(Log), %% true = analyse_trace(TRecvPid, %% fun(Events) -> find_mode(async,Events) end), %% true = analyse_trace(TRecvPid, @@ -726,12 +728,12 @@ op_switch_to_sync_tty(Config) -> {HConfig,StdHConfig} = start_handler(?MODULE, standard_io, Config), NumOfReqs = 500, NewHConfig = - HConfig#{logger_std_h => StdHConfig#{toggle_sync_qlen => 3, - drop_new_reqs_qlen => NumOfReqs+1, - flush_reqs_qlen => 2*NumOfReqs, - enable_burst_limit => false}}, + HConfig#{config => StdHConfig#{sync_mode_qlen => 3, + drop_mode_qlen => NumOfReqs+1, + flush_qlen => 2*NumOfReqs, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), - send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, seq, {chars,79}, notice), ok. op_switch_to_sync_tty(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -747,22 +749,22 @@ op_switch_to_drop_file(Config) -> Procs = 2, Bursts = 10, NewHConfig = - HConfig#{logger_std_h => - StdHConfig#{toggle_sync_qlen => 1, - drop_new_reqs_qlen => 2, - flush_reqs_qlen => + HConfig#{config => + StdHConfig#{sync_mode_qlen => 1, + drop_mode_qlen => 2, + flush_qlen => Procs*NumOfReqs*Bursts, - enable_burst_limit => false}}, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), %% It sometimes happens that the handler gets the %% requests in a slow enough pace so that dropping %% never occurs. Therefore, lets generate a number of %% bursts to increase the chance of message buildup. - [send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, info) || + [send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice) || _ <- lists:seq(1, Bursts)], Logged = count_lines(Log), ok = stop_handler(?MODULE), - _ = file:delete(Log), + _ = file_delete(Log), ct:pal("Number of messages dropped = ~w (~w)", [Procs*NumOfReqs*Bursts-Logged,Procs*NumOfReqs*Bursts]), true = (Logged < (Procs*NumOfReqs*Bursts)), @@ -785,19 +787,19 @@ op_switch_to_drop_tty(Config) -> NumOfReqs = 300, Procs = 2, NewHConfig = - HConfig#{logger_std_h => StdHConfig#{toggle_sync_qlen => 1, - drop_new_reqs_qlen => 2, - flush_reqs_qlen => - Procs*NumOfReqs+1, - enable_burst_limit => false}}, + HConfig#{config => StdHConfig#{sync_mode_qlen => 1, + drop_mode_qlen => 2, + flush_qlen => + Procs*NumOfReqs+1, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), - send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, info), + send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice), ok. op_switch_to_drop_tty(cleanup, _Config) -> ok = stop_handler(?MODULE). op_switch_to_flush_file() -> - [{timetrap,{minutes,3}}]. + [{timetrap,{minutes,5}}]. op_switch_to_flush_file(Config) -> Test = fun() -> @@ -809,12 +811,12 @@ op_switch_to_flush_file(Config) -> %% (verify with coverage of flush_log_requests/2) NewHConfig = - HConfig#{logger_std_h => - StdHConfig#{toggle_sync_qlen => 2, + HConfig#{config => + StdHConfig#{sync_mode_qlen => 2, %% disable drop mode - drop_new_reqs_qlen => 300, - flush_reqs_qlen => 300, - enable_burst_limit => false}}, + drop_mode_qlen => 300, + flush_qlen => 300, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), NumOfReqs = 1500, Procs = 10, @@ -826,11 +828,11 @@ op_switch_to_flush_file(Config) -> %% sync messages gets tested). Therefore, lets %% generate a number of bursts to increase the chance %% of message buildup in some random fashion. - [send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, info) || + [send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice) || _ <- lists:seq(1,Bursts)], Logged = count_lines(Log), ok = stop_handler(?MODULE), - _ = file:delete(Log), + _ = file_delete(Log), ct:pal("Number of messages flushed/dropped = ~w (~w)", [NumOfReqs*Procs*Bursts-Logged,NumOfReqs*Procs*Bursts]), true = (Logged < (NumOfReqs*Procs*Bursts)), @@ -848,6 +850,8 @@ op_switch_to_flush_file(Config) -> op_switch_to_flush_file(cleanup, _Config) -> _ = stop_handler(?MODULE). +op_switch_to_flush_tty() -> + [{timetrap,{minutes,5}}]. op_switch_to_flush_tty(Config) -> {HConfig,StdHConfig} = start_handler(?MODULE, standard_io, Config), @@ -855,15 +859,15 @@ op_switch_to_flush_tty(Config) -> %% when the flush happens (verify with coverage of flush_log_requests/2) NewHConfig = - HConfig#{logger_std_h => StdHConfig#{toggle_sync_qlen => 2, - %% disable drop mode - drop_new_reqs_qlen => 100, - flush_reqs_qlen => 100, - enable_burst_limit => false}}, + HConfig#{config => StdHConfig#{sync_mode_qlen => 2, + %% disable drop mode + drop_mode_qlen => 100, + flush_qlen => 100, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), NumOfReqs = 1000, Procs = 100, - send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, info), + send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice), ok. op_switch_to_flush_tty(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -871,17 +875,17 @@ op_switch_to_flush_tty(cleanup, _Config) -> limit_burst_disabled(Config) -> {Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NewHConfig = - HConfig#{logger_std_h => StdHConfig#{enable_burst_limit => false, - burst_limit_size => 10, - burst_window_time => 2000, - drop_new_reqs_qlen => 200, - flush_reqs_qlen => 300}}, + HConfig#{config => StdHConfig#{burst_limit_enable => false, + burst_limit_max_count => 10, + burst_limit_window_time => 2000, + drop_mode_qlen => 200, + flush_qlen => 300}}, ok = logger:set_handler_config(?MODULE, NewHConfig), NumOfReqs = 100, - send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages logged = ~w", [Logged]), - ok = file:delete(Log), + ok = file_delete(Log), NumOfReqs = Logged. limit_burst_disabled(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -890,17 +894,17 @@ limit_burst_enabled_one(Config) -> {Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), ReqLimit = 10, NewHConfig = - HConfig#{logger_std_h => StdHConfig#{enable_burst_limit => true, - burst_limit_size => ReqLimit, - burst_window_time => 2000, - drop_new_reqs_qlen => 200, - flush_reqs_qlen => 300}}, + HConfig#{config => StdHConfig#{burst_limit_enable => true, + burst_limit_max_count => ReqLimit, + burst_limit_window_time => 2000, + drop_mode_qlen => 200, + flush_qlen => 300}}, ok = logger:set_handler_config(?MODULE, NewHConfig), NumOfReqs = 100, - send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages logged = ~w", [Logged]), - ok = file:delete(Log), + ok = file_delete(Log), ReqLimit = Logged. limit_burst_enabled_one(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -910,19 +914,19 @@ limit_burst_enabled_period(Config) -> ReqLimit = 10, BurstTWin = 1000, NewHConfig = - HConfig#{logger_std_h => StdHConfig#{enable_burst_limit => true, - burst_limit_size => ReqLimit, - burst_window_time => BurstTWin, - drop_new_reqs_qlen => 20000, - flush_reqs_qlen => 20001}}, + HConfig#{config => StdHConfig#{burst_limit_enable => true, + burst_limit_max_count => ReqLimit, + burst_limit_window_time => BurstTWin, + drop_mode_qlen => 20000, + flush_qlen => 20001}}, ok = logger:set_handler_config(?MODULE, NewHConfig), Windows = 3, - Sent = send_burst({t,BurstTWin*Windows}, seq, {chars,79}, info), + Sent = send_burst({t,BurstTWin*Windows}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages sent = ~w~nNumber of messages logged = ~w", [Sent,Logged]), - ok = file:delete(Log), + ok = file_delete(Log), true = (Logged > (ReqLimit*Windows)) andalso (Logged < (ReqLimit*(Windows+2))). limit_burst_enabled_period(cleanup, _Config) -> @@ -931,36 +935,36 @@ limit_burst_enabled_period(cleanup, _Config) -> kill_disabled(Config) -> {Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NewHConfig = - HConfig#{logger_std_h=>StdHConfig#{enable_kill_overloaded=>false, - handler_overloaded_qlen=>10, - handler_overloaded_mem=>100}}, + HConfig#{config=>StdHConfig#{overload_kill_enable=>false, + overload_kill_qlen=>10, + overload_kill_mem_size=>100}}, ok = logger:set_handler_config(?MODULE, NewHConfig), NumOfReqs = 100, - send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages logged = ~w", [Logged]), - ok = file:delete(Log), - true = is_pid(whereis(?MODULE)), + ok = file_delete(Log), + true = is_pid(whereis(h_proc_name())), ok. kill_disabled(cleanup, _Config) -> ok = stop_handler(?MODULE). qlen_kill_new(Config) -> {_Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), - Pid0 = whereis(?MODULE), + Pid0 = whereis(h_proc_name()), {_,Mem0} = process_info(Pid0, memory), - RestartAfter = ?HANDLER_RESTART_AFTER, + RestartAfter = ?OVERLOAD_KILL_RESTART_AFTER, NewHConfig = - HConfig#{logger_std_h=>StdHConfig#{enable_kill_overloaded=>true, - handler_overloaded_qlen=>10, - handler_overloaded_mem=>Mem0+50000, - handler_restart_after=>RestartAfter}}, + HConfig#{config=>StdHConfig#{overload_kill_enable=>true, + overload_kill_qlen=>10, + overload_kill_mem_size=>Mem0+50000, + overload_kill_restart_after=>RestartAfter}}, ok = logger:set_handler_config(?MODULE, NewHConfig), MRef = erlang:monitor(process, Pid0), NumOfReqs = 100, Procs = 2, - send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, info), - %% send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice), + %% send_burst({n,NumOfReqs}, seq, {chars,79}, notice), receive {'DOWN', MRef, _, _, Info} -> case Info of @@ -970,7 +974,7 @@ qlen_kill_new(Config) -> ct:pal("Slow shutdown, handler process was killed!", []) end, timer:sleep(RestartAfter + 2000), - true = is_pid(whereis(?MODULE)), + true = is_pid(whereis(h_proc_name())), ok after 5000 -> @@ -990,28 +994,28 @@ qlen_kill_std(_Config) -> %% Log = filename:join(Dir, File), %% Node = start_std_h_on_new_node(Config, ?FUNCTION_NAME, Log), %% ok = rpc:call(Node, logger, set_handler_config, - %% [?STANDARD_HANDLER, logger_std_h, - %% #{enable_kill_overloaded=>true, - %% handler_overloaded_qlen=>10, - %% handler_overloaded_mem=>100000}]), + %% [?STANDARD_HANDLER, config, + %% #{overload_kill_enable=>true, + %% overload_kill_qlen=>10, + %% overload_kill_mem_size=>100000}]), {skip,"Not done yet"}. mem_kill_new(Config) -> {_Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), - Pid0 = whereis(?MODULE), + Pid0 = whereis(h_proc_name()), {_,Mem0} = process_info(Pid0, memory), - RestartAfter = ?HANDLER_RESTART_AFTER, + RestartAfter = ?OVERLOAD_KILL_RESTART_AFTER, NewHConfig = - HConfig#{logger_std_h=>StdHConfig#{enable_kill_overloaded=>true, - handler_overloaded_qlen=>50000, - handler_overloaded_mem=>Mem0+500, - handler_restart_after=>RestartAfter}}, + HConfig#{config=>StdHConfig#{overload_kill_enable=>true, + overload_kill_qlen=>50000, + overload_kill_mem_size=>Mem0+500, + overload_kill_restart_after=>RestartAfter}}, ok = logger:set_handler_config(?MODULE, NewHConfig), MRef = erlang:monitor(process, Pid0), NumOfReqs = 100, Procs = 2, - send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, info), - %% send_burst({n,NumOfReqs}, seq, {chars,79}, info), + send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice), + %% send_burst({n,NumOfReqs}, seq, {chars,79}, notice), receive {'DOWN', MRef, _, _, Info} -> case Info of @@ -1021,7 +1025,7 @@ mem_kill_new(Config) -> ct:pal("Slow shutdown, handler process was killed!", []) end, timer:sleep(RestartAfter * 3), - true = is_pid(whereis(?MODULE)), + true = is_pid(whereis(h_proc_name())), ok after 5000 -> @@ -1040,17 +1044,17 @@ mem_kill_std(_Config) -> restart_after(Config) -> {Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NewHConfig1 = - HConfig#{logger_std_h=>StdHConfig#{enable_kill_overloaded=>true, - handler_overloaded_qlen=>10, - handler_restart_after=>never}}, + HConfig#{config=>StdHConfig#{overload_kill_enable=>true, + overload_kill_qlen=>10, + overload_kill_restart_after=>never}}, ok = logger:set_handler_config(?MODULE, NewHConfig1), - MRef1 = erlang:monitor(process, whereis(?MODULE)), + MRef1 = erlang:monitor(process, whereis(h_proc_name())), %% kill handler - send_burst({n,100}, {spawn,2,0}, {chars,79}, info), + send_burst({n,100}, {spawn,2,0}, {chars,79}, notice), receive {'DOWN', MRef1, _, _, _Info1} -> - timer:sleep(?HANDLER_RESTART_AFTER + 1000), - undefined = whereis(?MODULE), + timer:sleep(?OVERLOAD_KILL_RESTART_AFTER + 1000), + undefined = whereis(h_proc_name()), ok after 5000 -> @@ -1058,20 +1062,20 @@ restart_after(Config) -> end, {Log,_,_} = start_handler(?MODULE, ?FUNCTION_NAME, Config), - RestartAfter = ?HANDLER_RESTART_AFTER, + RestartAfter = ?OVERLOAD_KILL_RESTART_AFTER, NewHConfig2 = - HConfig#{logger_std_h=>StdHConfig#{enable_kill_overloaded=>true, - handler_overloaded_qlen=>10, - handler_restart_after=>RestartAfter}}, + HConfig#{config=>StdHConfig#{overload_kill_enable=>true, + overload_kill_qlen=>10, + overload_kill_restart_after=>RestartAfter}}, ok = logger:set_handler_config(?MODULE, NewHConfig2), - Pid0 = whereis(?MODULE), + Pid0 = whereis(h_proc_name()), MRef2 = erlang:monitor(process, Pid0), %% kill handler - send_burst({n,100}, {spawn,2,0}, {chars,79}, info), + send_burst({n,100}, {spawn,2,0}, {chars,79}, notice), receive {'DOWN', MRef2, _, _, _Info2} -> timer:sleep(RestartAfter + 2000), - Pid1 = whereis(?MODULE), + Pid1 = whereis(h_proc_name()), true = is_pid(Pid1), false = (Pid1 == Pid0), ok @@ -1083,7 +1087,7 @@ restart_after(Config) -> restart_after(cleanup, _Config) -> ok = stop_handler(?MODULE). -%% send handler requests (filesync, info, reset, change_config) +%% send handler requests (sync, info, reset, change_config) %% during high load to verify that sync, dropping and flushing is %% handled correctly. handler_requests_under_load() -> @@ -1092,17 +1096,17 @@ handler_requests_under_load(Config) -> {Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NewHConfig = - HConfig#{logger_std_h => StdHConfig#{toggle_sync_qlen => 2, - drop_new_reqs_qlen => 1000, - flush_reqs_qlen => 2000, - enable_burst_limit => false}}, + HConfig#{config => StdHConfig#{sync_mode_qlen => 2, + drop_mode_qlen => 1000, + flush_qlen => 2000, + burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), - Pid = spawn_link(fun() -> send_requests(?MODULE, 1, [{filesync,[]}, + Pid = spawn_link(fun() -> send_requests(?MODULE, 1, [{sync,[]}, {info,[]}, {reset,[]}, {change_config,[]}]) end), - Sent = send_burst({t,10000}, seq, {chars,79}, info), + Sent = send_burst({t,10000}, seq, {chars,79}, notice), Pid ! {self(),finish}, ReqResult = receive {Pid,Result} -> Result end, Logged = count_lines(Log), @@ -1115,7 +1119,7 @@ handler_requests_under_load(Config) -> Errors = [{Req,FindError(Res)} || {Req,Res} <- ReqResult], NoOfReqs = lists:foldl(fun({_,Res}, N) -> N + length(Res) end, 0, ReqResult), ct:pal("~w requests made. Errors: ~n~p", [NoOfReqs,Errors]), - ok = file:delete(Log). + ok = file_delete(Log). handler_requests_under_load(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -1128,8 +1132,8 @@ send_requests(HName, TO, Reqs = [{Req,Res}|Rs]) -> Result = case Req of change_config -> - logger:set_handler_config(HName, logger_std_h, - #{enable_kill_overloaded => + logger:set_handler_config(HName, config, + #{overload_kill_enable => false}); Func -> logger_std_h:Func(HName) @@ -1144,12 +1148,11 @@ start_handler(Name, TTY, Config) when TTY == standard_io; TTY == standard_error-> ok = logger:add_handler(Name, logger_std_h, - #{logger_std_h => #{type => TTY}, + #{config => #{type => TTY}, filter_default=>log, filters=>?DEFAULT_HANDLER_FILTERS([Name]), formatter=>{?MODULE,op}}), - {ok,{_,HConfig = #{logger_std_h := StdHConfig}}} = - logger:get_handler_config(Name), + {ok,HConfig = #{config := StdHConfig}} = logger:get_handler_config(Name), {HConfig,StdHConfig}; start_handler(Name, FuncName, Config) -> @@ -1159,12 +1162,11 @@ start_handler(Name, FuncName, Config) -> Type = {file,Log}, ok = logger:add_handler(Name, logger_std_h, - #{logger_std_h => #{type => Type}, + #{config => #{type => Type}, filter_default=>log, filters=>?DEFAULT_HANDLER_FILTERS([Name]), formatter=>{?MODULE,op}}), - {ok,{_,HConfig = #{logger_std_h := StdHConfig}}} = - logger:get_handler_config(Name), + {ok,HConfig = #{config := StdHConfig}} = logger:get_handler_config(Name), {Log,HConfig,StdHConfig}. stop_handler(Name) -> @@ -1192,17 +1194,21 @@ wait_until_written(File, Sz) -> end. count_lines1(File) -> - Counter = fun Cnt(Dev,LC) -> - case file:read_line(Dev) of - eof -> LC; - _ -> Cnt(Dev,LC+1) - end - end, {_,Dev} = file:open(File, [read]), - Lines = Counter(Dev, 0), + Lines = count_lines2(Dev, 0), file:close(Dev), Lines. +count_lines2(Dev, LC) -> + case file:read_line(Dev) of + {ok,"Handler logger_std_h_SUITE " ++_} -> + %% Not counting handler info + count_lines2(Dev,LC); + {ok,_} -> + count_lines2(Dev,LC+1); + eof -> LC + end. + send_burst(NorT, Type, {chars,Sz}, Class) -> Text = [34 + rand:uniform(126-34) || _ <- lists:seq(1,Sz)], case NorT of @@ -1271,9 +1277,11 @@ format(#{msg:={report,#{label:={gen_server,terminate}}}},op) -> ""; format(#{msg:={report,#{label:={proc_lib,crash}}}},op) -> ""; -format(#{msg:={F,A}},Pid) when is_list(F), is_list(A) -> +format(#{msg:={F,A}},OpOrPid) when is_list(F), is_list(A) -> String = lists:flatten(io_lib:format(F,A)), - Pid ! {log,String}, + if is_pid(OpOrPid) -> OpOrPid ! {log,String}; + true -> ok + end, String++"\n"; format(#{msg:={string,String0}},Pid) -> String = unicode:characters_to_list(String0), @@ -1282,21 +1290,21 @@ format(#{msg:={string,String0}},Pid) -> add_remove_instance_nofile(Type) -> ok = logger:add_handler(?MODULE,logger_std_h, - #{logger_std_h => #{type => Type}, + #{config => #{type => Type}, filter_default=>stop, filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]), formatter=>{?MODULE,self()}}), - Pid = whereis(?MODULE), + Pid = whereis(h_proc_name()), true = is_pid(Pid), group_leader(group_leader(),Pid), % to get printouts in test log - logger:info(M1=?msg,?domain), + logger:notice(M1=?msg,?domain), ?check(M1), - %% check that filesync doesn't do damage even if not relevant - ok = logger_std_h:filesync(?MODULE), + %% check that sync doesn't do damage even if not relevant + ok = logger_std_h:sync(?MODULE), ok = logger:remove_handler(?MODULE), timer:sleep(500), - undefined = whereis(?MODULE), - logger:info(?msg,?domain), + undefined = whereis(h_proc_name()), + logger:notice(?msg,?domain), ?check_no_log, ok. @@ -1379,7 +1387,7 @@ start_op_trace() -> TRecvPid = spawn_link(fun() -> trace_receiver(5000) end), {ok,_} = dbg:tracer(process, {TraceFun, TRecvPid}), - {ok,_} = dbg:p(whereis(?MODULE), [c]), + {ok,_} = dbg:p(whereis(h_proc_name()), [c]), {ok,_} = dbg:p(self(), [c]), MS1 = dbg:fun2ms(fun([_]) -> return_trace() end), @@ -1459,7 +1467,7 @@ start_tracer(Trace,Expected) -> Pid = self(), FileCtrlPid = maps:get(file_ctrl_pid, logger_std_h:info(?MODULE)), dbg:tracer(process,{fun tracer/2,{Pid,Expected}}), - dbg:p(whereis(?MODULE),[c]), + dbg:p(whereis(h_proc_name()),[c]), dbg:p(FileCtrlPid,[c]), tpl(Trace), ok. @@ -1525,3 +1533,11 @@ escape([H|T]) -> [H|escape(T)]; escape([]) -> []. + +h_proc_name() -> + h_proc_name(?MODULE). +h_proc_name(Name) -> + ?name_to_reg_name(logger_std_h,Name). + +file_delete(Log) -> + file:delete(Log). diff --git a/lib/kernel/test/logger_test_lib.erl b/lib/kernel/test/logger_test_lib.erl index 4ac05e6480..9097453c10 100644 --- a/lib/kernel/test/logger_test_lib.erl +++ b/lib/kernel/test/logger_test_lib.erl @@ -37,7 +37,7 @@ setup(Config,Vars) -> " -boot start_sasl -kernel start_timer true " "-config ",ConfigFileName]}]) of {ok, Node} -> - L = rpc:call(Node, logger, i, []), + L = rpc:call(Node, logger, get_config, []), ct:log("~p",[L]), {ok, L, Node}; {error, Reason} -> @@ -52,10 +52,10 @@ log(Node, M, F, A) -> rpc:call(Node, M, F, A ++ [MD]). sync_and_read(Node,disk_log,Log) -> - rpc:call(Node,logger_disk_log_h,disk_log_sync,[?STANDARD_HANDLER]), + rpc:call(Node,logger_disk_log_h,sync,[?STANDARD_HANDLER]), file:read_file(Log ++ ".1"); sync_and_read(Node, file,Log) -> - ok = rpc:call(Node,logger_std_h,filesync,[?STANDARD_HANDLER]), + ok = rpc:call(Node,logger_std_h,sync,[?STANDARD_HANDLER]), file:read_file(Log). diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index aa8e4dc119..60a1b0bff8 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1 +1 @@ -KERNEL_VSN = 6.0 +KERNEL_VSN = 5.4.3 diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml index c78ba2e5c0..ba94e913f5 100644 --- a/lib/mnesia/doc/src/notes.xml +++ b/lib/mnesia/doc/src/notes.xml @@ -39,22 +39,7 @@ thus constitutes one section in this document. The title of each section is the version number of Mnesia.</p> - <section><title>Mnesia 4.15.4</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> Calls to <c>erlang:get_stacktrace()</c> are removed. - </p> - <p> - Own Id: OTP-14861</p> - </item> - </list> - </section> - -</section> - -<section><title>Mnesia 4.15.3</title> + <section><title>Mnesia 4.15.3</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk index aaa1c3006f..45f811846d 100644 --- a/lib/mnesia/vsn.mk +++ b/lib/mnesia/vsn.mk @@ -1 +1 @@ -MNESIA_VSN = 4.15.4 +MNESIA_VSN = 4.15.3 diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml index 5548b21fc5..c0b8309af6 100644 --- a/lib/observer/doc/src/notes.xml +++ b/lib/observer/doc/src/notes.xml @@ -32,35 +32,6 @@ <p>This document describes the changes made to the Observer application.</p> -<section><title>Observer 2.8</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Added possibility to garbage collect selected processes - and fixed a crash when the saved config file contained - bad data.</p> - <p> - Own Id: OTP-14993 Aux Id: PR-1666 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Use uri_string module instead of http_uri.</p> - <p> - Own Id: OTP-14902</p> - </item> - </list> - </section> - -</section> - <section><title>Observer 2.7</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk index bf6fd2a421..74a6db768e 100644 --- a/lib/observer/vsn.mk +++ b/lib/observer/vsn.mk @@ -1 +1 @@ -OBSERVER_VSN = 2.8 +OBSERVER_VSN = 2.7 diff --git a/lib/os_mon/doc/src/notes.xml b/lib/os_mon/doc/src/notes.xml index a08a6b7184..cec0856a8b 100644 --- a/lib/os_mon/doc/src/notes.xml +++ b/lib/os_mon/doc/src/notes.xml @@ -31,22 +31,6 @@ </header> <p>This document describes the changes made to the OS_Mon application.</p> -<section><title>Os_Mon 2.4.5</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Fix <c>disksup</c> to handle mount paths with spaces in - them.</p> - <p> - Own Id: OTP-14513</p> - </item> - </list> - </section> - -</section> - <section><title>Os_Mon 2.4.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/os_mon/vsn.mk b/lib/os_mon/vsn.mk index 4a327e5506..eb4f13ea9e 100644 --- a/lib/os_mon/vsn.mk +++ b/lib/os_mon/vsn.mk @@ -1 +1 @@ -OS_MON_VSN = 2.4.5 +OS_MON_VSN = 2.4.4 diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml index a925894ff2..b3370a06ab 100644 --- a/lib/parsetools/doc/src/notes.xml +++ b/lib/parsetools/doc/src/notes.xml @@ -31,21 +31,6 @@ </header> <p>This document describes the changes made to the Parsetools application.</p> -<section><title>Parsetools 2.1.7</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> Calls to <c>erlang:get_stacktrace()</c> are removed. - </p> - <p> - Own Id: OTP-14861</p> - </item> - </list> - </section> - -</section> - <section><title>Parsetools 2.1.6</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk index 210723e449..b6d2ce0cd4 100644 --- a/lib/parsetools/vsn.mk +++ b/lib/parsetools/vsn.mk @@ -1 +1 @@ -PARSETOOLS_VSN = 2.1.7 +PARSETOOLS_VSN = 2.1.6 diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml index df1c83d8f2..11012ee9e5 100644 --- a/lib/public_key/doc/src/notes.xml +++ b/lib/public_key/doc/src/notes.xml @@ -35,42 +35,6 @@ <file>notes.xml</file> </header> -<section><title>Public_Key 1.6</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Update calls to the base64 module to conform to that - module's type specifications.</p> - <p> - Own Id: OTP-14788 Aux Id: OTP-14624 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Use uri_string module instead of http_uri.</p> - <p> - Own Id: OTP-14902</p> - </item> - <item> - <p> - Compleate PKCS-8 encoding support and enhance the - decoding of 'PrivateKeyInfo' to conform to the rest of - Erlang public_key API.</p> - <p> - Own Id: OTP-15093</p> - </item> - </list> - </section> - -</section> - <section><title>Public_Key 1.5.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index 7284da0499..524869df16 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -969,27 +969,96 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, </type> <desc> <p>This function checks that the <i>Presented Identifier</i> (e.g hostname) in a peer certificate - is in agreement with the <i>Reference Identifier</i> that the client expects to be connected to. + is in agreement with at least one of the <i>Reference Identifier</i> that the client expects to be connected to. The function is intended to be added as an extra client check of the peer certificate when performing <seealso marker="public_key:public_key#pkix_path_validation-3">public_key:pkix_path_validation/3</seealso> </p> <p>See <url href="https://tools.ietf.org/html/rfc6125">RFC 6125</url> for detailed information about hostname verification. - The <seealso marker="using_public_key#verify_hostname">User's Manual</seealso> + The <seealso marker="using_public_key#verify_hostname">User's Guide</seealso> and <seealso marker="using_public_key#verify_hostname_examples">code examples</seealso> describes this function more detailed. </p> <p>The <c>{OtherRefId,term()}</c> is defined by the user and is passed to the <c>match_fun</c>, if defined. - If that term is a binary, it will be converted to a string. + If the term in <c>OtherRefId</c> is a binary, it will be converted to a string. </p> <p>The <c>ip</c> Reference ID takes an <seealso marker="inet:inet#type-ip_address">inet:ip_address()</seealso> or an ip address in string format (E.g "10.0.1.1" or "1234::5678:9012") as second element. </p> + <p>The options are:</p> + <taglist> + <tag><c>match_fun</c></tag> + <item> + The <c>fun/2</c> in this option replaces the default host name matching rules. The fun should return a + boolean to tell if the Reference ID and Presented ID matches or not. The fun can also return a third + value, the atom <c>default</c>, if the default matching rules shall apply. + This makes it possible to augment the tests with a special case: + <code> +fun(....) -> true; % My special case + (_, _) -> default % all others falls back to the inherit tests +end + </code> + <br/>See <seealso marker="#pkix_verify_hostname_match_fun-1">pkix_verify_hostname_match_fun/1</seealso> for a + function that takes a protocol name as argument and returns a <c>fun/2</c> suitable for this option and + <seealso marker="using_public_key#redefining_match_op">Re-defining the match operation</seealso> + in the User's Guide for an example. + </item> + + <tag><c>fail_callback</c></tag> + <item>If a matching fails, there could be circumstances when the certificate should be accepted anyway. Think for + example of a web browser where you choose to accept an outdated certificate. This option enables implementation + of such a function. This <c>fun/1</c> is called when no <c>ReferenceID</c> matches. The return value of the fun + (a <c>boolean()</c>) decides the outcome. If <c>true</c> the the certificate is accepted otherwise + it is rejected. See + <seealso marker="using_public_key#-pinning--a-certificate">"Pinning" a Certificate</seealso> + in the User's Guide. + </item> + + <tag><c>fqdn_fun</c></tag> + <item>This option augments the host name extraction from URIs and other Reference IDs. It could for example be + a very special URI that is not standardised. The fun takes a Reference ID as argument and returns one of: + <list> + <item>the hostname</item> + <item>the atom <c>default</c>: the default host name extract function will be used</item> + <item>the atom <c>undefined</c>: a host name could not be extracted. The pkix_verify_hostname/3 + will return <c>false</c>.</item> + </list> + <br/>For an example, see + <seealso marker="using_public_key#hostname_extraction">Hostname extraction</seealso> + in the User's Guide. + </item> + </taglist> + </desc> </func> <func> + <name>pkix_verify_hostname_match_fun(Protcol) -> fun(RefId | FQDN::string(), PresentedID) -> boolean() | default</name> + <fsummary>Returns a fun that is intendended as argument to the match_fun option in pkix_verify_hostname/3. + </fsummary> + <type> + <v>Protocol = https</v> + <d>The algorithm for wich the fun should implement the special matching rules</d> + <v>RefId</v> + <d>See <seealso marker="#pkix_verify_hostname-3">pkix_verify_hostname/3</seealso>.</d> + <v>FQDN</v> + <d>See <seealso marker="#pkix_verify_hostname-3">pkix_verify_hostname/3</seealso>.</d> + <v>PresentedID</v> + <d>See <seealso marker="#pkix_verify_hostname-3">pkix_verify_hostname/3</seealso>.</d> + </type> + <desc> + <p>The return value of calling this function is intended to be used in the <c>match_fun</c> option in + <seealso marker="#pkix_verify_hostname-3">pkix_verify_hostname/3</seealso>. + </p> + <p>The returned fun augments the verify hostname matching according to the specific rules for + the protocol in the argument. + </p> + </desc> + </func> + + + <func> <name>sign(Msg, DigestType, Key) -> binary()</name> <name>sign(Msg, DigestType, Key, Options) -> binary()</name> <fsummary>Creates a digital signature.</fsummary> diff --git a/lib/public_key/doc/src/using_public_key.xml b/lib/public_key/doc/src/using_public_key.xml index 417d479da3..b936b7fcb5 100644 --- a/lib/public_key/doc/src/using_public_key.xml +++ b/lib/public_key/doc/src/using_public_key.xml @@ -570,6 +570,7 @@ true = public_key:verify(Digest, none, Signature, PublicKey),</code> <c>fqdn_fun</c> and <c>match_fun</c>. </p> <section> + <marker id="hostname_extraction"></marker> <title>Hostname extraction</title> <p>The <c>fqdn_fun</c> extracts hostnames (Fully Qualified Domain Names) from uri_id or other ReferenceIDs that are not pre-defined in the public_key function. @@ -595,7 +596,8 @@ true = public_key:verify(Digest, none, Signature, PublicKey),</code> </code> </section> <section> - <title>Re-defining the match operations</title> + <marker id="redefining_match_op"></marker> + <title>Re-defining the match operation</title> <p>The default matching handles dns_id and uri_id. In an uri_id the value is tested for equality with a value from the <c>Subject Alternate Name</c>. If som other kind of matching is needed, use the <c>match_fun</c> option. diff --git a/lib/public_key/priv/moduli b/lib/public_key/priv/moduli index 446f4b8bf4..0c44d525ba 100644 --- a/lib/public_key/priv/moduli +++ b/lib/public_key/priv/moduli @@ -1,193 +1,306 @@ -20151021104105 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D182EB7 -20151021104106 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D27F94F -20151021104107 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D398EB7 -20151021104108 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D4B850F -20151021104108 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D4BF35B -20151021104108 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D5031DF -20151021104109 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D5A4933 -20151021104110 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D6434BF -20151021104111 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D70676B -20151021104111 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D7235E3 -20151021104113 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D963493 -20151021104114 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DAABAA7 -20151021104115 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DC2E333 -20151021104116 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DE16A7B -20151021104117 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DE2C5D3 -20151021104118 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DFF382F -20151021104119 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E158F13 -20151021104122 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E4D9FEB -20151021104123 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E5C1FDB -20151021104126 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E9BB69B -20151021104126 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E9F62D3 -20151021104127 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EAA1C27 -20151021104128 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EBC3313 -20151021104129 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EC0733B -20151021104130 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EDB7AD3 -20151021104132 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EF56457 -20151021104132 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EF5A9CF -20151021104133 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9F13CBB3 -20151021104218 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BAAFFDF -20151021104222 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BCB6D93 -20151021104225 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BE660BB -20151021104226 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BE676C3 -20151021104229 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BF3E23B -20151021104230 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BF95757 -20151021104241 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C59BEA7 -20151021104242 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C6231B3 -20151021104244 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C6879BF -20151021104250 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C9B678F -20151021104252 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CA66A4B -20151021104253 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CAB5543 -20151021104256 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CB96933 -20151021104300 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CDA8493 -20151021104308 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D18C0C7 -20151021104310 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D1DA5BF -20151021104318 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D4AB15F -20151021104325 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D7DE42F -20151021104329 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17DA03D3B -20151021104335 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17DD88BFF -20151021104338 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17DE82B5F -20151021104342 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E07AF43 -20151021104343 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E091E6F -20151021104346 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E28B90F -20151021104347 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E2A24F3 -20151021104401 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17EB074A7 -20151021104403 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17EC01B0F -20151021104406 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17ED2186F -20151021104407 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17ED55AAB -20151021104411 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17EF58773 -20151021104414 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17F0B3267 -20151021104423 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17F4DF61B -20151021104434 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17F9BBB0B -20151021104442 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17FDD6AFB -20151021104350 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE5E381EF -20151021104414 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE641C193 -20151021104422 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE659F523 -20151021104427 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE660E217 -20151021104438 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE6842F73 -20151021104441 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE689683B -20151021104455 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE6C41E3B -20151021104512 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE71E3BFF -20151021104525 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE75C804F -20151021104527 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE75DC48B -20151021104535 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE7738983 -20151021104543 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE787027B -20151021104610 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8075A1B -20151021104625 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE84F79B3 -20151021104628 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE859F617 -20151021104641 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8948E2F -20151021104646 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8A571B3 -20151021104659 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8CEA637 -20151021104705 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8E590FF -20151021104707 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8E7943F -20151021104731 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE95A975F -20151021104741 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE985F923 -20151021104745 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE996E20B -20151021104806 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE9FACFD7 -20151021104827 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEA562C43 -20151021104839 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEA8F25E3 -20151021104939 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEBB1DA0B -20151021104941 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEBB86153 -20151021105002 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEC1B8883 -20151021105019 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEC71316F -20151021105035 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BECB1D113 -20151021105042 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BECC3F3AB -20151021105045 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BECCC109B -20151021105101 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED16353B -20151021105106 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED24854F -20151021105109 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED2AE4B3 -20151021105116 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED472CF7 -20151021104612 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E360CD0C3 -20151021104628 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3620FBE7 -20151021104701 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E36490F57 -20151021105014 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E377ACADB -20151021105125 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E37E6DE07 -20151021105320 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E38C2387F -20151021105649 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3A61E46B -20151021105815 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3B0A6A4B -20151021105848 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3B47D2C3 -20151021105948 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3BBBB953 -20151021110011 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3BE3B83B -20151021110036 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3C0A3F1B -20151021110201 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3CB1970F -20151021110208 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3CB70C2B -20151021110235 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3CE4E4DF -20151021110424 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3DB68CD7 -20151021110525 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3E290717 -20151021110655 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3ED6DA83 -20151021110731 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3F14C563 -20151021110831 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3F85477F -20151021111418 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E420DE56B -20151021111430 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E421DBA2F -20151021111624 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E42F39A93 -20151021111916 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E44302363 -20151021112222 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E4585795F -20151021112245 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E45A1DAFF -20151021112339 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E4601674F -20151021112437 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E46691977 -20151021112521 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E46AF3AD3 -20151021112532 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E46BCAE97 -20151021112708 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E476520D3 -20151021112724 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E477B3317 -20151021105143 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BA7321EB -20151021105537 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BB3AF34B -20151021105816 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BBC51883 -20151021110444 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BD1A86C7 -20151021111341 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BEDB7BBB -20151021111438 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BF0297AB -20151021111935 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BFF381FF -20151021113820 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C433A1BF -20151021113833 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C43B426B -20151021113900 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C45007D3 -20151021113921 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C45D8C3B -20151021113941 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C4685D5F -20151021114203 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C4F95D97 -20151021114417 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C57ED2FF -20151021114645 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C612EC33 -20151021114825 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C67219F7 -20151021114922 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C6A942BB -20151021115945 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C91E14DB -20151021120515 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CA5F5DB3 -20151021120715 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CAD0D497 -20151021121027 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CB8F9D6F -20151021121241 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CC0F677F -20151021121518 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CC9CC647 -20151021121600 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CCC0ADC3 -20151021121734 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CD1BC68B -20151021121759 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CD2A7DBF -20151021122003 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CDA3D323 -20151021122542 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CED8D107 -20151021122856 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CF8DFEE7 -20151021123548 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D11CAC4F -20151021123633 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D1426BBB -20151021124201 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D2A62F0B -20151021124454 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D353F0FB -20151021124620 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D3AE526F -20151021125224 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D535C4CB -20151021130254 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D7B5CA43 -20151021111833 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B239959D5A7 -20151021112931 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B239A078C1B -20151021123021 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B239EC676DF -20151021131523 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23A2B9FC6B -20151021141029 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23A7BD762B -20151021143421 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23A9C3EFDF -20151021144912 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AB1077AF -20151021145200 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AB49943B -20151021145825 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23ABE06353 -20151021150910 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23ACDA0223 -20151021153131 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AE91738F -20151021154038 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AF40D013 -20151021154300 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AF75AD97 -20151021155008 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B01C9553 -20151021162240 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B319431B -20151021162649 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B35A3D2B -20151021163640 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B439E263 -20151021171004 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B748B983 -20151021172144 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B8609B5B -20151021173002 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B9021E9F -20151021182612 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23BE0C1EDB -20151021190053 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23C120FF97 -20151021192934 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23C3BEB637 +20180605163926 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E3790983687163B +20180605163926 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098369B52F3 +20180605163926 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098369DE513 +20180605163927 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909836B52273 +20180605163928 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909836C20313 +20180605163928 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909836C9430B +20180605163929 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909836DA8707 +20180605163929 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909836F54DB3 +20180605163930 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E3790983717A4D3 +20180605163931 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098372B4C9F +20180605163931 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098372F90F3 +20180605163932 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E3790983730E783 +20180605163932 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098373292DF +20180605163932 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909837356303 +20180605163933 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E3790983743AE7F +20180605163933 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098375E7EEB +20180605163934 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098376750E3 +20180605163934 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098376EC6E7 +20180605163936 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909837A659EF +20180605163936 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909837AD4BE7 +20180605163937 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909837B64E27 +20180605163937 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909837CB4A7F +20180605163938 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909837DDDCB3 +20180605163939 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909837FC35C3 +20180605163939 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909837FE3CDB +20180605163939 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098380C0B83 +20180605163940 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909838128533 +20180605163941 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098383338D7 +20180605163941 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909838450DFF +20180605163942 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909838487D47 +20180605163942 2 6 100 1023 2 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E379098384CCA3B +20180605163943 2 6 100 1023 5 C3B299C4B84296166548A199E1A643F5D00EC1A3E5DA6FE1B5A710220B66BF9D991130FE7A1060DA60127D185C4B301F3EFA5FAEC709DCFB84237488F5614314D426009C5A78A50E27B73DC5A642B0733CB216C91B3AD172E74D4F756CD11832F97866AA8E7A415D634A657E7433453DDAB0BC3A261CB7AA8E37909838664DEF +20180605164241 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC0FCBFECB +20180605164243 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC0FDD64C3 +20180605164247 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC100666A7 +20180605164250 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC1030926F +20180605164251 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC1032D8C3 +20180605164256 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC1072924B +20180605164259 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC1090839F +20180605164301 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC10A234EB +20180605164306 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC10DFDBF7 +20180605164309 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC10FA17CB +20180605164310 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC10FE87E7 +20180605164315 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC11409597 +20180605164318 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC116159DF +20180605164324 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC11AC1B33 +20180605164327 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC11CA3F3F +20180605164329 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC11DC7E7B +20180605164333 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC120452BB +20180605164335 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC121AA82B +20180605164336 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC12227373 +20180605164339 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC12408E5B +20180605164343 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC126E985F +20180605164343 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC1272F6F3 +20180605164345 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC1279FD67 +20180605164346 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC127EDDEB +20180605164348 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC129DA56B +20180605164351 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC12BB0F0B +20180605164353 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC12CF73D7 +20180605164357 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC12FD603B +20180605164359 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC13089AEF +20180605164400 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC131627D3 +20180605164406 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC13547C4F +20180605164412 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC139D9763 +20180605164412 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC13A041BF +20180605164416 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC13CDD8EB +20180605164419 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC13ED0BF3 +20180605164420 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC13EDD913 +20180605164421 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC13F9C1AF +20180605164423 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC14000907 +20180605164424 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC14109807 +20180605164425 2 6 100 1535 2 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC141232B3 +20180605164426 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC14128AC7 +20180605164426 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC1413D4C7 +20180605164429 2 6 100 1535 5 E0EB69B054B239480F217B62FC7CB9CED55EE1B89CD9EBF68FF762B6FD8EE697715C55A255A32B3B41183E78AF4C28DE8614B1C5DF84C88829625BFEF77BA995868888DFD82E49A069338545170AFEC8D2AEFBBEEB4698BCE4E6D7725848B47661F37361EE3FD6FA8BF99E35E35C94729846E60582D00995663AE1C3666B0AB1AFC9316239DC33438FB72AAE7F760CA5D655706DEF44C2D594D01C9F6AB6F7D0F5EA974D6BE256E518A68A0C8902F10BAF2837E295BADC429BA190AC1427B407 +20180605162024 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820A9B6DBF +20180605162030 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820AB71C5B +20180605162033 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820ABF82EF +20180605162036 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820AC82523 +20180605162048 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820B08B40B +20180605162113 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820B8A5FA7 +20180605162125 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820BC6A33F +20180605162128 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820BD10B4B +20180605162138 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820C01495B +20180605162215 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820CD1DE2B +20180605162227 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820D0FD0D3 +20180605162248 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820D7E119F +20180605162307 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820DE78837 +20180605162313 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820E00124F +20180605162328 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820E52028B +20180605162338 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820E83722F +20180605162405 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820F1A3AE7 +20180605162413 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820F3F4EFF +20180605162422 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820F6C4983 +20180605162445 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820FE667F3 +20180605162448 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA820FF1635F +20180605162455 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA8210101C4B +20180605162459 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA82102130B3 +20180605162503 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA821032FD0B +20180605162512 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA821061CB83 +20180605162520 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA8210880823 +20180605162522 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA82108C26F7 +20180605162526 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA82109CB12F +20180605162533 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA8210BB232F +20180605162535 2 6 100 2047 5 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA8210BC312F +20180605162559 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA82114266EB +20180605162617 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA8211A7EF93 +20180605162620 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA8211B1F463 +20180605162622 2 6 100 2047 2 EF800DA0F9EB4469B688C23071C58D9878E1174F7E07324B0BEA4FB5AE0346081E6F11059BB476DC4AFA0DB79D5F32F4AEA65DA1C9EFA1D004FB6344054D51F8678127338384A32FA7599F49F761C676A2EC1D98632090FD549A088D67E855D40A0FD5611B97974951E78032484E335157CF6FD3AC75534B5C1C138CD2ADB4E3CDE2592FDA8C14A0518D0BD8D857A7B7E5117D84E5E95EEDD90C495461DE8BF7037A392136050EBC5675E407A54C68F4C2DC1DA6B66541B46A12E3AAC9E6F5CE5CCB18C7986B7D9C54B454627150734D15586B91665FF5268A27F6D5F8AA9353C203D76B419600E6F131159CFABF562B925160B8BD1E6C33CAEDDA8211B2B8CB +20180605165041 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935413C2A47 +20180605165123 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935418152F7 +20180605165153 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A593541B11757 +20180605165207 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A593541C320AB +20180605165355 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935428684D7 +20180605165613 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935437F2AFB +20180605165641 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A593543A9D4DB +20180605165800 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935442F850B +20180605165954 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A593544F97433 +20180605170035 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935453BD0D3 +20180605170132 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935459D2583 +20180605170224 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A593545EFFA8B +20180605170257 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354623E5C3 +20180605170321 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935464932C3 +20180605171004 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935492771BB +20180605171050 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A593549763053 +20180605171111 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354994174B +20180605171124 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A593549A3E147 +20180605171332 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354A88895F +20180605171340 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354A8E5173 +20180605171346 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354A903D4F +20180605171418 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354AC3192B +20180605171917 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354CE17653 +20180605172016 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354D459DC7 +20180605172106 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354D9A8CE3 +20180605172258 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354E6015A3 +20180605172334 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354E99359B +20180605172635 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59354FDAF763 +20180605173053 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A593551AB6C67 +20180605173245 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935527032B7 +20180605173251 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A59355272787B +20180605173312 2 6 100 3071 2 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A5935529301CB +20180605173342 2 6 100 3071 5 EB5C4079829C2E1A39E88BFF48E2F94A4304E5198072CB97EACD9E3403E692767F80CC8DF04630FFC8B3DBC8521E6A8BC1E7A8FD54F3F28353F8353A6280C97DFBD87D3E8986FD077076C8CB440B2909EDC327470F92BD8BF35F90C0497C5392271CA0291C1F7E3636F5ED8034AC1CADFDE55B103A3B825A55EE452557FB712D34FB597A9D93DBB11FD12AFC1C2ADC95EC76D90AAC1795734C019804CE6F5922E6131CEEB4995C04277252F2D776AA185252A03451A99F2BE4E51ADC514BA754276FB6C3A9ACB9E2BB474D7F519B5BC56DC00D0D042DC066543F639569F00DD59FC1ADADCDD88FCFF0CDA84B8E7D8A58D77B9A22D2800A91EBE47B9B986AC9498A91E891A55CC17C6A398F04D2A14D30A205DAC8A41A7C33010298CF8FE53D9CC46F2AB136798C548ED9A503C132AD48DB1D038137636039BEB6983AC2EF3F2EF287CAB70F37455E206BF7684C8214191FBFFF447B587A3D94143336A22C1A83B6AB9A7DC2EB1099D04F7B9F4E134FB7A2329CCCE6E0FE73AB9A593552C1A7E7 +20180605174443 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F71BB9EBA7 +20180605175218 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F71D2678A3 +20180605175425 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F71D861ED3 +20180605175901 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F71E5FB7CF +20180605180343 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F71F3B10EB +20180605180359 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F71F3EFC3B +20180605181956 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F7224AFBAB +20180605182309 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F722DFE397 +20180605182606 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F723682E0F +20180605183001 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F7241C6B53 +20180605183144 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F72468A833 +20180605183823 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F725A5A94B +20180605184629 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F7271E9047 +20180605184939 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F727B4FF23 +20180605190534 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F72AAFF2BF +20180605190753 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F72B14D523 +20180605191340 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F72C1ED923 +20180605191639 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F72CA9B123 +20180605193155 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F72F768B5B +20180605193341 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F72FC32ECB +20180605194146 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F73137091B +20180605194618 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F7320594AB +20180605194826 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F7326065DF +20180605194913 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F7327A7273 +20180605195719 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F733F6EE4F +20180605200053 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F7349A133B +20180605200209 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F734CDA683 +20180605200404 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F73524AC77 +20180605200812 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F735E21A27 +20180605201507 2 6 100 4095 5 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F737264DFF +20180605201935 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F737F47113 +20180605202538 2 6 100 4095 2 C99ACF60A371F11C9A02EA6920EA7F8F897742FD159713DE275C9C05059C86D7433F57043C70CC9D33F1E3CE222BB1991703F5F9688AAAF21305A0C263C82CAC5174B2621A318E14B1D7888B5F7ECDD4737101DCEC368A64AB38430AE56C3A6300E36FE8FB57C3619327C62ADC80671F67DC772A9C44EFB266D1120F9B9E7DEE5E3D092D6560D2794BFE19391FF4D11D5860DA7D110F3E13F6503765AA4060394E92F6E4301AEB248BFEA34182444B09732F95AA9B0FAAE1DC295022F1267099DE7E23B50D85585BED875C529FA59D642A09743222FDA04031281D729E9C2E9FC3E22FAE8C1AEA0A0F2FF7EC0C32E9B6B190B71917FFB8949A3ADB771843AE1DD39A3DAE9521CE2D10D2D12584E9289D849DBB9A52C7D990FA52EF786A0CA3D33EEDDD1F7350F501EC0ADAFBCA1B825FE995BF373853AC3FE33E48E728D918FA9A68B0E60F283EC8232B8F00984DB33C8800F9800183709C71F7CD5DF5837799837B473BFDB77E579DD76A2A239BFE09D0E32401B7D784391EEC064DF984E29F5C67F7F039BC8F156407AABD94879B4ABD773DA5506743A2E1AC7A5250ED51DD3D30E2CCC63971F1C72E7F424009884416F869A701C5257E9A6A1580324971575BF2999D37088AFB1B57B6F582007B7927CDE06166F2E500B5AC2C5143E6BE0C1A9AF4FEC2C9F688C86EB7DCB6A2C0F9CF6E4901361CAFC40EC640F7390F0743 +20180605210627 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFBDE9C663 +20180605211229 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFBE5D31FF +20180605212615 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFBF726B37 +20180605213758 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFC05E3C97 +20180605214634 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFC108344F +20180605221135 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFC2F6C7EF +20180605221612 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFC34A2373 +20180605222719 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFC426CF47 +20180605225054 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFC5FF2A63 +20180605230438 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFC70EA13F +20180605232516 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFC8A507BF +20180606000440 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFCBB897D3 +20180606003911 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFCE5E6DDF +20180606004021 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFCE6D003B +20180606004054 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFCE6EF7C3 +20180606011249 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFD0E6DF43 +20180606013848 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFD2E87873 +20180606020718 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFD5166B47 +20180606021121 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFD55F3E2B +20180606030823 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFD9C61CC3 +20180606033204 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFDB8F4F47 +20180606033802 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFDBF98B5B +20180606035103 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFDCF1AF47 +20180606041154 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFDE894FEF +20180606041520 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFDEC4EE7B +20180606043713 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFE06AD163 +20180606053417 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFE4C5AD13 +20180606060033 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFE6C71C97 +20180606061040 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFE77EB58B +20180606062720 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFE8BC530F +20180606065112 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFEA7F6853 +20180606065226 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFEA8EAA53 +20180606071446 2 6 100 5121 5 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFEC3498CF +20180606073822 2 6 100 5121 2 37585C4D659694D0B23500E18769F1EF93A776FF9FB92171358D9FE60A517E2CB91A4984A7E923B213CA5ED889D7CBD176B7B475315CB90EBD9920E41043A6C0BD37A8E2679AA7944ED273FDB1CBCAED3B2950BC73132CDE38789421CDDFAEC1C7662F3F9C3EA0C56758D7D3D0257499CE832FEF537F1BC17FFCB2360465A663AB629EF222B7C1E2ACF6368963B6A3D89E5617765B01D483C3BEB0F40D2BC4F4E0512CE41796C411A1EF20D70ED4F071EC56A24C52161D82B9222A52D56B0E48E118DDD1A5C01042E401B6724C80E939B3140A471CEA8C28E33883903283153A3EED07A506818930D61B420B0FF8D1B5F33A2E112B363D2B85A9FDE12AAA3DAE0E08945F4CE4E038A1B61624DD76CADFE172B0FE3C332F7B014634E7F4F80268EB6F1261F0667BF1FC4D9F0BA87C4CC42AC1261F7DA7C4508E3A70485F3D41B5B7AFA8DF0CA0CE61AF7A696B769FF69AB808AED3AE33F40E5E6DA7F8849349FB4A262965160C155B86AA0E13A8FB5EF1BD477790FD8949970B71DD508C971A88781DADEF4F67C1BF8E6BE1AC75B9E6CD74C471FB2D94B27269A9E30B671A52ABE673DAD632C1CC9C139468B852C06844D0D05A40D3A50D410DC4B8DD5B118626128CC5A2DA0093BE486F5D30E621DDB217B03AB97097733BD6E8D1CCFC7515D8761CF7EB0525483678785E29093865A60DA525D0A1D282501C27B1F6C7FEC64BED44F5409889BE78E049E22C5095E7EF4C9B7E88A49DF5CDBE6016A13072A28500AC00E64DB3CE3EBFC668CA0CB94CDDE8381F342E5CE4E2B1FC3067A295771DD0A8FFF308D5A47A91F1A67D8F77C3D20B88EAF17915867EE181DBC2DE8DF43B7179396A563292DB2966E79672BF8B7D0D0A3398A2E374C0E4A1C91DFEDF3BF93 +20180606081635 2 6 100 6143 5 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A3819B8FC5F +20180606083850 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A381B1D13EB +20180606084353 2 6 100 6143 5 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A381B65B5F7 +20180606090554 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A381CB9AFDB +20180606092723 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A381E06BDBB +20180606093241 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A381E51ADE3 +20180606101118 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A3820AE5D83 +20180606101425 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A3820D4A8DB +20180606103024 2 6 100 6143 5 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A3821C99D9F +20180606115838 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A3827308863 +20180606121641 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A38284780CB +20180606121947 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A38286F57DB +20180606131248 2 6 100 6143 5 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A382B9CA287 +20180606135001 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A382DD37563 +20180606140647 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A382ECDF72B +20180606143527 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A383086B0F3 +20180606152011 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A38333510EB +20180606153449 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A3834099ED3 +20180606154730 2 6 100 6143 5 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A3834C6C2F7 +20180606155117 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A3834F7FF83 +20180606191134 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A3840D756E3 +20180606201246 2 6 100 6143 5 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A38446BC09F +20180606211911 2 6 100 6143 5 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A384849597F +20180606223301 2 6 100 6143 5 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A384C9296DF +20180606230821 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A384E995923 +20180607010019 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A38550B3B83 +20180607010449 2 6 100 6143 5 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A385542D20F +20180607022006 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A3859892A7B +20180607022905 2 6 100 6143 2 E52412D53049FA1E04E2773DFEC7889C30A4F3D4C3B3F7097EE2AF5389338B19F1A6F05E376AACA05A03716100BA338DA622A68FBE05566BBE6A32410BFAAF78177F712BEEE39DC8282F5E395907F7B7BB12E2A4C5C5E960E3C130C6F47F5A4D3E568D82E2D3A2BCB2BFDBDEA6739C8BB88F694A66EBF24F1AE57EB8C932B4DD9E83E0B400B70670CC4956B5B6E8F386D597FBDD1B7C7835024F002C2D3786B6BB82877959B16A78ED6192602832F6931E0A822D4ED88EB2BFA40234061518AC7E18EA0DF2398E27ECA306532B6155E18477E5A74B005A7A3903F762930F0EAA569B7C50B7502E3D4E4EDB115627DE49BBDED6528FFBBEEBF16D7D3EE29D61B0D5859ABDD8665345D05F7E5DD8FBB170203113333A87502E3E299E90F2D83AF447D67ADA23E77475E0E7416860385EDF12DD59F2576551D9E82457396064EDE8D13BDDF3F40AE591B4A0D3CB0527454EFABC40E629AF3B5A02BDCA06E194A195B13AD319E81915AB1375BB952A0B779040C46C23184962602D70BB0CBA2ED70AB24E2EB08B1BAEFE96D14154FCF1D00461A4D0B7291EC5010678482A136E4B3A4588C80C7AD89189FAA17F29FF4E5D318079EE5C181CC2CF586A6F73114BD85117EB97FE65CC2D2E3441B688C0DBDD11909783227150DF0FEE0946F39E6565285A62CCBF5464D5A518A7D217C6142A31134C0E8A8F401930F3A6979BC35C24275247444FBAAC542AB1280E7B455888F3AD8FE770FF3782DA1A5D76B3C633C40EC2E6A1B0615AF15931D3DD11F98907E0B836B16D5A2E450A97747509EFEB9963BC306A650B3215E1E0FCCEF9F323B56B75D579A8B280D757E2D28D7ABD079E2C0A7FAE800035BD7386E4EB901AA3BE80644720E625195CA36048A7C3514BD0247C37AD92AA3265B496C539B7DE84E39909E982A6D10D177803B0D38E2B80323C1DE7AD104FD5C1D1D631DA6309651C987255308DBE2DF7F4ED233BF6E6C07AD563E6F6FA23E3E9D248135EF83CBC35DB87F39E666F238B8DB06200DCF63EFA84117C2FDF365125604E09D972A32CA03490FD7D81C947C0B278BB2A385A0321EB +20180607045001 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EA3B1267B +20180607051849 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EA4D3FCDB +20180607052645 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EA51AE857 +20180607074455 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EAABB372F +20180607085512 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EAD8764F3 +20180607101435 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EB0B93D7F +20180607122858 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EB613F7A7 +20180607163002 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EBF961A17 +20180607164733 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EC03FE5D7 +20180607170431 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EC0E41B93 +20180607210523 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0ECA453803 +20180608000228 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0ED1125EF3 +20180608010403 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0ED3657E33 +20180608015201 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0ED537E7FB +20180608023333 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0ED6C3867B +20180608023523 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0ED6CC5597 +20180608025418 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0ED77890BB +20180608052209 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EDD073603 +20180608064909 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EE0434A13 +20180608083049 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EE410EA0B +20180608084134 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EE46EFA03 +20180608113212 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EEAB7B3A3 +20180608123538 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EED06D17F +20180608133606 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EEF40EF2B +20180608134723 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EEFA3A923 +20180608141153 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EF0866973 +20180608154036 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EF3C931BF +20180608155132 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EF42B6B9B +20180608192033 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EFBB82C37 +20180608203618 2 6 100 7167 5 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EFE7167C7 +20180608203803 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0EFE777583 +20180608231830 2 6 100 7167 2 E76114725DD41FA35A7DA1CF2A6C5701F689FC40E96BDAB540431472B92D5E38711F596734C76D1407BC11D5EECD10C52AE09D6EB46C7A119FE7BF2CE718363E5D9D06D972A80D1AEBE550FEF87C596C7B2FAB2FA6A27BE1D6CBFBD7A8B55FFBEFC78E6028AB4F83093162C4D8F9C4E72D45AEE3F788A1AA98A93B2E92DCC69739C3311002388723ED096B0FECB0698AB631108A2F5922453FA81DD178DDFB7A8E651E19E086F36684EF4958EF57E18393C173D07B594AEA0EAF5FE770F72550528C1637E341715CC80C74A2024CDEB2F949200E29BBFC0519F029CA2D45C4A66602553EF9A9086183018A055DFE19698B779908B119CB4C9E162680CA5E3EA471F4AF46F77DA5FF2A2C23C18509B1E8D0591B868A76163079461A83FBDAC95A5E8E4EB9152EAFCDFAD9CE5CDA7CE7846BEE134D52242152C4B671D1B2A05B927F6546A272DDEC50DDAE2D66B866C393F7CA3E2FF505FCC5187394BEEA2BC94F840B800884A8853A6A9AF1FB62837DDE066CC17EDDAD6921F0D96A7A9C2C1705CC024050201E93AF587FE1A480EDA8DCC257B0F7FF6A3006613250098090436BC3C63039846C8A2FD4180BB744D8584184C18F7B05BB110FC4D1C8C1D019EB072FC5C55DDBAE8272CAC153810A6D5A828B7B86350F656D350299264A111C8C876D7502D634C6014F324773E64FFE56DA602736355061CAF39DD29706111ED10F00BD80EE4FE076F6BA743F210C9DC502493A8974FEC1E2706C094A20C29EA7DB29B37D3BD709CD6942FB8ED5EE3D1C521AFFA3A242A13A5A705C458027118C950E656794F671373CE3A7A2D53C0C4BCDDF539D530ABE4A554ED76F7D0D43C1DFFEA320D1CD14A2BC5A5B2C04D84C17399C590D94D86F3E85EC66693D364379149FB7E5709C45B7077D8784114D14B640EB8F50DECCE1A83B041CD217155918BFE937BC0C4E8BBA30452A2F00A4D5F2091DD12C8849EA4989EAC9BCB7040C0049C3986D4F5BF0F3D55FD05A847D3FC4A58F4F5DB860333B1C60F8AE4646919D339B0E4342FEE167A214B25D17D25BDDB7F81BCC37551435C033A66BCD3775FCAE15CA9F311E90FBFF2A082AC2A6B8B0C7F4F5865BFB3B18DEE1E184587C3BA746869D70402BCE1AFAC1AA45BF4D8A6A390F076CA1D6381F7581E2A5718BF44EFB75E9864EBF5EB011FD7C0892C8500BFA01B422E4B67222C259A263863E66CC26C533D0796C0C17D4945D9E0ADDD961EAC0FC3E594B14C13B9A586B0F04486A93 +20180607113212 2 6 100 8191 5 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD9285F38A617 +20180607125146 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928617A82F3 +20180607125328 2 6 100 8191 5 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928617CB5DF +20180607151424 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD92865898703 +20180607154110 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928664CFCC3 +20180607160549 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD92866F6C0D3 +20180607170551 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD92868ADB733 +20180607185631 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD9286BD88C63 +20180607214035 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928707BBADB +20180607235316 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928743304D3 +20180608011956 2 6 100 8191 5 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928769DD007 +20180608062301 2 6 100 8191 5 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD9287EFA162F +20180608062621 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD9287F06E163 +20180608091419 2 6 100 8191 5 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD92883A67EDF +20180608093938 2 6 100 8191 5 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD92884520EDF +20180608122935 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD92888E78073 +20180608144406 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD9288C8EB5F3 +20180608204615 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928965840CB +20180608213353 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928979C33F3 +20180608221715 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD92898C4F47B +20180608230356 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD92899FB78E3 +20180609004940 2 6 100 8191 5 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD9289CC3013F +20180609041610 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928A235CA2B +20180609054840 2 6 100 8191 5 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928A49B8067 +20180609133521 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928B0B91E4B +20180609143811 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928B24E1BF3 +20180609222946 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928BE4C0EC3 +20180610032425 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928C5BA8AFB +20180610042318 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928C72C452B +20180610043314 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928C762DC4B +20180610072715 2 6 100 8191 5 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928CBBDB7BF +20180610083654 2 6 100 8191 5 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928CD718587 +20180610085444 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928CDD91733 +20180610125906 2 6 100 8191 2 CEC852A0F60D2D7ECA1964A06B30C9C74CED6097183E357235647B360695981BFCA2F828FF22BB22CBCFF24E5B421D02E4169AA216FA977C33943011749067AF3996452BEB9C466CB71DB44802D60450F77A488C2C653115C2DD322D781CB1F4F70CBA60F5030B2569B1147F1EA25872E40326FF2F21D60DDBCC2350883EDF246F9F60D2BED0887D8CD9629A2317C4342785BED83D75765C8CCB9770B156256AB3A3D2F1E5C213BF51DA215802212A3EB18ECA6AFB944D26382E2F314FFB6F83AA2BB057E17BF7BE2604BEFF9BEAF8C72594B5097B97CDE8B4724B7A41816481154886EA99878F7D1570F1365971A237B18B0C048B4E0B550F0E4B84B0AEA8111991ADDB782A2585632E85100B8E6B04048565A70F699A04DF650C7FD138F489FC7B6D5D306FD86902666DA4C2F5259795BAEFA426F391265C2840232DC57DF50093EB6A6BDA2884BE777701953FBA502A233D811A49EBF59241B5931C6DAFC1CF3CFD688E182D8D27FF2CE1CA1D5AB06A44ACF0BAC4A35BF5212955D52AF7FE1F0EED58205C7A08EDF536AB22727C670B56D3F134485D4D4CE3D93883EA07AB900E4B9E1B39B6C19FFACFF664224038B5DE4C97DF0008282E6DDFCB9CAD35CD18FD9EE5EDCE40800E741F5CACAC25CEA9EF53C3B43008FF371EF9453A4E4AB69112C5761E903B5656D7FCA40090A1B26C8670217A2DF0AB05F4E530E1445FB243F2E8376BA169BD46A57EED72BE4395D77F5C595E422DECC125DC9ED0445CC15BC977F7DB6F683A419D862606E8EEC600CB206CDB958E9C98DC23E42BCDAE6560561177C4A119E0C65B22121B127B0A3E4A1D92CB42C297E59EDCD056F32DF3B8BF436785A842414BE3203395703B08EA6DCE4ECFE7831A882C0E0644C9D8C259CBFB3DB05AFCA2669D61D2E12EC3EB7BB105BC96627D239F3009F246CB5312C35420251A92F49C0B4C4B51B5526919C6767A13068A220497DFDEA49FC181F4EA2BAF496AE58E2A924F27F658FE6F7F7E21E26F5BCE5D469ABD9F3F19766051E9352CDB1324388C5DB78A6BD1DC861BE588FFDE7DDFE87F1CB0E9F422BD2B95A1EDC2D65EF9A88F36465053F4611E2B425CA697D4ACB99B5DE6B699495EA2F8F840D4720E40F475D3761432EBAAB46C15F2C251AB9C0AA4FAADEFD40B3C707F7B2A6729E55342F8728D21D263FF204B95407976147B9482170466B718232AA3E82A0C53049C6B2C0884830CEDCD8B9992309BB49BFD6BFD4695B0060540DE388DABC39D732B392F38D433EE0C02BE154DD8A48DB89BD98CB161A63AEEB0D25CC9A29D7C6F3780EA87808E8463E9EE46CBD669FAD39B6BDF75B054951784154BAB9C0BC554F30258AC6B39D72A492C027EE8955704E44414DF957398A9A0DA9005E6B152930F7A71AEEAAF2543947A773545E7A8B0B9C13F0CCAD928D3DBCC1B 20151021113847 2 6 100 8191 2 DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE37347869A3 20151021133636 2 6 100 8191 2 DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE373914ECA3 -20151021140108 2 6 100 8191 5 DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE373A17959F +b20151021140108 2 6 100 8191 5 DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE373A17959F diff --git a/lib/public_key/src/pubkey_moduli.hrl b/lib/public_key/src/pubkey_moduli.hrl index e4beecc12a..d3e2492cf2 100644 --- a/lib/public_key/src/pubkey_moduli.hrl +++ b/lib/public_key/src/pubkey_moduli.hrl @@ -1,395 +1,623 @@ -define(dh_default_groups, [{1023, [{2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840821904219}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016037066299}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840822843699}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016038392563}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840824293227}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016038561043}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840824411619}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016040084083}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840826770579}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016040928019}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840829698867}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016041403147}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840831699579}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016044289459}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840831788499}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016046539987}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840835116819}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016048107763}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840838791147}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016048195459}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840839741403}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016048489219}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840843908763}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016051183339}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840844149459}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016051761379}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840846037779}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016059530419}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840846316347}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016061519299}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840848087763}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016061652187}, {2, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840851778483}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016062557059}, + {2, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016062981427}, + {2, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016066800187}, + {5, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016042534663}, + {5, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016047828127}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840818511543}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016048304863}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840819546447}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016049426047}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840820698807}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016052250343}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840821875983}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016055892463}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840822182367}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016056347623}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840823493823}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016056938023}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840828115623}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016058313343}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840833652783}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016065124567}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840844852263}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016066293247}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840849785943}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016066518343}, {5, - 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840849803727}]}, + 137423569441246262992289626302405506810075372518201635033473127540045433614984773406065519964899878780586235832348933590594300290793347611716697640359482924853366011641117770719027755146909495326369377183195861495553717174988136205384838926110458474346294939275424613035724229598089601829380531182016068472303}]}, {1535, [{2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891121581459}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789627621067}, + {2, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789628761283}, + {2, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789634361539}, + {2, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789638537803}, + {2, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789641659627}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891123347643}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789647419339}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891123353283}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789659085619}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891124232763}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789662256763}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891131462067}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789664867003}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891135933003}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789666330667}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891136255299}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789666841459}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891137177907}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789668814427}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891139347603}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789672118003}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891152305467}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789672898027}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891159084867}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789674915179}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891161343219}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789676842763}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891172563627}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789681188923}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891174672243}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789682812883}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891180467739}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789691688803}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891185564427}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789694851307}, {2, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891189869307}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789696895987}, + {2, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789696948499}, + {2, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789699330739}, + {5, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789631448743}, + {5, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789634212463}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891119456223}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789640500127}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891124590423}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789645700087}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891130908327}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789647710183}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891131873727}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789652039063}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891135211407}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789654186463}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891143426247}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789661060927}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891143747007}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789671831647}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891146699103}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789672578407}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891150054447}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789678179287}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891155995647}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789681924847}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891157019487}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789686897743}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891159178863}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789691863487}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891161250063}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789697728943}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891170145447}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789698140423}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891171171087}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789699225607}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891172350063}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789699353287}, {5, - 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891176092263}]}, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789699437767}, + {5, + 2117681492913321569697017096248004964074655225855064803226626530973545674132063479305336653601343613581681296068799225967217443469822913599882869070603558288530230411228882956187328693299502078948089815664109460010482204163236896700745132726891852191217183972837285242539058483051590799983736242396087464474074677177065221920708495653383923226837547541111948031363494948381073214833218893715532814018571166368347836868668692007351599237524270407572667789700740103}]}, {2047, [{2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127673160083}, - {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127674746147}, - {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127677513587}, - {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127677855803}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074755345499}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127681703483}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074756461859}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127691773067}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074760692747}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127693199747}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074773822283}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127694475899}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074776983899}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127702886939}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074790653483}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127707613619}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074794713299}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127713247667}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074815828619}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127727962403}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074834327939}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127729070603}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074842331123}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127741606979}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074845064267}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127745340899}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074846183603}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127764392459}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074847350027}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127764820307}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074850417539}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127771318403}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074852923427}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127781167379}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074865137387}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127782355883}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074871791507}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127782887579}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074872448099}, {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127787746619}, - {2, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127789102259}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074872498379}, + {5, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074753531327}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127666983407}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074755896047}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127675200023}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074769190823}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127687609343}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074773140287}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127691690063}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074801938847}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127708300823}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074808850487}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127712140847}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074810458703}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127715948087}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074819068463}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127717449983}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074828950247}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127717581887}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074831380223}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127725119327}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074843050847}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127735619543}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074853193463}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127776932207}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074854277423}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127788684623}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074856272687}, {5, - 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127790955767}]}, + 30234100291786660119150592253986164718868634461318049072554515332884967674928782249469681512369934810827458855581922926809556244370595605788701190647548919395621435148266404705314169286338735491330335839065308771794695863455361843400123918598469633373229888515556903041476081665517841329650690706907312078385023867825976012891153434200817912196296808624612663609473822637069014486910713969827270391274088701875401022668082592335250640966918882542262485103727016143768199802712794462461532704087012779665855118715263701391361266921229205676528586338993875313766674367990445223648968867957230166128407903969074856341807}]}, {3071, [{2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199506260163}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289461870763}, + {2, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289490971387}, + {2, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289493767387}, + {2, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289502528779}, + {2, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289515762739}, + {2, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289520111827}, + {2, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289526490499}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199530244827}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289531918987}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199578944619}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289535321539}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199589988939}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289537766083}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199594013379}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289585885627}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199601609043}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289591046227}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199604230203}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289593005899}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199606755099}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289609404787}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199618079787}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289612863787}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199653718659}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289648408147}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199657776483}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289660538083}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199707657579}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289673483683}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199722711699}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289677227419}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199743456099}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289698314083}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199785339603}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289741797499}, {2, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199797260499}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289743929803}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199507581927}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289453025863}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199510208343}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289457558263}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199537327623}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289460688727}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199551703167}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289474675927}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199617722127}, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289594040647}, + {5, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289609025887}, + {5, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289609530703}, + {5, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289654971847}, + {5, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289728752743}, + {5, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289741648567}, + {5, + 5341214654634261952873757181561533451707821361473790513564315292835421225907290979705658514768610744229080270038566630873421837799494130654470818355524260427309266809137559455752156841542079285699912382198438256477191140483659741554623458276984132571490005422487391200312212866133415680909716507907845827994683552282075519283183306400978216170683966125586514167935144707307129515552296413428393454073134896115280919323970931969859738752463628375871247541392539129483603011834938988123237171126084442161006950491163910976429369302209546222425310901643650474858404742396613584660709357575219554168390865409561609082174871377547770444430973616557924010418332760953296455735166542214510320276939683699294586632574638203802976903133684878674504505778352407591179548498641812857848247717199756967280188814464938382873930435957699864919392905570032937866615892011156011915598355499435483769756567649481438043557349653592289746986983}]}, + {4095, + [{2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908261488803}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908267757267}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908296392939}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908296649787}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908347767723}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908378270547}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908383266867}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908404042059}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908438601507}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908495213859}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908512647459}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908521746723}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908568726363}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908573748939}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908598118683}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908611654827}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908619313779}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908654940987}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908658321027}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908711194899}, + {2, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908729714499}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199621084383}, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908237597607}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199634824407}, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908282017743}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199642326807}, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908357526423}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199665149823}, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908366458383}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199708695087}, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908428742727}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199765825887}, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908488602303}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199767685887}, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908617606623}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199773947727}, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908644249167}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199780743543}, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908664024183}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199786221207}, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908676438567}, {5, - 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199798706967}]}, - {4095, + 822475527894530229285616572113840248471252289865654730245673569989009517195150670386319918731764341482939973599599030444586627098726805325532602670776492782830517765627499389443537251148551632924278584658894256392558800578282770783952781444172123021909239761249266774011128112210797775865561188225245937456884457382356013600801136212313898917668235824265001348217562305609115401999529744566651634335823205650035802368807460021617740974817291658859354863897470423588038163002057414285871641295222833687523714538475514552855242579151518676338365048493158502050812316214163484509139051517638342109175849018785568945149403656833584359154601084850728291664155244903363511084332084337961858034913924653425899617872300974717518876133738228463402736897605365573279650828581423928774933880146466418294504197525108110672457161289146815032997391965470390378909910135534473119298720916725046763262261767220808960157446815529871730997078479389353851235418277521225090118250855917746026804319123727978865815215602336860198597431012309304151978584224046103750860062629864591763945976315990671793648388266723695721279940197843205282458713913995036945430630152450677414407385229033726976302905725696701985169880658807635234608315361840320908697685503}]}, + {5121, [{2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328641094123}, - {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328654189387}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247097689699}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328663242883}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247187891059}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328715041723}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247233309283}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328717604779}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247329347539}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328805204587}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247374725179}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328806565843}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247374854083}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328807451707}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247416266563}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328836115507}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247449925747}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328845968059}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247491264043}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328887178459}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247565114563}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328908234163}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247602039643}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328948166083}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247648923259}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328954136203}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247676572003}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328963052323}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247749635347}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329023777723}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247795316107}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329047093003}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247845693523}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329058480379}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247846693459}, {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329090057419}, - {2, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329132001859}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247903649683}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328685618887}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247105253887}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328733393407}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247123422007}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328804704703}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247138876567}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328808160607}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247150015567}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328817663383}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247182428143}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328826409727}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247202352967}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328842353143}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247251099967}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328915670167}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247277733823}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328928173423}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247373770207}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328936548223}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247486491463}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328945813063}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247595077447}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328955100607}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247618301767}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328983302407}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247645016047}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328995176167}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247783283863}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329021303887}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247816131343}, {5, - 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329064403567}]}, + 649437634112526011781048553400039087345326903154523759350403591156064026924461442249265424643851483793427933209842971350578174113891441825577284685965852170818096276564472575980385637569538579237402539408651576344680653270161629667112355235907244563250700929011643383515531122864487687325699022847401349887930148743573324935926928038313274118780408648738039221552094286634605859059178302001609063051473627616638916986695467354111409872240377448596882457893385604785675125747799925704521626444410537947809612042456889585358493384339367397319430466068497259487250009990226983476303290182605464299191144834590976900215207184217290547939862278004600042733098488459539365766704233072540349790910413963048455919274571091600102388120830520138960918238026360535071025369430480571742657175404099199715243175884516644982333939980185912023546244471169175154232817129035386017126612372249727029415960226233559719423091324216204450258205068541788852628274234145551296430267231614519548422573530219115334315814963859220772016127905259664901596292960624357867171314754794327851281187544474064975723856559261998464776997766060743177575177887669315503357551968629467385805021951612024977234727345596392623743650652821546588655008745166946053122284578514217986359571614564066926642313354080995691975795001216172305325876725224168312406194959039369235312034402577256851071978396414051789255283218481832719899346830805746190414783360826783268783647194536819312776246291560322670087150506500394384601386261997874464354519244142316219347283660495896740247874345167}]}, {6143, [{2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255204878912539}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066212697067}, + {2, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066239737819}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205024824427}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066261564859}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205108938283}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066266476003}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205168452667}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066306104707}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205178336083}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066308614363}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205194695203}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066415298659}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205234987027}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066433581259}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205249389907}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066436192219}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205299503899}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066526639459}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205303762219}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066543056683}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205318419043}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066571940083}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205369723267}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066616922347}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205388065627}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066630852307}, {2, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205483192027}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066646474627}, + {2, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066845660899}, + {2, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104067076479267}, + {2, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104067184606083}, + {2, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104067259968123}, + {2, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104067267961323}, {5, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255204867528103}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066189360223}, {5, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255204958533343}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066217457143}, {5, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205142917087}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066324667807}, {5, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205164709807}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066489492103}, {5, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205223494543}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066643247863}, {5, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205238451607}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066905718943}, {5, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205398650527}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104066970573183}, {5, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205534891927}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104067042481887}, {5, - 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205578782263}]}, + 30210369155779651888589832154992934074138507220822617750684652871127582962409899985645946445695043253195686248244998571402305199678770384280564307485035486218800068429843963439425551779021865465473175487387006425679517736862515996424867831461548685177440883895142510892080386024242790580351718476912346064665887342021801124592374644199240055614707801951400286738571835106941459565263538011604632591754698655670731747906958754306695890917250845082935314433013066321817795811216868330076422883334026288452966305998174700518168814979477732850177021088448137305837683404856702535774772361477172629825124721712806311678193131143271354379844514551970600366748790881625770009341628054007754553253798271412759265676226769394213651014204828629926952929904315923670432908575989917617637701451215022415020602741724294119817098286839062394376589141071497906909592069997336204239169602926838746847024777759842015748321319275357899423502183072151966760234482986263033779816032715802142058060420345923767082809675434739360245514122590144988299733345731573144371526046690587022732405227784184600940160738238518293781021765582962691631713434222022562950296250509633938674749281309291074381760671163336862668582157228513024763628253337784730104842959368278069041285218519766922739574404159050610285845118633942864745158438604557438873320358729699870593735296129291292133537433344339822168319576836729204869998368045864710009464349668393627057504172016907834801787571594303040666608785976162184230007930556331766254151014073812956419139773303370139752142739047952426344593274617190212675329544654619143794215577626176639637678757668518842586496846866347512471156638951909845841212416559374312458890749201523393740959899515314744619218832833815902335851353279396321673115498490049357132026679171719767095122045794337383943188601986364730890641872503895354104067188249103}]}, + {7167, + [{2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284680505796219}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284680524856539}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284680670831859}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284680995675027}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681153034243}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681267142387}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681306144307}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681336711163}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681362638459}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681374503099}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681467737603}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681522006547}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681585814027}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681591978499}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681697407907}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681773510443}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681779980579}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681794840947}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681855986587}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284682028742019}, + {2, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284682126322323}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284680529504343}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284680623896367}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284680724430207}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284680814262183}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284680973785623}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284680984913367}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681363215767}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681736147327}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681849549247}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284681982651447}, + {5, + 5483947689873238016293916031421210417715226198450458695278359214939920808903888754748291585234470514731095293158971577871290333956546390471923967166891926796058037943347061391932048683243406115629059207198430761405517792845307599528545123275907240829958638010654676409407473464540147054022768326380533144139109013796005070619515692497303229683409723476100264437337159592967071649572068146217379004726298805073131642749312292639037974687912276595434011484665633472741970437405242931540792817150021104152269103538845906716294609703037973874968257574699425342614963850129729638055165011318321314629257017448744791130817504976352049315558175084707575517905220240735436472311376085977023193255767115772199401681050675227245864337841813577099951328506716260252484525951496988402157538736606893316558602219804539468211692272341101231081798647407433475330661334010047363328925076029072733284928506274503591566463356567449951050328939372527077820435552083641057965091365289077453354175453158803766717082697605135002698550392387018215808881309906132288850897899530025875371847565845964186403727130406970585738244224109459935326058926178367135154001854890789551481230848123840375019517586126229348925204229138925157417388983071508190365878773959469248844627811548238703202907823260627705881418371964608641916875906309702255332357870246656733850484860625288965209661089574538795660416296959228913342040037715375469749366782116594607018721130210724633134051682028201789300859780675503521182677498151404274736590115271652257881815395804591347270645487515405426176207583246761514846190105223591830994843572131787042752062568982393789415091692293114059135480055118138148767250658263869768994686391725791746769853583344796533031355717997717521032986544321281377626382079046164167636841143008587025918057095843339228816609264878115677918487854067887356202214595419884175437682477994901012403352228510424776160081628734502208471530373704829323453838286290450475142257346198410524038065099740082374843587568140564545670658917308004231061168599338344693117101685656038296427353228994834347618154742061252460559481017139006630352773110812670787299045754161442872626284682028345287}]}, {8191, [{2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408345391859}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408413484803}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408426294467}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408437420243}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408466188083}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408519326819}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408597129947}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408659473619}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408841130339}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409006846067}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409068135923}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409232339147}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409253569523}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409273017467}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409293367523}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409431407147}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409674894923}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409701436403}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409902628547}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645410027309819}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645410051540267}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645410055117899}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645410163529523}, + {2, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645410264370203}, + {2, 938991641448887958659860711024139841840373070892857314837350127283993531354468803860225599873491818506054401963417489724433963777795696041544477412963807403300832656512849715212168703537706302853428971073305304224008208665300028518281475780493382070018498379488833882168221853720545474425047940975435356027594634176129712250061883354535324982741923143373986406603949677080360223989497048086447454366625852264609369284140522273595340921542019308988041920995057608746115976973659704188342646944998285431473302075966106608530908140377765357842459486869512398523240695806503711124427370056638597159539032058092571318621818616699716647464298881944582194013388150591419588422793657857267906072494480713650129757905856314362270238621284311461743652666256381611674809565144562467655186251867429369336740018623120262859220669942243740953355278814789244133782043857008487446798345197999966787658254507117076710455244182794239065255535191498857182705725985655379455993825553257619502588673174759329362518373537685585117537004065137523099625519490356398330532110250061129576411957409731201790054967354938147031111368166150009421041430118523249245874882140875551501824754839814848195806919150975076831338899823813371473496616326897054534509843640848822974414341233324307292275820287661792887177523563243279340678632061899626115667671047274195425889742755327012266774742591229119994211561599405909368902449776535330722644597809098307346948888547387746758109319767106289995123864514603259977184876246412673772519845777697496361969177346826245108557971745523905955370437517039028495325595180934057507336816903052766590118820327869839202378278312909402987412274414739124292902164277499512007446916921747463997761815820546816791093343347969046462095463611789365326128045878985464594892022442144072282717352526544915821855299863549245012366815543939396712522935345161074836470227392836664033041735035699615758782980717425699108612161567924880267630103820215946940542401779795959759774248414245436455737309858403883625882609790799283421857564831362243562647683958370353023343221966296655134926556805244483888769178095889844741765908328185625663202823312608064683035802724504683124396450612201783060593269112984065572954508643688374585823409316161924407053191442613988480926581084892323451281350937867676271858142177713557970909833234285545964647506859724327822527317869059455132036566677244407755994867168874825546516623190701762311472512591018622127119388239627852234680483324150442403}, {2, 938991641448887958659860711024139841840373070892857314837350127283993531354468803860225599873491818506054401963417489724433963777795696041544477412963807403300832656512849715212168703537706302853428971073305304224008208665300028518281475780493382070018498379488833882168221853720545474425047940975435356027594634176129712250061883354535324982741923143373986406603949677080360223989497048086447454366625852264609369284140522273595340921542019308988041920995057608746115976973659704188342646944998285431473302075966106608530908140377765357842459486869512398523240695806503711124427370056638597159539032058092571318621818616699716647464298881944582194013388150591419588422793657857267906072494480713650129757905856314362270238621284311461743652666256381611674809565144562467655186251867429369336740018623120262859220669942243740953355278814789244133782043857008487446798345197999966787658254507117076710455244182794239065255535191498857182705725985655379455993825553257619502588673174759329362518373537685585117537004065137523099625519490356398330532110250061129576411957409731201790054967354938147031111368166150009421041430118523249245874882140875551501824754839814848195806919150975076831338899823813371473496616326897054534509843640848822974414341233324307292275820287661792887177523563243279340678632061899626115667671047274195425889742755327012266774742591229119994211561599405909368902449776535330722644597809098307346948888547387746758109319767106289995123864514603259977184876246412673772519845777697496361969177346826245108557971745523905955370437517039028495325595180934057507336816903052766590118820327869839202378278312909402987412274414739124292902164277499512007446916921747463997761815820546816791093343347969046462095463611789365326128045878985464594892022442144072282717352526544915821855299863549245012366815543939396712522935345161074836470227392836664033041735035699615758782980717425699108612161567924880267630103820215946940542401779795959759774248414245436455737309858403883625882609790799283421857564831362243562647683958370353023343221966296655134926556805244483888769178095889844741765908328185625663202823312608064683035802724504683124396450612201783060593269112984065572954508643688374585823409316161924407053191442613988480926581084892323451281350937867676271858142177713557970909833234285545964647506859724327822527317869059455132036566677244407755994867168874825546516623190701762311472512591018622127119388239627852234680483324227808419}, {5, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408307521047}, + {5, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408345535967}, + {5, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408700026887}, + {5, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408840291887}, + {5, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408918699743}, + {5, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645408929943263}, + {5, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409339998527}, + {5, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645409471627367}, + {5, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645410128181183}, + {5, + 881045461522943321086778073300940478556218355297969911976909161486894133662493726399243167458009140047097403832005558428608022057031977203602474613009545091720237343240266129021712322298408144531017770778248716957128799297677903712279084392023819163463966227515269649827380536523405101157732109499388260769586116300288304982677621782718749987230168262305655004727816729815800533511307474309647349575475321354016095742812539133151602748038504759763440423033004809780519532557484323246180020130950200646945418165013898390018998574383185461948128020544881733962825915669056546421700831605194278745248581382984298520377716141327298492058956203175900776169162131066555283318461828456520694888875026876615176999234594065729624240200260702661257238500249077130700729314922467706084046564196655345340394880604121971434682608173172839952354536660137326680056370043971462309932399249681084807535691908014774608948539576573091871838175518964071111240660427603031489552613754601246540211425394120613055590993731825013169587667380928210308207859749014992608494977324762902471764267795852486660601596648189999837075454896316687482540387017067211974603191279230953515521397067907513757763367315888101693042775385804066821260256218210264761730017655260313514255350592287156466544141273327424165523630928036465070504326759160965905472140206420733620859718350162744176336519051572708874620380237875083788097274492094030771087416734847686560630664937136197575123272360898853159596587429099207143246305845544244799356813180338388773189837194780822656452007718856513775556746086854637309945375913748887588098858159436611056484858182222940508156607890079350636796413492320863755066068420264176273501354701451580424930853731245191488999731887724342512885115174853872824237863191925018415676193712562003253140276927443202251707682541813796844055771821904734125528936278921457950566975054216078541402261766645717620168828928676184585062086661069943438428009453737016388913674954661321656899115360462958864817727116179756063838264308057333138934007726602464976584961039426342748390610135215206761067742896313902468085136725214515755654144065167649442144794757021442299332980346481411405659939120613041046295543064197536090990615733218132400037369470292737483454477799095857545361137577823887518193742510875707781884043932899326953370891554930847941892191784528780453236476476667586752290919919524010419077090794678643057876460306613406236250774207318712135446125272108408598954645410156742023}, + {5, 938991641448887958659860711024139841840373070892857314837350127283993531354468803860225599873491818506054401963417489724433963777795696041544477412963807403300832656512849715212168703537706302853428971073305304224008208665300028518281475780493382070018498379488833882168221853720545474425047940975435356027594634176129712250061883354535324982741923143373986406603949677080360223989497048086447454366625852264609369284140522273595340921542019308988041920995057608746115976973659704188342646944998285431473302075966106608530908140377765357842459486869512398523240695806503711124427370056638597159539032058092571318621818616699716647464298881944582194013388150591419588422793657857267906072494480713650129757905856314362270238621284311461743652666256381611674809565144562467655186251867429369336740018623120262859220669942243740953355278814789244133782043857008487446798345197999966787658254507117076710455244182794239065255535191498857182705725985655379455993825553257619502588673174759329362518373537685585117537004065137523099625519490356398330532110250061129576411957409731201790054967354938147031111368166150009421041430118523249245874882140875551501824754839814848195806919150975076831338899823813371473496616326897054534509843640848822974414341233324307292275820287661792887177523563243279340678632061899626115667671047274195425889742755327012266774742591229119994211561599405909368902449776535330722644597809098307346948888547387746758109319767106289995123864514603259977184876246412673772519845777697496361969177346826245108557971745523905955370437517039028495325595180934057507336816903052766590118820327869839202378278312909402987412274414739124292902164277499512007446916921747463997761815820546816791093343347969046462095463611789365326128045878985464594892022442144072282717352526544915821855299863549245012366815543939396712522935345161074836470227392836664033041735035699615758782980717425699108612161567924880267630103820215946940542401779795959759774248414245436455737309858403883625882609790799283421857564831362243562647683958370353023343221966296655134926556805244483888769178095889844741765908328185625663202823312608064683035802724504683124396450612201783060593269112984065572954508643688374585823409316161924407053191442613988480926581084892323451281350937867676271858142177713557970909833234285545964647506859724327822527317869059455132036566677244407755994867168874825546516623190701762311472512591018622127119388239627852234680483324244759967}]}] ). diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 1c4acc9e1a..45dbd9bcc3 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -49,6 +49,7 @@ pkix_normalize_name/1, pkix_path_validation/3, pkix_verify_hostname/2, pkix_verify_hostname/3, + pkix_verify_hostname_match_fun/1, ssh_decode/2, ssh_encode/2, ssh_hostkey_fingerprint/1, ssh_hostkey_fingerprint/2, ssh_curvename2oid/1, oid2ssh_curvename/1, @@ -883,12 +884,24 @@ pkix_crls_validate(OtpCert, DPAndCRLs0, Options) -> Options, pubkey_crl:init_revokation_state()). %-------------------------------------------------------------------- --spec pkix_verify_hostname(Cert :: #'OTPCertificate'{} | binary(), - ReferenceIDs :: [{uri_id | dns_id | ip | srv_id | oid(), string()}]) -> boolean(). +-spec pkix_verify_hostname(#'OTPCertificate'{} | binary(), + referenceIDs() + ) -> boolean(). --spec pkix_verify_hostname(Cert :: #'OTPCertificate'{} | binary(), - ReferenceIDs :: [{uri_id | dns_id | ip | srv_id | oid(), string()}], - Options :: proplists:proplist()) -> boolean(). +-spec pkix_verify_hostname(#'OTPCertificate'{} | binary(), + referenceIDs(), + proplists:proplist()) -> boolean(). + +-type referenceIDs() :: [referenceID()] . +-type referenceID() :: {uri_id | dns_id | ip | srv_id | oid(), string()} + | {ip, inet:ip_address()} . + +-spec pkix_verify_hostname_match_fun(high_level_alg()) -> match_fun() . + +-type high_level_alg() :: https . +-type match_fun() :: fun((ReferenceID::referenceID() | string(), + PresentedID::{atom()|oid(),string()}) -> match_fun_result() ) . +-type match_fun_result() :: boolean() | default . %% Description: Validates a hostname to RFC 6125 %%-------------------------------------------------------------------- @@ -953,6 +966,11 @@ pkix_verify_hostname(Cert = #'OTPCertificate'{tbsCertificate = TbsCert}, Referen end end. +pkix_verify_hostname_match_fun(https) -> + fun({dns_id,FQDN=[_|_]}, {dNSName,Name=[_|_]}) -> verify_hostname_match_wildcard(FQDN, Name); + (_, _) -> default + end. + %%-------------------------------------------------------------------- -spec ssh_decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}] ; (binary(), ssh2_pubkey) -> public_key() @@ -1516,9 +1534,7 @@ verify_hostname_match_default(Ref, Pres) -> verify_hostname_match_default0(FQDN=[_|_], {cn,FQDN}) -> not lists:member($*, FQDN); verify_hostname_match_default0(FQDN=[_|_], {cn,Name=[_|_]}) -> - [F1|Fs] = string:tokens(FQDN, "."), - [N1|Ns] = string:tokens(Name, "."), - match_wild(F1,N1) andalso Fs==Ns; + verify_hostname_match_wildcard(FQDN, Name); verify_hostname_match_default0({dns_id,R}, {dNSName,P}) -> R==P; verify_hostname_match_default0({uri_id,R}, {uniformResourceIdentifier,P}) -> @@ -1553,6 +1569,13 @@ verify_hostname_match_default0({srv_id,R}, {?srvName_OID,P}) -> verify_hostname_match_default0(_, _) -> false. + +verify_hostname_match_wildcard(FQDN, Name) -> + [F1|Fs] = string:tokens(FQDN, "."), + [N1|Ns] = string:tokens(Name, "."), + match_wild(F1,N1) andalso Fs==Ns. + + ok({ok,X}) -> X. l16_to_tup(L) -> list_to_tuple(l16_to_tup(L, [])). diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index 572748edc9..073bd6f4a2 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -310,7 +310,7 @@ init_ec_pem_encode_generated(Config) -> ec_pem_encode_generated() -> [{doc, "PEM-encode generated EC key"}]. -ec_pem_encode_generated(Config) -> +ec_pem_encode_generated(_Config) -> Key1 = public_key:generate_key({namedCurve, 'secp384r1'}), public_key:pem_entry_encode('ECPrivateKey', Key1), @@ -965,7 +965,7 @@ pkix_verify_hostname_cn(Config) -> %% openssl req -x509 -nodes -newkey rsa:1024 -keyout /dev/null -extensions SAN -config public_key_SUITE_data/verify_hostname.conf 2>/dev/null > public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem %% %% Subject: C=SE, CN=example.com -%% Subject Alternative Name: DNS:kb.example.org, URI:http://www.example.org, URI:https://wws.example.org +%% Subject Alternative Name: DNS:kb.example.org, DNS:*.example.org, URI:http://www.example.org, URI:https://wws.example.org pkix_verify_hostname_subjAltName(Config) -> DataDir = proplists:get_value(data_dir, Config), @@ -984,7 +984,25 @@ pkix_verify_hostname_subjAltName(Config) -> {dns_id,"wws.example.org"}]), %% Check that a dns_id matches a DNS subjAltName: - true = public_key:pkix_verify_hostname(Cert, [{dns_id,"kb.example.org"}]). + true = public_key:pkix_verify_hostname(Cert, [{dns_id,"kb.example.org"}]), + + %% Check that a dns_id does not match a DNS subjAltName wiht wildcard + false = public_key:pkix_verify_hostname(Cert, [{dns_id,"other.example.org"}]), + + %% Check that a dns_id does match a DNS subjAltName wiht wildcard with matchfun + true = public_key:pkix_verify_hostname(Cert, [{dns_id,"other.example.org"}], + [{match_fun, public_key:pkix_verify_hostname_match_fun(https)} + ] + ), + + %% Check that a uri_id does not match a DNS subjAltName wiht wildcard + false = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://other.example.org"}]), + + %% Check that a dns_id does match a DNS subjAltName wiht wildcard with matchfun + true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://other.example.org"}], + [{match_fun, public_key:pkix_verify_hostname_match_fun(https)} + ] + ). %%-------------------------------------------------------------------- %% Uses the pem-file for pkix_verify_hostname_cn @@ -1031,7 +1049,14 @@ pkix_verify_hostname_options(Config) -> end}]), true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://example.com"}], [{fqdn_fun, fun(_) -> default end}]), - false = public_key:pkix_verify_hostname(Cert, [{uri_id,"some://very.wrong.domain"}]). + false = public_key:pkix_verify_hostname(Cert, [{uri_id,"some://very.wrong.domain"}]), + + true = public_key:pkix_verify_hostname(Cert, [{dns_id,"example.com"}]), + true = public_key:pkix_verify_hostname(Cert, [{dns_id,"abb.bar.example.com"}]), + false = public_key:pkix_verify_hostname(Cert, [{dns_id,"example.com"}, + {dns_id,"abb.bar.example.com"}], + [{fqdn_fun,fun(_)->undefined end}]). + %%-------------------------------------------------------------------- %% To generate the PEM file contents: @@ -1351,7 +1376,7 @@ do_gen_ec_param(File) -> ct:fail({key_gen_fail, File}) end. -init_per_testcase_gen_ec_param(TC, Curve, Config) -> +init_per_testcase_gen_ec_param(_TC, Curve, Config) -> case crypto:ec_curves() of [] -> {skip, missing_ec_support}; @@ -1367,7 +1392,7 @@ init_per_testcase_gen_ec_param(TC, Curve, Config) -> end. -crypto_supported_curve(Curve, Curves) -> +crypto_supported_curve(Curve, _Curves) -> try crypto:generate_key(ecdh, Curve) of {error,_} -> false; % Just in case crypto is changed in the future... _-> true diff --git a/lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem b/lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem index 83e1ad37b3..7ab9ed7b96 100644 --- a/lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem +++ b/lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem @@ -1,14 +1,14 @@ -----BEGIN CERTIFICATE----- -MIICEjCCAXugAwIBAgIJANwliLph5EiAMA0GCSqGSIb3DQEBCwUAMCMxCzAJBgNV -BAYTAlNFMRQwEgYDVQQDEwtleGFtcGxlLmNvbTAeFw0xNjEyMjAxNTEyMjRaFw0x -NzAxMTkxNTEyMjRaMCMxCzAJBgNVBAYTAlNFMRQwEgYDVQQDEwtleGFtcGxlLmNv -bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAydstIN157w8QxkVaOl3wm81j -fgZ8gqO3BXkECPF6bw5ewLlmePL6Qs4RypsaRe7cKJ9rHFlwhpdcYkxWSWEt2N7Z -Ry3N4SjuU04ohWbYgy3ijTt7bJg7jOV1Dh56BnI4hwhQj0oNFizNZOeRRfEzdMnS -+uk03t/Qre2NS7KbwnUCAwEAAaNOMEwwSgYDVR0RBEMwQYIOa2IuZXhhbXBsZS5v -cmeGFmh0dHA6Ly93d3cuZXhhbXBsZS5vcmeGF2h0dHBzOi8vd3dzLmV4YW1wbGUu -b3JnMA0GCSqGSIb3DQEBCwUAA4GBAKqFqW5gCso422bXriCBJoygokOTTOw1Rzpq -K8Mm0B8W9rrW9OTkoLEcjekllZcUCZFin2HovHC5HlHZz+mQvBI1M6sN2HVQbSzS -EgL66U9gwJVnn9/U1hXhJ0LO28aGbyE29DxnewNR741dWN3oFxCdlNaO6eMWaEsO -gduJ5sDl +MIICITCCAYqgAwIBAgIJAP31suf/Fi4oMA0GCSqGSIb3DQEBCwUAMCMxCzAJBgNV +BAYTAlNFMRQwEgYDVQQDEwtleGFtcGxlLmNvbTAeFw0xODA1MTcxMDIzNDBaFw0x +ODA2MTYxMDIzNDBaMCMxCzAJBgNVBAYTAlNFMRQwEgYDVQQDEwtleGFtcGxlLmNv +bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsUVMXSM4Q6vYp7H4Svsfv4QQ +dmUD3IdTbtumlyAqLZuc6Z0HU9IOE0wpF97+5AE3moHluwN/MtSX/fb9oxCjh3L6 +iDla770uUoIgiWkA9lyzuYXt7zGsqc0EmGMJRAHp4jOxI26U/C8wdXoyZsGD8GPr +hYAI2Me4CkdDqCoRuUUCAwEAAaNdMFswWQYDVR0RBFIwUIIOa2IuZXhhbXBsZS5v +cmeCDSouZXhhbXBsZS5vcmeGFmh0dHA6Ly93d3cuZXhhbXBsZS5vcmeGF2h0dHBz +Oi8vd3dzLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBCwUAA4GBAKs8vWMqpXiuFhcq +6W1dMrVB4tuDjt1Ctr3g2USXBLgm8NxsZzslFyDnrvtZY0hbjcAkGKMMhy8lFD5t ++GjBbyp7MKII6vJaVvc+wbrsbNdvioB1puGwbgVhgD3Kb79do9h6JrNncjMvBN7j +VK6BUB8TUofFmztMjoPlxFOs/7qK -----END CERTIFICATE----- diff --git a/lib/public_key/test/public_key_SUITE_data/verify_hostname.conf b/lib/public_key/test/public_key_SUITE_data/verify_hostname.conf index a28864dc78..6b4e4f284e 100644 --- a/lib/public_key/test/public_key_SUITE_data/verify_hostname.conf +++ b/lib/public_key/test/public_key_SUITE_data/verify_hostname.conf @@ -10,7 +10,8 @@ CN=example.com subjectAltName = @alt_names [alt_names] -DNS = kb.example.org +DNS.1 = kb.example.org +DNS.2 = *.example.org URI.1 = http://www.example.org URI.2 = https://wws.example.org diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk index f7faadb8fb..99a0cc087e 100644 --- a/lib/public_key/vsn.mk +++ b/lib/public_key/vsn.mk @@ -1 +1 @@ -PUBLIC_KEY_VSN = 1.6 +PUBLIC_KEY_VSN = 1.5.2 diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml index 3c0d282ba6..d7ad7c8dcc 100644 --- a/lib/reltool/doc/src/notes.xml +++ b/lib/reltool/doc/src/notes.xml @@ -38,22 +38,7 @@ thus constitutes one section in this document. The title of each section is the version number of Reltool.</p> - <section><title>Reltool 0.7.6</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> Calls to <c>erlang:get_stacktrace()</c> are removed. - </p> - <p> - Own Id: OTP-14861</p> - </item> - </list> - </section> - -</section> - -<section><title>Reltool 0.7.5</title> + <section><title>Reltool 0.7.5</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk index c698790ede..49997b1e52 100644 --- a/lib/reltool/vsn.mk +++ b/lib/reltool/vsn.mk @@ -1 +1 @@ -RELTOOL_VSN = 0.7.6 +RELTOOL_VSN = 0.7.5 diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml index fb13b74888..355e3dd40d 100644 --- a/lib/runtime_tools/doc/src/notes.xml +++ b/lib/runtime_tools/doc/src/notes.xml @@ -32,22 +32,6 @@ <p>This document describes the changes made to the Runtime_Tools application.</p> -<section><title>Runtime_Tools 1.13</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - New utility module <c>scheduler</c> which makes it easier - to measure scheduler utilization.</p> - <p> - Own Id: OTP-14904</p> - </item> - </list> - </section> - -</section> - <section><title>Runtime_Tools 1.12.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk index 0a4ad61537..26869b9412 100644 --- a/lib/runtime_tools/vsn.mk +++ b/lib/runtime_tools/vsn.mk @@ -1 +1 @@ -RUNTIME_TOOLS_VSN = 1.13 +RUNTIME_TOOLS_VSN = 1.12.5 diff --git a/lib/sasl/doc/src/error_logging.xml b/lib/sasl/doc/src/error_logging.xml index 8731b73599..356b1f98e9 100644 --- a/lib/sasl/doc/src/error_logging.xml +++ b/lib/sasl/doc/src/error_logging.xml @@ -33,8 +33,8 @@ <file>error_logging.xml</file> </header> <note> - <p>The SASL error logging concept desribed in this section is - deprecated since OTP-21, when the + <p>The SASL error logging concept described in this section is + deprecated since Erlang/OTP 21.0, when the new <seealso marker="kernel:logger_chapter">logging API</seealso> was introduced.</p> <p>The new default behaviour is that the SASL application no @@ -45,9 +45,10 @@ which is setup by Kernel. <seealso marker="#progress_report">Progress reports</seealso> are by default not logged, but can be enabled - by setting the Kernel configuration - parameter <seealso marker="kernel:kernel_app#logger_progress_reports"> - <c>logger_progress_reports</c></seealso> to <c>log</c>.</p> + by setting the primary log level to <c>info</c>, for example by + using the Kernel configuration + parameter <seealso marker="kernel:kernel_app#logger_level"> + <c>logger_level</c></seealso>.</p> <p>The old SASL error logging behaviour can be re-enabled by setting the Kernel configuration parameter <seealso marker="kernel:kernel_app#logger_sasl_compatible"> @@ -70,10 +71,10 @@ <item>Progress report</item> <item>Crash report</item> </list> - <p>When the SASL application is started, it adds a logger handler + <p>When the SASL application is started, it adds a Logger handler that formats and writes these reports, as specified in the <seealso marker="sasl_app#deprecated_error_logger_config">configuration - parameters for SASL</seealso></p> + parameters for SASL</seealso>.</p> <section> <marker id="supervisor_report"/> diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml index c2dc9a3fc2..791e9c063a 100644 --- a/lib/sasl/doc/src/notes.xml +++ b/lib/sasl/doc/src/notes.xml @@ -31,81 +31,6 @@ </header> <p>This document describes the changes made to the SASL application.</p> -<section><title>SASL 3.2</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>A new logging API is added to Erlang/OTP, see the - <seealso - marker="kernel:logger"><c>logger(3)</c></seealso> manual - page, and section <seealso - marker="kernel:logger_chapter">Logging</seealso> in the - Kernel User's Guide.</p> - <p>Calls to <c>error_logger</c> are automatically - redirected to the new API, and legacy error logger event - handlers can still be used. It is, however, recommended - to use the Logger API directly when writing new code.</p> - <p>Notice the following potential incompatibilities:</p> - <list> <item><p>Kernel configuration parameters - <c>error_logger</c> still works, but is overruled if the - default handler's output destination is configured with - Kernel configuration parameter <c>logger</c>.</p> <p>In - general, parameters for configuring error logger are - overwritten by new parameters for configuring - Logger.</p></item> <item><p>The concept of SASL error - logging is deprecated, meaning that by default the SASL - application does not affect which log events are - logged.</p> <p>By default, supervisor reports and crash - reports are logged by the default Logger handler started - by Kernel, and end up at the same destination (terminal - or file) as other standard log event from Erlang/OTP.</p> - <p>Progress reports are not logged by default, but can be - enabled with the Kernel configuration parameter - <c>logger_progress_reports</c>.</p> <p>To obtain - backwards compatibility with the SASL error logging - functionality from earlier releases, set Kernel - configuration parameter <c>logger_sasl_compatible</c> to - <c>true</c>. This prevents the default Logger handler - from logging any supervisor-, crash-, or progress - reports. Instead, SASL adds a separate Logger handler - during application start, which takes care of these log - events. The SASL configuration parameters - <c>sasl_error_logger</c> and <c>sasl_errlog_type</c> - specify the destination (terminal or file) and severity - level to log for these events.</p></item></list> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13295</p> - </item> - <item> - <p> - The old and out-dated "Status Inspection" tool (modules - <c>si</c> and <c>si_sasl_sup</c>) is removed.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14469</p> - </item> - <item> - <p> - When creating the release tar file, systools now includes - sys.config.src if it exists in the - $ROOT/releases/<vsn>/ directory. This is to allow - adjustments, e.g. resolving environment variables, after - unpacking the release, but before installing it. This - functionality requires a custom tool which uses - sys.config.src as input and creates a correct sys.config - file.</p> - <p> - Own Id: OTP-14950 Aux Id: PR-1560 </p> - </item> - </list> - </section> - -</section> - <section><title>SASL 3.1.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/sasl/doc/src/sasl_app.xml b/lib/sasl/doc/src/sasl_app.xml index be275879ee..6f3b4fd7b0 100644 --- a/lib/sasl/doc/src/sasl_app.xml +++ b/lib/sasl/doc/src/sasl_app.xml @@ -102,10 +102,11 @@ reports</em>, <em>crash reports</em>, and <em>progress reports</em>. These reports are now also printed by the default logger handler started by the Kernel application. Progress - reports are by default stopped by a filter, but can be - added by setting the Kernel configuration - parameter <seealso marker="kernel:kernel_app#logger_progress_reports"> - <c>logger_progress_reports</c></seealso> to <c>log</c>.</p> + reports are by default stopped by the primary log level, but can + be enabled by setting this level to <c>info</c>, for example by + using the Kernel configuration + parameter <seealso marker="kernel:kernel_app#logger_level"> + <c>logger_level</c></seealso>.</p> <p>If the old error logger event handlers are still desired, they must be added by calling <c>error_logger:add_report_handler/1,2</c>.</p> @@ -131,14 +132,13 @@ </taglist> <p>A similar behaviour, but still using the new logger API, can be obtained by setting the Kernel application environment - variable <seealso marker="kernel:kernel_app#logger_sasl_compatible"><c>logger_sasl_compatible=true</c></seealso>. This will add a - second instance of the standard logger handler - named <c>sasl</c>, which will only print the SASL reports. No - SASL reports will then be printed by the Kernel logger - handler.</p> - <p>The <c>sasl</c> handler will be configured according to the - values of the following SASL application environment - variables.</p> + variable <seealso marker="kernel:kernel_app#logger_sasl_compatible"> + <c>logger_sasl_compatible</c></seealso> to <c>true</c>. This + adds a second instance of the standard Logger handler, + named <c>sasl</c>, which only prints the SASL reports. No SASL + reports are then printed by the Kernel logger handler.</p> + <p>The <c>sasl</c> handler is configured according to the values + of the following SASL application environment variables.</p> <taglist> <tag><c><![CDATA[sasl_error_logger = Value ]]></c></tag> <item> diff --git a/lib/sasl/src/sasl.erl b/lib/sasl/src/sasl.erl index 92b80694d7..5db3d75cfb 100644 --- a/lib/sasl/src/sasl.erl +++ b/lib/sasl/src/sasl.erl @@ -131,6 +131,10 @@ add_sasl_logger(std, undefined) -> ok; add_sasl_logger(Dest, Level) -> FC = #{legacy_header=>true, single_line=>false}, + case Level of + info -> allow_progress(); + _ -> ok + end, ok = logger:add_handler(sasl,logger_std_h, #{level=>Level, filter_default=>stop, @@ -139,8 +143,8 @@ add_sasl_logger(Dest, Level) -> {fun logger_filters:remote_gl/2,stop}}, {sasl_domain, {fun logger_filters:domain/2, - {log,equal,[beam,erlang,otp,sasl]}}}], - logger_std_h=>#{type=>Dest}, + {log,equal,[otp,sasl]}}}], + config=>#{type=>Dest}, formatter=>{logger_formatter,FC}}). delete_sasl_logger(undefined) -> ok; @@ -151,6 +155,7 @@ delete_sasl_logger(_Type) -> add_error_logger_mf(undefined) -> ok; add_error_logger_mf({Dir, MaxB, MaxF}) -> + allow_progress(), error_logger:add_report_handler( log_mf_h, log_mf_h:init(Dir, MaxB, MaxF, fun pred/1)). @@ -161,6 +166,13 @@ delete_error_logger_mf(_) -> pred({_Type, GL, _Msg}) when node(GL) =/= node() -> false; pred(_) -> true. +allow_progress() -> + #{level:=PL} = logger:get_primary_config(), + case logger:compare_levels(info,PL) of + lt -> ok = logger:set_primary_config(level,info); + _ -> ok + end. + %%%----------------------------------------------------------------- %%% supervisor functionality %%%----------------------------------------------------------------- diff --git a/lib/sasl/test/sasl_report_SUITE.erl b/lib/sasl/test/sasl_report_SUITE.erl index 72ee2f0a10..c3e0fdd63b 100644 --- a/lib/sasl/test/sasl_report_SUITE.erl +++ b/lib/sasl/test/sasl_report_SUITE.erl @@ -82,7 +82,7 @@ do_gen_server_crash(Config, Encoding) -> application:set_env(kernel, error_logger_format_depth, 30), error_logger:logfile({open,KernelLog}), application:start(sasl), - logger:i(print), + ct:log("Logger config:~n~p",[logger:get_config()]), ct:log("error_logger handlers: ~p",[error_logger:which_report_handlers()]), crash_me(), diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk index 0972ae20ba..52b168598a 100644 --- a/lib/sasl/vsn.mk +++ b/lib/sasl/vsn.mk @@ -1 +1 @@ -SASL_VSN = 3.2 +SASL_VSN = 3.1.2 diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl index 4416626a4c..7f627d66d9 100644 --- a/lib/snmp/src/compile/snmpc.erl +++ b/lib/snmp/src/compile/snmpc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2017. All Rights Reserved. +%% Copyright Ericsson AB 1997-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -456,6 +456,7 @@ compile_parsed_data(#pdata{mib_name = MibName, RelChk = get_relaxed_row_name_assign_check(Opts), Data = #dldata{deprecated = Deprecated, relaxed_row_name_assign_check = RelChk}, + mc_new_type_loop(Definitions), put(augmentations, false), definitions_loop(Definitions, Data), MibName. @@ -481,7 +482,40 @@ do_update_imports([{{Mib, ImportsFromMib0},_Line}|Imports], Acc) -> update_status(Name, Status) -> #cdata{status_ets = Ets} = get(cdata), ets:insert(Ets, {Name, Status}). - + + +mc_new_type_loop( + [{#mc_new_type{ + name = NewTypeName, + macro = Macro, + syntax = OldType, + display_hint = DisplayHint},Line}|T]) -> + ?vlog2("typeloop -> new_type:" + "~n Macro: ~p" + "~n NewTypeName: ~p" + "~n OldType: ~p" + "~n DisplayHint: ~p", + [Macro, NewTypeName, OldType, DisplayHint], Line), + ensure_macro_imported(Macro,Line), + Types = (get(cdata))#cdata.asn1_types, + case lists:keysearch(NewTypeName, #asn1_type.aliasname, Types) of + {value,_} -> + snmpc_lib:print_error("Type ~w already defined.", + [NewTypeName],Line); + false -> + %% NameOfOldType = element(2,OldType), + ASN1 = snmpc_lib:make_ASN1type(OldType), + snmpc_lib:add_cdata(#cdata.asn1_types, + [ASN1#asn1_type{aliasname = NewTypeName, + imported = false, + display_hint = DisplayHint}]) + end, + mc_new_type_loop(T); +mc_new_type_loop([_|T]) -> + mc_new_type_loop(T); +mc_new_type_loop([]) -> + ok. + %% A deprecated object definitions_loop([{#mc_object_type{name = ObjName, status = deprecated}, @@ -745,32 +779,8 @@ definitions_loop([{#mc_object_type{name = NameOfTable, ColMEs]), definitions_loop(RestObjs, Data); -definitions_loop([{#mc_new_type{name = NewTypeName, - macro = Macro, - syntax = OldType, - display_hint = DisplayHint},Line}|T], - Data) -> - ?vlog2("defloop -> new_type:" - "~n Macro: ~p" - "~n NewTypeName: ~p" - "~n OldType: ~p" - "~n DisplayHint: ~p", - [Macro, NewTypeName, OldType, DisplayHint], Line), - ensure_macro_imported(Macro,Line), - Types = (get(cdata))#cdata.asn1_types, - case lists:keysearch(NewTypeName, #asn1_type.aliasname, Types) of - {value,_} -> - snmpc_lib:print_error("Type ~w already defined.", - [NewTypeName],Line); - false -> - %% NameOfOldType = element(2,OldType), - ASN1 = snmpc_lib:make_ASN1type(OldType), - snmpc_lib:add_cdata(#cdata.asn1_types, - [ASN1#asn1_type{aliasname = NewTypeName, - imported = false, - display_hint = DisplayHint}]) - end, - definitions_loop(T, Data); +definitions_loop([{#mc_new_type{},_}|T], Data) -> + definitions_loop(T, Data); %% Plain variable definitions_loop([{#mc_object_type{name = NewVarName, diff --git a/lib/snmp/test/snmp_compiler_test.erl b/lib/snmp/test/snmp_compiler_test.erl index 2b6bba4ee6..0a7b729d1f 100644 --- a/lib/snmp/test/snmp_compiler_test.erl +++ b/lib/snmp/test/snmp_compiler_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -58,7 +58,8 @@ otp_10799/1, otp_10808/1, otp_14145/1, - otp_13014/1 + otp_13014/1, + otp_14196/1 ]). %%---------------------------------------------------------------------- @@ -138,7 +139,7 @@ all() -> groups() -> [{tickets, [], [otp_6150, otp_8574, otp_8595, otp_10799, otp_10808, otp_14145, - otp_13014]}]. + otp_13014, otp_14196]}]. init_per_group(_GroupName, Config) -> Config. @@ -489,6 +490,22 @@ otp_13014(Config) when is_list(Config) -> TableInfo, ok. +%%====================================================================== + +otp_14196(suite) -> + []; +otp_14196(Config) when is_list(Config) -> + put(tname, otp14196), + p("starting with Config: ~p~n", [Config]), + + Dir = ?config(case_top_dir, Config), + MibDir = ?config(mib_dir, Config), + MibFile = join(MibDir, "OTP14196-MIB.mib"), + ?line {ok, Mib} = + snmpc:compile(MibFile, [{outdir, Dir}, {verbosity, trace}]), + p("Mib: ~n~p~n", [Mib]), + ok. + %%====================================================================== diff --git a/lib/snmp/test/snmp_test_data/OTP14196-MIB.mib b/lib/snmp/test/snmp_test_data/OTP14196-MIB.mib new file mode 100644 index 0000000000..0b3c718a02 --- /dev/null +++ b/lib/snmp/test/snmp_test_data/OTP14196-MIB.mib @@ -0,0 +1,47 @@ +OTP14196-MIB DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, OBJECT-TYPE, snmpModules, mib-2 + FROM SNMPv2-SMI + TEXTUAL-CONVENTION + FROM SNMPv2-TC + OBJECT-GROUP + FROM SNMPv2-CONF + ; + +otp14196MIB MODULE-IDENTITY + LAST-UPDATED "1004210000Z" + ORGANIZATION "" + CONTACT-INFO + "" + DESCRIPTION + "Test mib for OTP-14196" + ::= { snmpModules 1 } + +testCompliances OBJECT IDENTIFIER ::= { otp14196MIB 1 } +test OBJECT IDENTIFIER ::= { mib-2 15 } + +typeA OBJECT-TYPE + SYNTAX TypeAType + MAX-ACCESS accessible-for-notify + STATUS current + DESCRIPTION + "Test type for OTP-14196" + ::= { test 4711 } + +TypeAType ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "" + SYNTAX INTEGER + +testGroups OBJECT IDENTIFIER ::= { testCompliances 1 } + +testGroupA OBJECT-GROUP + OBJECTS { typeA } + STATUS current + DESCRIPTION + "" + ::= { testGroups 17 } + +END diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index 87ebfc3c6a..d0ed674eee 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/doc/src/notes.xml @@ -30,144 +30,6 @@ <file>notes.xml</file> </header> -<section><title>Ssh 4.7</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Updated ssh_connection:shell/2 documentation.</p> - <p> - Own Id: OTP-14880</p> - </item> - <item> - <p> - If the daemon port listener is restarted, it could - potentially fail with <c>eaddrinuse</c> if the timing is - unlucky. It will now retry and exponentially back off the - listener restart a few times before failing.</p> - <p> - Own Id: OTP-14955</p> - </item> - <item> - <p> - A channel callback module always got the module name as - reason in a call to terminate. Now it will get the proper - Reason, usually 'normal'.</p> - <p> - Own Id: OTP-15084</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - An option <c>exec</c> for daemons implementing the 'exec' - has existed a long time but has been undocumented. The - old behaviour is kept for compatibility EXCEPT that error - messages are changed and are sent as "stderror" text.</p> - <p> - A new option value is defined to make it much more easy - to implement an own <c>exec</c> server.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14851</p> - </item> - <item> - <p> - The undocumented ssh_dbg module is completely re-written - to facilitate tracing/debugging.</p> - <p> - Own Id: OTP-14896</p> - </item> - <item> - <p> - The SSH supervisor structure has been slightly changed. - This makes stopping the ssh application considerably - faster if there are open connections. This is important - in for example restarts.</p> - <p> - Own Id: OTP-14988</p> - </item> - <item> - <p> - The type specifications in SSH are reworked and the - following types are renamed:</p> - <p> - ssh:ssh_connection_ref() is changed to - ssh:connection_ref(), </p> - <p> - ssh:ssh_daemon_ref() is changed to ssh:daemon_ref(),</p> - <p> - ssh:ssh_channel_id() is changed to ssh:channel_id().</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-15002 Aux Id: OTP-15030 </p> - </item> - <item> - <p> - The internal timer handling in SSH is now based on the - gen_statem timers.</p> - <p> - Own Id: OTP-15019</p> - </item> - <item> - <p> - Removed unused <c>ssh_client_key.erl</c> and - <c>ssh_server_key.erl</c>.</p> - <p> - Own Id: OTP-15028</p> - </item> - <item> - <p> - The Reference Manual pages are partly updated.</p> - <p> - The ssh page is now generated from specs and types, is - restructured and is partly rephrased.</p> - <p> - The ssh_channel, ssh_connection, ssh_client_key_api, - ssh_server_key_api and ssh_sftp pages are updated with - links, correct type names and some minor changes.</p> - <p> - Own Id: OTP-15030 Aux Id: OTP-15002 </p> - </item> - <item> - <p> - The behaviors <c>ssh_channel</c> and - <c>ssh_daemon_channel</c> are renamed to - <c>ssh_client_channel</c> and <c>ssh_server_channel</c> - respectively.</p> - <p> - The old modules are kept for compatibility but should - preferably be replaced when updating callback modules - referring them.</p> - <p> - Own Id: OTP-15041</p> - </item> - <item> - <p> - The <c>rekey_limit</c> option could now set the max time - as well as the previously max data amount.</p> - <p> - Own Id: OTP-15069 Aux Id: ERL-617 </p> - </item> - <item> - <p> - Change process exit supervision with monitor instead of - link</p> - <p> - Own Id: OTP-15082</p> - </item> - </list> - </section> - -</section> - <section><title>Ssh 4.6.9</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/ssh/doc/src/ssh_app.xml b/lib/ssh/doc/src/ssh_app.xml index 6d180a5272..2ebd176e12 100644 --- a/lib/ssh/doc/src/ssh_app.xml +++ b/lib/ssh/doc/src/ssh_app.xml @@ -130,39 +130,47 @@ For the list on a particular installation, use the command <seealso marker="ssh:ssh#default_algorithms/0">ssh:default_algorithms/0</seealso>. The user may override the default algorithm configuration both on the server side and the client side. - See the option <c>preferred_algorithms</c> in the <seealso marker="ssh:ssh#daemon/1">ssh:daemon/1,2,3</seealso> and + See the options + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + and + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso> + in the <seealso marker="ssh:ssh#daemon/1">ssh:daemon/1,2,3</seealso> and <seealso marker="ssh:ssh#connect/3">ssh:connect/3,4</seealso> functions. </p> - <p>Supported algorithms are:</p> + <p>Supported algorithms are (in the default order):</p> <marker id="supported_algos"></marker> <taglist> <tag>Key exchange algorithms</tag> <item> <list type="bulleted"> - <item>ecdh-sha2-nistp256</item> <item>ecdh-sha2-nistp384</item> <item>ecdh-sha2-nistp521</item> - <item>diffie-hellman-group-exchange-sha1</item> + <item>ecdh-sha2-nistp256</item> <item>diffie-hellman-group-exchange-sha256</item> - <item>diffie-hellman-group14-sha1</item> - <item>diffie-hellman-group14-sha256</item> <item>diffie-hellman-group16-sha512</item> <item>diffie-hellman-group18-sha512</item> - <item>(diffie-hellman-group1-sha1, retired: can be enabled with the <c>preferred_algorithms</c> option)</item> + <item>diffie-hellman-group14-sha256</item> + <item>diffie-hellman-group14-sha1</item> + <item>diffie-hellman-group-exchange-sha1</item> + <item>(diffie-hellman-group1-sha1, retired: It can be enabled with the + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + or + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso> + options)</item> </list> </item> <tag>Public key algorithms</tag> <item> <list type="bulleted"> - <item>ecdsa-sha2-nistp256</item> <item>ecdsa-sha2-nistp384</item> <item>ecdsa-sha2-nistp521</item> + <item>ecdsa-sha2-nistp256</item> <item>ssh-rsa</item> - <item>ssh-dss</item> <item>rsa-sha2-256</item> <item>rsa-sha2-512</item> + <item>ssh-dss</item> </list> </item> @@ -178,11 +186,11 @@ <tag>Encryption algorithms (ciphers)</tag> <item> <list type="bulleted"> - <item>[email protected]</item> <item>[email protected]</item> - <item>aes128-ctr</item> - <item>aes192-ctr</item> <item>aes256-ctr</item> + <item>aes192-ctr</item> + <item>[email protected]</item> + <item>aes128-ctr</item> <item>aes128-cbc</item> <item>3des-cbc</item> <item>(AEAD_AES_128_GCM, not enabled per default)</item> @@ -241,7 +249,11 @@ <item><url href="https://tools.ietf.org/html/rfc4253">RFC 4253</url>, The Secure Shell (SSH) Transport Layer Protocol. <p>Except</p> <list type="bulleted"> - <item>8.1. diffie-hellman-group1-sha1. Disabled by default, can be enabled with the <c>preferred_algorithms</c> option.</item> + <item>8.1. diffie-hellman-group1-sha1. Disabled by default, can be enabled with the + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + or + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso> + options.</item> </list> <p/> </item> @@ -280,7 +292,10 @@ <p><marker id="rfc5647_note"/>There is an ambiguity in the synchronized selection of cipher and mac algorithm. This is resolved by OpenSSH in the ciphers [email protected] and [email protected] which are implemented. If the explicit ciphers and macs AEAD_AES_128_GCM or AEAD_AES_256_GCM are needed, - they could be enabled with the option preferred_algorithms. + they could be enabled with the options + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + or + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso>. </p> <warning> <p> @@ -322,10 +337,18 @@ <p>Deviations:</p> <list type="bulleted"> <item>The <c>diffie-hellman-group1-sha1</c> is not enabled by default, but is still supported and can be enabled - with the option <c>preferred-algorithms</c></item> + with the options + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + or + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso>. + </item> <item>The questionable sha1-based algorithms <c>diffie-hellman-group-exchange-sha1</c> and <c>diffie-hellman-group14-sha1</c> are still enabled by default for compatibility with ancient clients and servers. - They can be disabled with the option <c>preferred-algorithms</c></item> + They can be disabled with the options + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + or + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso>. + They will be disabled by default when the draft is turned into an RFC.</item> </list> <p/> </item> diff --git a/lib/ssh/src/ssh_client_channel.erl b/lib/ssh/src/ssh_client_channel.erl index 134d3f08bd..8b5e196412 100644 --- a/lib/ssh/src/ssh_client_channel.erl +++ b/lib/ssh/src/ssh_client_channel.erl @@ -180,6 +180,8 @@ init([Options]) -> {stop, Why} -> {stop, Why} catch + _:undef -> + {stop, {bad_channel_callback_module,Cb}}; _:Reason -> {stop, Reason} end. diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl index ed03b4e2ed..dad7636e3f 100644 --- a/lib/ssh/src/ssh_connection.erl +++ b/lib/ssh/src/ssh_connection.erl @@ -498,25 +498,24 @@ handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId, data = Data}, #connection{channel_cache = Cache} = Connection, server) -> <<?DEC_BIN(SsName,_SsLen)>> = Data, - - #channel{remote_id = RemoteId} = Channel0 = + #channel{remote_id=RemoteId} = Channel = ssh_client_channel:cache_lookup(Cache, ChannelId), - - ReplyMsg = {subsystem, ChannelId, WantReply, binary_to_list(SsName)}, - - try - {ok, Pid} = start_subsystem(SsName, Connection, Channel0, ReplyMsg), - erlang:monitor(process, Pid), - Channel = Channel0#channel{user = Pid}, - ssh_client_channel:cache_update(Cache, Channel), - Reply = {connection_reply, - channel_success_msg(RemoteId)}, - {[Reply], Connection} - catch - _:_ -> - ErrorReply = {connection_reply, channel_failure_msg(RemoteId)}, - {[ErrorReply], Connection} - end; + Reply = + try + start_subsystem(SsName, Connection, Channel, + {subsystem, ChannelId, WantReply, binary_to_list(SsName)}) + of + {ok, Pid} -> + erlang:monitor(process, Pid), + ssh_client_channel:cache_update(Cache, Channel#channel{user=Pid}), + channel_success_msg(RemoteId); + {error,_Error} -> + channel_failure_msg(RemoteId) + catch + _:_ -> + channel_failure_msg(RemoteId) + end, + {[{connection_reply,Reply}], Connection}; handle_msg(#ssh_msg_channel_request{request_type = "subsystem"}, Connection, client) -> @@ -822,7 +821,12 @@ start_channel(Cb, Id, Args, SubSysSup, Exec, Opts) -> ChannelSup = ssh_subsystem_sup:channel_supervisor(SubSysSup), case max_num_channels_not_exceeded(ChannelSup, Opts) of true -> - ssh_server_channel_sup:start_child(ChannelSup, Cb, Id, Args, Exec); + case ssh_server_channel_sup:start_child(ChannelSup, Cb, Id, Args, Exec) of + {error,{Error,_Info}} -> + throw(Error); + Others -> + Others + end; false -> throw(max_num_channels_exceeded) end. diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index f1ff3a70e2..f16aff947b 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -1345,11 +1345,11 @@ handle_event(info, {Proto, Sock, NewData}, StateName, D0 = #data{socket = Sock, {next_event, internal, Msg} ]} catch - C:E -> + C:E:ST -> {Shutdown, D} = ?send_disconnect(?SSH_DISCONNECT_PROTOCOL_ERROR, io_lib:format("Bad packet: Decrypted, but can't decode~n~p:~p~n~p", - [C,E,erlang:get_stacktrace()]), + [C,E,ST]), StateName, D1), {stop, Shutdown, D} end; @@ -1378,10 +1378,10 @@ handle_event(info, {Proto, Sock, NewData}, StateName, D0 = #data{socket = Sock, StateName, D0), {stop, Shutdown, D} catch - C:E -> + C:E:ST -> {Shutdown, D} = ?send_disconnect(?SSH_DISCONNECT_PROTOCOL_ERROR, - io_lib:format("Bad packet: Couldn't decrypt~n~p:~p~n~p",[C,E,erlang:get_stacktrace()]), + io_lib:format("Bad packet: Couldn't decrypt~n~p:~p~n~p",[C,E,ST]), StateName, D0), {stop, Shutdown, D} end; @@ -1770,6 +1770,10 @@ set_kex_overload_prefix(Msg = <<?BYTE(Op),_/binary>>, #data{ssh_params=SshParams case catch atom_to_list(kex(SshParams)) of "ecdh-sha2-" ++ _ -> <<"ecdh",Msg/binary>>; + "curve25519-" ++ _ -> + <<"ecdh",Msg/binary>>; + "curve448-" ++ _ -> + <<"ecdh",Msg/binary>>; "diffie-hellman-group-exchange-" ++ _ -> <<"dh_gex",Msg/binary>>; "diffie-hellman-group" ++ _ -> diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl index 631c4d0213..235f09a178 100644 --- a/lib/ssh/src/ssh_transport.erl +++ b/lib/ssh/src/ssh_transport.erl @@ -104,7 +104,12 @@ algo_two_spec_class(_) -> false. default_algorithms(kex) -> supported_algorithms(kex, [ - 'diffie-hellman-group1-sha1' % Gone in OpenSSH 7.3.p1 + %% Under devolpment: + 'curve25519-sha256', + '[email protected]', + 'curve448-sha512', + %% Gone in OpenSSH 7.3.p1: + 'diffie-hellman-group1-sha1' ]); default_algorithms(cipher) -> @@ -126,6 +131,11 @@ supported_algorithms(kex) -> {'ecdh-sha2-nistp384', [{public_keys,ecdh}, {ec_curve,secp384r1}, {hashs,sha384}]}, {'ecdh-sha2-nistp521', [{public_keys,ecdh}, {ec_curve,secp521r1}, {hashs,sha512}]}, {'ecdh-sha2-nistp256', [{public_keys,ecdh}, {ec_curve,secp256r1}, {hashs,sha256}]}, + %% https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves + %% Secure Shell (SSH) Key Exchange Method using Curve25519 and Curve448 + {'curve25519-sha256', [{public_keys,eddh}, {curves,x25519}, {hashs,sha256}]}, + {'[email protected]', [{public_keys,eddh}, {curves,x25519}, {hashs,sha256}]}, + {'curve448-sha512', [{public_keys,eddh}, {curves,x448}, {hashs,sha512}]}, {'diffie-hellman-group-exchange-sha256', [{public_keys,dh}, {hashs,sha256}]}, {'diffie-hellman-group16-sha512', [{public_keys,dh}, {hashs,sha512}]}, % In OpenSSH 7.3.p1 {'diffie-hellman-group18-sha512', [{public_keys,dh}, {hashs,sha512}]}, % In OpenSSH 7.3.p1 @@ -403,7 +413,10 @@ key_exchange_first_msg(Kex, Ssh0=#ssh{opts=Opts}) when Kex == 'diffie-hellman-gr key_exchange_first_msg(Kex, Ssh0) when Kex == 'ecdh-sha2-nistp256' ; Kex == 'ecdh-sha2-nistp384' ; - Kex == 'ecdh-sha2-nistp521' -> + Kex == 'ecdh-sha2-nistp521' ; + Kex == 'curve25519-sha256' ; + Kex == '[email protected]'; + Kex == 'curve448-sha512' -> Curve = ecdh_curve(Kex), {Public, Private} = generate_key(ecdh, Curve), {SshPacket, Ssh1} = ssh_packet(#ssh_msg_kex_ecdh_init{q_c=Public}, Ssh0), @@ -666,8 +679,10 @@ handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic}, catch Class:Error -> ?DISCONNECT(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED, - io_lib:format("ECDH compute key failed in server: ~p:~p", - [Class,Error]) + io_lib:format("ECDH compute key failed in server: ~p:~p~n" + "Kex: ~p, Curve: ~p~n" + "PeerPublic: ~p", + [Class,Error,Kex,Curve,PeerPublic]) ) end. @@ -1874,6 +1889,11 @@ sha(?'secp521r1') -> sha(secp521r1); sha('ecdh-sha2-nistp256') -> sha(secp256r1); sha('ecdh-sha2-nistp384') -> sha(secp384r1); sha('ecdh-sha2-nistp521') -> sha(secp521r1); +sha('curve25519-sha256' ) -> sha256; +sha('[email protected]' ) -> sha256; +sha('curve448-sha512') -> sha512; +sha(x25519) -> sha256; +sha(x448) -> sha512; sha(Str) when is_list(Str), length(Str)<50 -> sha(list_to_atom(Str)). @@ -1938,7 +1958,10 @@ dh_bits(#alg{encrypt = Encrypt, ecdh_curve('ecdh-sha2-nistp256') -> secp256r1; ecdh_curve('ecdh-sha2-nistp384') -> secp384r1; -ecdh_curve('ecdh-sha2-nistp521') -> secp521r1. +ecdh_curve('ecdh-sha2-nistp521') -> secp521r1; +ecdh_curve('curve448-sha512' ) -> x448; +ecdh_curve('curve25519-sha256' ) -> x25519; +ecdh_curve('[email protected]' ) -> x25519. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile index 0a99d31a63..64282cf3b9 100644 --- a/lib/ssh/test/Makefile +++ b/lib/ssh/test/Makefile @@ -36,6 +36,7 @@ MODULES= \ ssh_options_SUITE \ ssh_basic_SUITE \ ssh_bench_SUITE \ + ssh_chan_behaviours_SUITE \ ssh_compat_SUITE \ ssh_connection_SUITE \ ssh_dbg_SUITE \ @@ -53,6 +54,8 @@ MODULES= \ ssh_key_cb_options \ ssh_key_cb_engine_keys \ ssh_trpt_test_lib \ + ssh_chan_behaviours_client \ + ssh_chan_behaviours_server \ ssh_echo_server \ ssh_bench_dev_null \ ssh_peername_sockname_server \ @@ -136,6 +139,6 @@ release_tests_spec: opt $(INSTALL_DATA) ssh.spec ssh_bench.spec ssh.cover "$(RELSYSDIR)" $(INSTALL_DATA) $(HRL_FILES_NEEDED_IN_TEST) "$(RELSYSDIR)" chmod -R u+w "$(RELSYSDIR)" - @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) + @tar cf - *_SUITE_data property_test | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/ssh/test/ssh_algorithms_SUITE.erl b/lib/ssh/test/ssh_algorithms_SUITE.erl index 0ce4bd8699..3a5478f847 100644 --- a/lib/ssh/test/ssh_algorithms_SUITE.erl +++ b/lib/ssh/test/ssh_algorithms_SUITE.erl @@ -100,7 +100,7 @@ init_per_suite(Config) -> ct:log("all() ->~n ~p.~n~ngroups()->~n ~p.~n",[all(),groups()]), ssh:start(), [{std_simple_sftp_size,25000} % Sftp transferred data size - | setup_pubkey(Config)] + | Config] end ). @@ -459,17 +459,6 @@ pubkey_opts(Config) -> {system_dir, SystemDir}]. -setup_pubkey(Config) -> - DataDir = proplists:get_value(data_dir, Config), - UserDir = proplists:get_value(priv_dir, Config), - Keys = - [ssh_test_lib:setup_dsa(DataDir, UserDir), - ssh_test_lib:setup_rsa(DataDir, UserDir), - ssh_test_lib:setup_ecdsa("256", DataDir, UserDir) - ], - ssh_test_lib:write_auth_keys(Keys, UserDir), % 'authorized_keys' shall contain ALL pub keys - Config. - setup_pubkey(Alg, Config) -> DataDir = proplists:get_value(data_dir, Config), UserDir = proplists:get_value(priv_dir, Config), diff --git a/lib/ssh/test/ssh_chan_behaviours_SUITE.erl b/lib/ssh/test/ssh_chan_behaviours_SUITE.erl new file mode 100644 index 0000000000..16ed152bcd --- /dev/null +++ b/lib/ssh/test/ssh_chan_behaviours_SUITE.erl @@ -0,0 +1,152 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2018-2018. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +%% + +-module(ssh_chan_behaviours_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("ssh/src/ssh.hrl"). +-include("ssh_test_lib.hrl"). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +%%-------------------------------------------------------------------- +%% Common Test interface functions ----------------------------------- +%%-------------------------------------------------------------------- + +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap,{seconds,60}}]. + +all() -> + [ + noexist_subsystem, + undefined_subsystem, + defined_subsystem, + subsystem_client + ]. + +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + ?CHECK_CRYPTO( + begin + ssh:start(), + Config + end). + +end_per_suite(_Config) -> + {Time,R} = timer:tc(ssh, stop, []), + ct:log("Stop ssh: ~p ms",[(100*(Time div 1000)) / 100]), + R. + +init_per_testcase(_TC, Config) -> + SubSystems = [ + {"bad_cb", {ssh_chan_behaviours_undefined, []}}, % A non-existing file + {"ch1", {ssh_chan_behaviours_server, [self(),true]}} + ], + {Pid, Host, Port} = ssh_test_lib:std_daemon(Config, [{subsystems,SubSystems}]), + C = ssh_test_lib:std_connect(Config, Host, Port, []), + [{connref,C}, {daemon_pid,Pid}| Config]. + +end_per_testcase(_TC, Config) -> + {Time,_} = timer:tc(ssh, stop_daemon, [proplists:get_value(daemon_pid,Config)]), + ct:log("Stop daemon: ~p ms",[(100*(Time div 1000)) / 100]), + case flush() of + [] -> ok; + Msgs -> ct:pal("Unhandled messages:~n~p", [Msgs]) + end. + + +-define(EXPECT(What, Bind), + Bind = + (fun() -> + receive What -> + ct:log("~p:~p ~p got ~p",[?MODULE,?LINE,self(),What]), + Bind + after 5000 -> + ct:log("~p:~p ~p Flushed:~n~p",[?MODULE,?LINE,self(),flush()]), + ct:fail("Timeout!",[]) + end + end)() + ). + +%%-------------------------------------------------------------------- +%% Test Cases -------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Try start a subsystem whos name is not known by the server +noexist_subsystem(Config) -> + C = proplists:get_value(connref, Config), + {ok, Ch} = ssh_connection:session_channel(C, infinity), + failure = ssh_connection:subsystem(C, Ch, "noexist", infinity), + ok = ssh_connection:close(C, Ch), + ?EXPECT({ssh_cm,C,{closed,Ch}},[]), + ok. + +%% Try to start a subsystem with a known name, but without any callback file +undefined_subsystem(Config) -> + C = proplists:get_value(connref, Config), + {ok, Ch} = ssh_connection:session_channel(C, infinity), + failure = ssh_connection:subsystem(C, Ch, "bad_cb", infinity), + ok = ssh_connection:close(C, Ch), + ?EXPECT({ssh_cm,C,{closed,Ch}},[]), % self() is instead of a proper channel handler + ok. + +%% Try to start and stop a subsystem with known name and defined callback file +defined_subsystem(Config) -> + C = proplists:get_value(connref, Config), + {ok, Ch1} = ssh_connection:session_channel(C, infinity), + + success = ssh_connection:subsystem(C, Ch1, "ch1", infinity), + IDsrv = ?EXPECT({{_Csrv,_Ch1srv}, {ssh_channel_up,_Ch1srv,_Csrv}}, {_Csrv,_Ch1srv}), + + ok = ssh_connection:close(C, Ch1), + ?EXPECT({IDsrv, {terminate,normal}}, []), + ?EXPECT({ssh_cm, C, {closed,Ch1}}, []), % self() is instead of a proper channel handler + ok. + +%% Try to start and stop a subsystem from a ssh_client_channel behviour +subsystem_client(Config) -> + C = proplists:get_value(connref, Config), + + {ok,ChRef} = ssh_chan_behaviours_client:start_link(C), + IDclt = ?EXPECT({{C,Ch1clt}, {ssh_channel_up,Ch1clt,C}}, {C,Ch1clt}), + IDsrv = ?EXPECT({{_Csrv,Ch1srv}, {ssh_channel_up,Ch1srv,_Csrv}}, {_Csrv,Ch1srv}), + + ok = ssh_chan_behaviours_client:stop(ChRef), + ?EXPECT({IDclt, {terminate,normal}}, []), % From the proper channel handler + ?EXPECT({IDsrv, {terminate,normal}}, []), + ok. + +%%%================================================================ +%%% +%%% + +flush() -> lists:reverse(flush([])). + +flush(Acc) -> + receive + M -> + flush([M|Acc]) + after 0 -> + Acc + end. + diff --git a/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_dsa_key new file mode 100644 index 0000000000..51ab6fbd88 --- /dev/null +++ b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_dsa_key @@ -0,0 +1,13 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK +wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q +diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA +l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X +skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF +Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP +ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah +/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U +ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W +Lv62jKcdskxNyz2NQoBx +-----END DSA PRIVATE KEY----- + diff --git a/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_dsa_key.pub new file mode 100644 index 0000000000..4dbb1305b0 --- /dev/null +++ b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_dsa_key.pub @@ -0,0 +1,11 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j +YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2 +KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU +aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI +fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT +MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh +DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48 +wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2 +/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg== +---- END SSH2 PUBLIC KEY ---- diff --git a/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_ecdsa_key b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_ecdsa_key new file mode 100644 index 0000000000..fb1a862ded --- /dev/null +++ b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_ecdsa_key @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw +mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3 +CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7 +Hneb/99fIYopdMH5NMnk60zGO1uZ2vc= +-----END EC PRIVATE KEY----- diff --git a/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_ecdsa_key.pub b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_ecdsa_key.pub new file mode 100644 index 0000000000..428d5fb7d7 --- /dev/null +++ b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_ecdsa_key.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32 diff --git a/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_rsa_key new file mode 100644 index 0000000000..79968bdd7d --- /dev/null +++ b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_rsa_key @@ -0,0 +1,16 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337 +zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB +6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB +AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW +NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++ +udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW +WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt +n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5 +sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY ++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt +64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB +m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT +tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR +-----END RSA PRIVATE KEY----- + diff --git a/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_rsa_key.pub new file mode 100644 index 0000000000..75d2025c71 --- /dev/null +++ b/lib/ssh/test/ssh_chan_behaviours_SUITE_data/ssh_host_rsa_key.pub @@ -0,0 +1,5 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8 +semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW +RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q== +---- END SSH2 PUBLIC KEY ---- diff --git a/lib/ssh/test/ssh_chan_behaviours_client.erl b/lib/ssh/test/ssh_chan_behaviours_client.erl new file mode 100644 index 0000000000..07ac21ba97 --- /dev/null +++ b/lib/ssh/test/ssh_chan_behaviours_client.erl @@ -0,0 +1,143 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2005-2016. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +%% + +%%% Description: Example ssh client +-module(ssh_chan_behaviours_client). +-behaviour(ssh_client_channel). +-record(state, { + parent, + cm, + ch, + dbg + }). +-export([start_link/1, start/1, + stop/1, send_eof/1, + init/1, handle_msg/2, handle_ssh_msg/2, terminate/2, + code_change/3, handle_call/3, handle_cast/2 + ]). + +-define(DBG(State,Fmt,Args), + case State#state.dbg of + true -> ct:log("~p:~p ~p C=~p Ch=~p "++Fmt, + [?MODULE,?LINE,self(),State#state.cm,State#state.ch|Args]); + false -> ok + end). + + +start_link(C) -> + {ok, Ch} = ssh_connection:session_channel(C, infinity), + ssh_client_channel:start_link(C, Ch, ssh_chan_behaviours_client, [C, Ch, self(), true]). + +start(C) -> + {ok, Ch} = ssh_connection:session_channel(C, infinity), + ssh_client_channel:start(C, Ch, ssh_chan_behaviours_client, [C, Ch, self(), true]). + +send_eof(ChRef) -> + ssh_client_channel:call(ChRef, send_eof). + +stop(ChRef) -> + ssh_client_channel:call(ChRef, stop). + + +init([C, Ch, Parent, Dbg|_Exec]) -> + case ssh_connection:subsystem(C, Ch, "ch1", infinity) of + success -> + State = #state{cm = C, + ch = Ch, + parent=Parent, + dbg=Dbg}, + ?DBG(State, "callback spawned, parent = ~p", [Parent]), + {ok, State}; + + Other -> + {stop, Other} + end. + +handle_msg({ssh_channel_up, ChannelId, ConnectionManager}=M, State0) -> + State = State0#state{cm = ConnectionManager, + ch = ChannelId}, + tell_parent(M, State), + ?DBG(State, "ssh_channel_up",[]), + {ok, State}. + +handle_ssh_msg({ssh_cm, C, {data, Ch, 0, Data}}=M, #state{ch=Ch,cm=C} = State) -> + tell_parent(M, State), + ?DBG(State, "ssh_cm data size(Data)=~p",[size(Data)]), + {ok, State}; + +handle_ssh_msg({ssh_cm, C, {data, Ch, Type, Data}}=M, #state{ch=Ch,cm=C} = State) -> + tell_parent(M, State), + ?DBG(State, "ssh_cm data Type=~p : ~p",[Type,Data]), + {ok, State}; + +handle_ssh_msg({ssh_cm, C, {eof, Ch}}=M, #state{ch=Ch,cm=C} = State) -> + tell_parent(M, State), + ?DBG(State, "eof",[]), + {ok, State}; + +handle_ssh_msg({ssh_cm, C, {signal, _Ch, _SigNameStr}=Sig} = M, #state{ch=Ch,cm=C} = State) -> + %% Ignore signals according to RFC 4254 section 6.9. + tell_parent(M, State), + ?DBG(State, "~p",[Sig]), + {ok, State}; + +handle_ssh_msg({ssh_cm, C, {exit_signal, Ch, _, _Error, _}=Sig}=M, #state{ch=Ch,cm=C} = State) -> + tell_parent(M, State), + ?DBG(State, "~p",[Sig]), + {stop, Ch, State}; + +handle_ssh_msg({ssh_cm, C, {exit_status, Ch, _Status}=Sig}=M, #state{ch=Ch,cm=C} = State) -> + tell_parent(M, State), + ?DBG(State, "~p",[Sig]), + {stop, Ch, State}. + + +handle_call(send_eof, _From,#state{ch=Ch,cm=C} = State) -> + {reply, ssh_connection:send_eof(C,Ch), State}; + +handle_call(stop, _From, State) -> + {stop, normal, ok, State}; + +handle_call(Msg, _From, State) -> + ?DBG(State, "Unknown call ~p", [Msg]), + {reply, {unknown_call,Msg}, State}. + + +terminate(Reason, State) -> + tell_parent({terminate,Reason}, State), + ?DBG(State, "terminate Reason = ~p",[Reason]). + + +handle_cast(Msg, State) -> + ?DBG(State, "Unknown cast ~p", [Msg]), + {noreply, State}. + +code_change(_OldVsn, State, _Extra) -> {ok, State}. + +%%%================================================================ +%%% +%%% + +tell_parent(Msg, #state{parent = Parent, + cm = C, + ch = Ch}) -> Parent ! {{C,Ch}, Msg}. + diff --git a/lib/ssh/test/ssh_chan_behaviours_server.erl b/lib/ssh/test/ssh_chan_behaviours_server.erl new file mode 100644 index 0000000000..a5ec19e0cf --- /dev/null +++ b/lib/ssh/test/ssh_chan_behaviours_server.erl @@ -0,0 +1,96 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2005-2016. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +%% + +%%% Description: Example ssh server +-module(ssh_chan_behaviours_server). +-behaviour(ssh_server_channel). +-record(state, { + parent, + cm, + ch, + dbg + }). +-export([init/1, handle_msg/2, handle_ssh_msg/2, terminate/2]). + +-define(DBG(State,Fmt,Args), + case State#state.dbg of + true -> ct:log("~p:~p ~p C=~p Ch=~p "++Fmt, + [?MODULE,?LINE,self(),State#state.cm,State#state.ch|Args]); + false -> ok + end). + + +init([Pid,Dbg|_Exec]) -> + {ok, #state{parent=Pid, + dbg=Dbg}}. + +handle_msg({ssh_channel_up, ChannelId, ConnectionManager}=M, State0) -> + State = State0#state{cm = ConnectionManager, + ch = ChannelId}, + tell_parent(M, State), + ?DBG(State, "ssh_channel_up",[]), + {ok, State}. + +handle_ssh_msg({ssh_cm, C, {data, Ch, 0, Data}}=M, #state{ch=Ch,cm=C} = State) -> + tell_parent(M, State), + ?DBG(State, "ssh_cm data size(Data)=~p",[size(Data)]), + {ok, State}; + +handle_ssh_msg({ssh_cm, C, {data, Ch, Type, Data}}=M, #state{ch=Ch,cm=C} = State) -> + tell_parent(M, State), + ?DBG(State, "ssh_cm data Type=~p : ~p",[Type,Data]), + {ok, State}; + +handle_ssh_msg({ssh_cm, C, {eof, Ch}}=M, #state{ch=Ch,cm=C} = State) -> + tell_parent(M, State), + ?DBG(State, "eof",[]), + {ok, State}; + +handle_ssh_msg({ssh_cm, C, {signal, _Ch, _SigNameStr}=Sig} = M, #state{ch=Ch,cm=C} = State) -> + %% Ignore signals according to RFC 4254 section 6.9. + tell_parent(M, State), + ?DBG(State, "~p",[Sig]), + {ok, State}; + +handle_ssh_msg({ssh_cm, C, {exit_signal, Ch, _, _Error, _}=Sig}=M, #state{ch=Ch,cm=C} = State) -> + tell_parent(M, State), + ?DBG(State, "~p",[Sig]), + {stop, Ch, State}; + +handle_ssh_msg({ssh_cm, C, {exit_status, Ch, _Status}=Sig}=M, #state{ch=Ch,cm=C} = State) -> + tell_parent(M, State), + ?DBG(State, "~p",[Sig]), + {stop, Ch, State}. + +terminate(Reason, State) -> + tell_parent({terminate,Reason}, State), + ?DBG(State, "terminate Reason = ~p",[Reason]), + ok. + +%%%================================================================ +%%% +%%% + +tell_parent(Msg, #state{parent = Parent, + cm = C, + ch = Ch}) -> Parent ! {{C,Ch}, Msg}. + diff --git a/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_dsa_key new file mode 100644 index 0000000000..51ab6fbd88 --- /dev/null +++ b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_dsa_key @@ -0,0 +1,13 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK +wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q +diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA +l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X +skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF +Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP +ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah +/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U +ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W +Lv62jKcdskxNyz2NQoBx +-----END DSA PRIVATE KEY----- + diff --git a/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_dsa_key.pub new file mode 100644 index 0000000000..4dbb1305b0 --- /dev/null +++ b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_dsa_key.pub @@ -0,0 +1,11 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j +YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2 +KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU +aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI +fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT +MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh +DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48 +wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2 +/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg== +---- END SSH2 PUBLIC KEY ---- diff --git a/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_ecdsa_key b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_ecdsa_key new file mode 100644 index 0000000000..2979ea88ed --- /dev/null +++ b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_ecdsa_key @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49 +AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s +VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A== +-----END EC PRIVATE KEY----- diff --git a/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_ecdsa_key.pub b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_ecdsa_key.pub new file mode 100644 index 0000000000..85dc419345 --- /dev/null +++ b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_ecdsa_key.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32 diff --git a/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_rsa_key new file mode 100644 index 0000000000..79968bdd7d --- /dev/null +++ b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_rsa_key @@ -0,0 +1,16 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337 +zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB +6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB +AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW +NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++ +udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW +WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt +n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5 +sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY ++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt +64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB +m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT +tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR +-----END RSA PRIVATE KEY----- + diff --git a/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_rsa_key.pub new file mode 100644 index 0000000000..75d2025c71 --- /dev/null +++ b/lib/ssh/test/ssh_property_test_SUITE_data/ssh_host_rsa_key.pub @@ -0,0 +1,5 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8 +semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW +RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q== +---- END SSH2 PUBLIC KEY ---- diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index 6060e50d31..f10e7aa96a 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,5 +1,5 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 4.7 +SSH_VSN = 4.6.9 APP_VSN = "ssh-$(SSH_VSN)" diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index 795c38bd8e..34fe352d08 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -27,128 +27,6 @@ </header> <p>This document describes the changes made to the SSL application.</p> -<section><title>SSL 9.0</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Correct handling of ECDH suites.</p> - <p> - Own Id: OTP-14974</p> - </item> - <item> - <p> - Proper handling of clients that choose to send an empty - answer to a certificate request</p> - <p> - Own Id: OTP-15050</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Distribution over SSL (inet_tls) has, to improve - performance, been rewritten to not use intermediate - processes and ports.</p> - <p> - Own Id: OTP-14465</p> - </item> - <item> - <p> - Add suport for ECDHE_PSK cipher suites</p> - <p> - Own Id: OTP-14547</p> - </item> - <item> - <p> - For security reasons no longer support 3-DES cipher - suites by default</p> - <p> - *** INCOMPATIBILITY with possibly ***</p> - <p> - Own Id: OTP-14768</p> - </item> - <item> - <p> - For security reasons RSA-key exchange cipher suites are - no longer supported by default</p> - <p> - *** INCOMPATIBILITY with possible ***</p> - <p> - Own Id: OTP-14769</p> - </item> - <item> - <p> - The interoperability option to fallback to insecure - renegotiation now has to be explicitly turned on.</p> - <p> - *** INCOMPATIBILITY with possibly ***</p> - <p> - Own Id: OTP-14789</p> - </item> - <item> - <p> - Drop support for SSLv2 enabled clients. SSLv2 has been - broken for decades and never supported by the Erlang - SSL/TLS implementation. This option was by default - disabled and enabling it has proved to sometimes break - connections not using SSLv2 enabled clients.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14824</p> - </item> - <item> - <p> - Remove CHACHA20_POLY1305 ciphers form default for now. We - have discovered interoperability problems, ERL-538, that - we believe needs to be solved in crypto.</p> - <p> - *** INCOMPATIBILITY with possibly ***</p> - <p> - Own Id: OTP-14882</p> - </item> - <item> - <p> - Generalize DTLS packet multiplexing to make it easier to - add future DTLS features and uses.</p> - <p> - Own Id: OTP-14888</p> - </item> - <item> - <p> - Use uri_string module instead of http_uri.</p> - <p> - Own Id: OTP-14902</p> - </item> - <item> - <p> - The SSL distribution protocol <c>-proto inet_tls</c> has - stopped setting the SSL option - <c>server_name_indication</c>. New verify funs for client - and server in <c>inet_tls_dist</c> has been added, not - documented yet, that checks node name if present in peer - certificate. Usage is still also yet to be documented.</p> - <p> - Own Id: OTP-14969 Aux Id: OTP-14465, ERL-598 </p> - </item> - <item> - <p> - Deprecate ssl:ssl_accept/[1,2,3] in favour of - ssl:handshake/[1,2,3]</p> - <p> - Own Id: OTP-15056</p> - </item> - </list> - </section> - -</section> - <section><title>SSL 8.2.6</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index 029f29cdb3..adf4fb9ba4 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -89,6 +89,7 @@ [binary()]} | {client | server, [binary()], binary()}}</c></p> <p><c>| {log_alert, boolean()}</c></p> <p><c>| {server_name_indication, hostname() | disable}</c></p> + <p><c>| {customize_hostname_check, list()}</c></p> <p><c>| {sni_hosts, [{hostname(), [ssl_option()]}]}</c></p> <p><c>| {sni_fun, SNIfun::fun()}</c></p> </item> @@ -649,6 +650,14 @@ fun(srp, Username :: string(), UserState :: term()) -> disables the hostname verification check <seealso marker="public_key:public_key#pkix_verify_hostname-2">public_key:pkix_verify_hostname/2</seealso> </p> </item> + + <tag><c>{customize_hostname_check, Options::list()}</c></tag> + <item> + <p> Customizes the hostname verification of the peer certificate, as different protocols that use + TLS such as HTTP or LDAP may want to do it differently, for possible options see + <seealso marker="public_key:public_key#pkix_verify_hostname-3">public_key:pkix_verify_hostname/3</seealso> </p> + </item> + <tag><c>{fallback, boolean()}</c></tag> <item> <p> Send special cipher suite TLS_FALLBACK_SCSV to avoid undesired TLS version downgrade. @@ -1492,6 +1501,18 @@ fun(srp, Username :: string(), UserState :: term()) -> </func> <func> + <name>suite_to_str(CipherSuite) -> String</name> + <fsummary>Returns the string representation of a cipher suite.</fsummary> + <type> + <v>CipherSuite = erl_cipher_suite()</v> + <v>String = string()</v> + </type> + <desc> + <p>Returns the string representation of a cipher suite.</p> + </desc> + </func> + + <func> <name>transport_accept(ListenSocket) -></name> <name>transport_accept(ListenSocket, Timeout) -> {ok, NewSocket} | {error, Reason}</name> diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl index a6ceff25cb..aa3d7e3f72 100644 --- a/lib/ssl/src/inet_tls_dist.erl +++ b/lib/ssl/src/inet_tls_dist.erl @@ -31,7 +31,7 @@ -export([nodelay/0]). --export([verify_client/3, verify_server/3, cert_nodes/1]). +-export([verify_client/3, cert_nodes/1]). -export([dbg/0]). % Debug @@ -236,12 +236,10 @@ accept_loop(Driver, Listen, Kernel) -> end. accept_loop(Driver, Listen, Kernel, Socket) -> - {Opts,CertNodesFun} = - setup_verify_client( - Driver, Socket, get_ssl_options(server)), + Opts = setup_verify_client(Socket, get_ssl_options(server)), wait_for_code_server(), case - ssl:ssl_accept( + ssl:handshake( Socket, trace([{active, false},{packet, 4}|Opts]), net_kernel:connecttime()) @@ -255,7 +253,7 @@ accept_loop(Driver, Listen, Kernel, Socket) -> {Kernel, controller, Pid} -> ok = ssl:controlling_process(SslSocket, Pid), trace( - Pid ! {self(), controller, CertNodesFun}); + Pid ! {self(), controller}); {Kernel, unsupported_protocol} -> exit(trace(unsupported_protocol)) end, @@ -278,48 +276,59 @@ accept_loop(Driver, Listen, Kernel, Socket) -> %% as a configuration marker that verify_client/3 shall be used. %% %% Replace the State in the first occurence of -%% {verify_fun,{fun ?MODULE:verify_client/3,State}} and remove the rest. +%% {verify_fun,{fun ?MODULE:verify_client/3,State}} +%% and remove the rest. %% The inserted state is not accesible from a configuration file %% since it is dynamic and connection dependent. %% -setup_verify_client(Driver, Socket, Opts) -> - setup_verify_client(Driver, Socket, Opts, undefined, []). +setup_verify_client(Socket, Opts) -> + setup_verify_client(Socket, Opts, true, []). %% -setup_verify_client(_Driver, _Socket, [], CertNodesFun, OptsR) -> - {lists:reverse(OptsR),CertNodesFun}; -setup_verify_client(Driver, Socket, [Opt|Opts], CertNodesFun, OptsR) -> +setup_verify_client(_Socket, [], _, OptsR) -> + lists:reverse(OptsR); +setup_verify_client(Socket, [Opt|Opts], First, OptsR) -> case Opt of - {verify_fun,{Fun,NewCertNodesFun}} -> + {verify_fun,{Fun,_}} -> case Fun =:= fun ?MODULE:verify_client/3 of - true when is_function(NewCertNodesFun, 1) -> + true -> if - CertNodesFun =:= undefined -> + First -> case inet:peername(Socket) of {ok,{PeerIP,_Port}} -> + {ok,Allowed} = net_kernel:allowed(), + AllowedHosts = allowed_hosts(Allowed), setup_verify_client( - Driver, Socket, Opts, NewCertNodesFun, + Socket, Opts, false, [{verify_fun, - {Fun, - {NewCertNodesFun,Driver,PeerIP}}} + {Fun, {AllowedHosts,PeerIP}}} |OptsR]); {error,Reason} -> exit(trace({no_peername,Reason})) end; true -> setup_verify_client( - Driver, Socket, Opts, CertNodesFun, OptsR) + Socket, Opts, First, OptsR) end; - true -> - exit( - trace( - {verify_client_bad_argument,CertNodesFun})); false -> setup_verify_client( - Driver, Socket, Opts, CertNodesFun, [Opt|OptsR]) + Socket, Opts, First, [Opt|OptsR]) end; _ -> - setup_verify_client( - Driver, Socket, Opts, CertNodesFun, [Opt|OptsR]) + setup_verify_client(Socket, Opts, First, [Opt|OptsR]) + end. + +allowed_hosts(Allowed) -> + lists:usort(allowed_node_hosts(Allowed)). +%% +allowed_node_hosts([]) -> []; +allowed_node_hosts([Node|Allowed]) -> + case dist_util:split_node(Node) of + {node,_,Host} -> + [Host|allowed_node_hosts(Allowed)]; + {host,Host} -> + [Host|allowed_node_hosts(Allowed)]; + _ -> + allowed_node_hosts(Allowed) end. %% Same as verify_peer but check cert host names for @@ -330,48 +339,19 @@ verify_client(_, {extension,_}, S) -> {unknown,S}; verify_client(_, valid, S) -> {valid,S}; -verify_client(PeerCert, valid_peer, {CertNodesFun,Driver,PeerIP} = S) -> - %% - %% Parse out all node names from the peer's certificate - %% - case CertNodesFun(PeerCert) of - undefined -> - %% Certificate allows all nodes +verify_client(_, valid_peer, {[],_} = S) -> + %% Allow all hosts + {valid,S}; +verify_client(PeerCert, valid_peer, {AllowedHosts,PeerIP} = S) -> + case + public_key:pkix_verify_hostname( + PeerCert, + [{ip,PeerIP}|[{dns_id,Host} || Host <- AllowedHosts]]) + of + true -> {valid,S}; - [] -> - %% Certificate allows no nodes - {fail,cert_missing_node_name}; - CertNodes -> - %% Check if the IP address of one of the nodes - %% in the peer certificate has the peer's IP address - case filter_nodes_by_ip(CertNodes, Driver, PeerIP) of - [] -> - {fail,cert_no_host_with_peer_ip}; - _ -> - {valid,S} - end - end. - -%% Filter out the nodes that has got the given IP address -%% -filter_nodes_by_ip(Nodes, Driver, IP) -> - [Node || - Node <- Nodes, - case dist_util:split_node(Node) of - {node,_,Host} -> - filter_host_by_ip(Host, Driver, IP); - {host,Host} -> - filter_host_by_ip(Host, Driver, IP); - {name,_Name} -> - true - end]. - -filter_host_by_ip(Host, Driver, IP) -> - case Driver:getaddr(Host) of - {ok,IP} -> - true; - _ -> - false + false -> + {fail,cert_no_hostname_nor_ip_match} end. @@ -417,19 +397,18 @@ gen_accept_connection( spawn_opt( fun() -> do_accept( - Driver, Kernel, AcceptPid, DistCtrl, - MyNode, Allowed, SetupTime) + Driver, AcceptPid, DistCtrl, + MyNode, Allowed, SetupTime, Kernel) end, [link, {priority, max}])). -do_accept(Driver, Kernel, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) -> +do_accept( + _Driver, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime, Kernel) -> SslSocket = ssl_connection:get_sslsocket(DistCtrl), receive - {AcceptPid, controller, CertNodesFun} -> + {AcceptPid, controller} -> Timer = dist_util:start_timer(SetupTime), - NewAllowed = - allowed_nodes( - Driver, CertNodesFun, SslSocket, Allowed), + NewAllowed = allowed_nodes(SslSocket, Allowed), HSData0 = hs_data_common(SslSocket), HSData = HSData0#hs_data{ @@ -443,65 +422,67 @@ do_accept(Driver, Kernel, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) -> dist_util:handshake_other_started(trace(HSData)) end. -%% Return a list of allowed nodes according to -%% the given Allowed list that matches the peer certificate -%% -allowed_nodes(_Driver, undefined, _SslSocket, Allowed) -> - Allowed; -allowed_nodes(Driver, CertNodesFun, SslSocket, Allowed) -> +allowed_nodes(_SslSocket, []) -> + %% Allow all + []; +allowed_nodes(SslSocket, Allowed) -> case ssl:peercert(SslSocket) of {ok,PeerCertDER} -> case ssl:peername(SslSocket) of {ok,{PeerIP,_Port}} -> - PeerCert = public_key:pkix_decode_cert(PeerCertDER, otp), - %% - %% Parse out all node names from the peer's certificate - %% - case CertNodesFun(PeerCert) of - undefined -> - %% Certificate allows all nodes - Allowed; + PeerCert = + public_key:pkix_decode_cert(PeerCertDER, otp), + case + allowed_nodes( + PeerCert, allowed_hosts(Allowed), PeerIP) + of [] -> - %% Certificate allows no nodes - ?shutdown(cert_missing_node_name); - CertNodes -> - %% Filter out all nodes in the - %% allowed list that is in peer - %% certificate and that has got - %% the same IP address as the peer - allowed( - filter_nodes_by_ip( - CertNodes, Driver, PeerIP), - Allowed) + error_logger:error_msg( + "** Connection attempt from " + "disallowed node(s) ~p ** ~n", [PeerIP]), + ?shutdown2( + PeerIP, trace({is_allowed, not_allowed})); + AllowedNodes -> + AllowedNodes end; Error1 -> ?shutdown2(no_peer_ip, trace(Error1)) end; + {error,no_peercert} -> + Allowed; Error2 -> ?shutdown2(no_peer_cert, trace(Error2)) end. -allowed(CertNodes, []) -> - %% Empty allowed list means all allowed - %% -> allow only certificate nodes - CertNodes; -allowed(CertNodes, Allowed) -> - %% Find the intersection of the allowed list and certificate nodes - case - [CertNode || - CertNode <- CertNodes, - dist_util:is_allowed(CertNode, Allowed)] - of - [] -> - error_logger:error_msg( - "** Connection attempt from " - "disallowed node(s) ~p ** ~n", [CertNodes]), - ?shutdown2(CertNodes, trace({is_allowed, not_allowed})); - NewAllowed -> - NewAllowed +allowed_nodes(PeerCert, [], PeerIP) -> + case public_key:pkix_verify_hostname(PeerCert, [{ip,PeerIP}]) of + true -> + Host = inet:ntoa(PeerIP), + true = is_list(Host), + [Host]; + false -> + [] + end; +allowed_nodes(PeerCert, [Node|Allowed], PeerIP) -> + case dist_util:split_node(Node) of + {node,_,Host} -> + allowed_nodes(PeerCert, Allowed, PeerIP, Node, Host); + {host,Host} -> + allowed_nodes(PeerCert, Allowed, PeerIP, Node, Host); + _ -> + allowed_nodes(PeerCert, Allowed, PeerIP) + end. + +allowed_nodes(PeerCert, Allowed, PeerIP, Node, Host) -> + case public_key:pkix_verify_hostname(PeerCert, [{dns_id,Host}]) of + true -> + [Node|allowed_nodes(PeerCert, Allowed, PeerIP)]; + false -> + allowed_nodes(PeerCert, Allowed, PeerIP) end. + setup(Node, Type, MyNode, LongOrShortNames, SetupTime) -> gen_setup(inet_tcp, Node, Type, MyNode, LongOrShortNames, SetupTime). @@ -541,15 +522,7 @@ do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) -> end. do_setup_connect(Driver, Kernel, Node, Address, Ip, TcpPort, Version, Type, MyNode, Timer) -> - Opts = - trace( - connect_options( - %% - %% Use verify_server/3 to verify that - %% the server's certificate is for Node - %% - setup_verify_server( - get_ssl_options(client), Node))), + Opts = trace(connect_options(get_ssl_options(client))), dist_util:reset_timer(Timer), case ssl:connect( Address, TcpPort, @@ -587,67 +560,6 @@ close(Socket) -> gen_close(Driver, Socket) -> trace(Driver:close(Socket)). -%% {verify_fun,{fun ?MODULE:verify_server/3,_}} is used -%% as a configuration marker that verify_server/3 shall be used. -%% -%% Replace the State in the first occurence of -%% {verify_fun,{fun ?MODULE:verify_server/3,State}} and remove the rest. -%% The inserted state is not accesible from a configuration file -%% since it is dynamic and connection dependent. -%% -setup_verify_server(Opts, Node) -> - setup_verify_server(Opts, Node, true). -%% -setup_verify_server([], _Node, _) -> - []; -setup_verify_server([Opt|Opts], Node, Once) -> - case Opt of - {verify_fun,{Fun,CertNodesFun}} -> - case Fun =:= fun ?MODULE:verify_server/3 of - true when not is_function(CertNodesFun, 1) -> - ?shutdown2( - Node, - {verify_server_bad_argument,CertNodesFun}); - true when Once -> - [{verify_fun,{Fun,{CertNodesFun,Node}}} - |setup_verify_server(Opts, Node, false)]; - true -> - setup_verify_server(Opts, Node, Once); - false -> - [Opt|setup_verify_server(Opts, Node, Once)] - end; - _ -> - [Opt|setup_verify_server(Opts, Node, Once)] - end. - -verify_server(_, {bad_cert,_} = Reason, _) -> - {fail,Reason}; -verify_server(_, {extension,_}, S) -> - {unknown,S}; -verify_server(_, valid, S) -> - {valid,S}; -verify_server(PeerCert, valid_peer, {CertNodesFun,Node} = S) -> - %% - %% Parse out all node names from the peer's certificate - %% - case CertNodesFun(PeerCert) of - undefined -> - %% Certificate allows all nodes - {valid,S}; - [] -> - %% Certificate allows no nodes - {fail,cert_missing_node_name}; - CertNodes -> - %% Check that the node we are connecting to - %% is in the peer certificate - case dist_util:is_allowed(Node, CertNodes) of - true -> - {valid,S}; - false -> - {fail,wrong_nodes_in_cert} - end - end. - %% ------------------------------------------------------------ %% Determine if EPMD module supports address resolving. Default diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index a7b4ec2bf7..eb5b351dd3 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -55,7 +55,7 @@ format_error/1, renegotiate/1, prf/5, negotiated_protocol/1, connection_information/1, connection_information/2]). %% Misc --export([handle_options/2, tls_version/1, new_ssl_options/3]). +-export([handle_options/2, tls_version/1, new_ssl_options/3, suite_to_str/1]). -deprecated({ssl_accept, 1, eventually}). -deprecated({ssl_accept, 2, eventually}). @@ -772,6 +772,16 @@ tls_version({3, _} = Version) -> tls_version({254, _} = Version) -> dtls_v1:corresponding_tls_version(Version). + +%%-------------------------------------------------------------------- +-spec suite_to_str(ssl_cipher:erl_cipher_suite()) -> string(). +%% +%% Description: Return the string representation of a cipher suite. +%%-------------------------------------------------------------------- +suite_to_str(Cipher) -> + ssl_cipher:suite_to_str(Cipher). + + %%%-------------------------------------------------------------- %%% Internal functions %%%-------------------------------------------------------------------- @@ -938,7 +948,8 @@ handle_options(Opts0, Role, Host) -> crl_check = handle_option(crl_check, Opts, false), crl_cache = handle_option(crl_cache, Opts, {ssl_crl_cache, {internal, []}}), max_handshake_size = handle_option(max_handshake_size, Opts, ?DEFAULT_MAX_HANDSHAKE_SIZE), - handshake = handle_option(handshake, Opts, full) + handshake = handle_option(handshake, Opts, full), + customize_hostname_check = handle_option(customize_hostname_check, Opts, []) }, CbInfo = proplists:get_value(cb_info, Opts, default_cb_info(Protocol)), @@ -954,7 +965,7 @@ handle_options(Opts0, Role, Host) -> client_preferred_next_protocols, log_alert, server_name_indication, honor_cipher_order, padding_check, crl_check, crl_cache, fallback, signature_algs, eccs, honor_ecc_order, beast_mitigation, - max_handshake_size, handshake], + max_handshake_size, handshake, customize_hostname_check], SockOpts = lists:foldl(fun(Key, PropList) -> proplists:delete(Key, PropList) end, Opts, SslOptions), @@ -1197,6 +1208,8 @@ validate_option(handshake, hello = Value) -> Value; validate_option(handshake, full = Value) -> Value; +validate_option(customize_hostname_check, Value) when is_list(Value) -> + Value; validate_option(Opt, Value) -> throw({error, {options, {Opt, Value}}}). diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl index a3333d35e9..dbd2ebf539 100644 --- a/lib/ssl/src/ssl_certificate.erl +++ b/lib/ssl/src/ssl_certificate.erl @@ -138,8 +138,8 @@ validate(_, {bad_cert, _} = Reason, _) -> {fail, Reason}; validate(_, valid, UserState) -> {valid, UserState}; -validate(Cert, valid_peer, UserState = {client, _,_, Hostname, _, _}) when Hostname =/= disable -> - verify_hostname(Hostname, Cert, UserState); +validate(Cert, valid_peer, UserState = {client, _,_, {Hostname, Customize}, _, _}) when Hostname =/= disable -> + verify_hostname(Hostname, Customize, Cert, UserState); validate(_, valid_peer, UserState) -> {valid, UserState}. @@ -333,12 +333,12 @@ new_trusteded_chain(DerCert, [_ | Rest]) -> new_trusteded_chain(_, []) -> unknown_ca. -verify_hostname({fallback, Hostname}, Cert, UserState) when is_list(Hostname) -> - case public_key:pkix_verify_hostname(Cert, [{dns_id, Hostname}]) of +verify_hostname({fallback, Hostname}, Customize, Cert, UserState) when is_list(Hostname) -> + case public_key:pkix_verify_hostname(Cert, [{dns_id, Hostname}], Customize) of true -> {valid, UserState}; false -> - case public_key:pkix_verify_hostname(Cert, [{ip, Hostname}]) of + case public_key:pkix_verify_hostname(Cert, [{ip, Hostname}], Customize) of true -> {valid, UserState}; false -> @@ -346,16 +346,16 @@ verify_hostname({fallback, Hostname}, Cert, UserState) when is_list(Hostname) -> end end; -verify_hostname({fallback, Hostname}, Cert, UserState) -> - case public_key:pkix_verify_hostname(Cert, [{ip, Hostname}]) of +verify_hostname({fallback, Hostname}, Customize, Cert, UserState) -> + case public_key:pkix_verify_hostname(Cert, [{ip, Hostname}], Customize) of true -> {valid, UserState}; false -> {fail, {bad_cert, hostname_check_failed}} end; -verify_hostname(Hostname, Cert, UserState) -> - case public_key:pkix_verify_hostname(Cert, [{dns_id, Hostname}]) of +verify_hostname(Hostname, Customize, Cert, UserState) -> + case public_key:pkix_verify_hostname(Cert, [{dns_id, Hostname}], Customize) of true -> {valid, UserState}; false -> diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index 3f8b9a8a9b..c5b5b76f05 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -43,7 +43,7 @@ filter/3, filter_suites/1, filter_suites/2, hash_algorithm/1, sign_algorithm/1, is_acceptable_hash/2, is_fallback/1, random_bytes/1, calc_mac_hash/4, - is_stream_ciphersuite/1]). + is_stream_ciphersuite/1, suite_to_str/1]). -export_type([cipher_suite/0, erl_cipher_suite/0, old_erl_cipher_suite/0, openssl_cipher_suite/0, @@ -1877,6 +1877,32 @@ suite(#{key_exchange := dhe_rsa, prf := sha256}) -> ?TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256. + +%%-------------------------------------------------------------------- +-spec suite_to_str(erl_cipher_suite()) -> string(). +%% +%% Description: Return the string representation of a cipher suite. +%%-------------------------------------------------------------------- +suite_to_str(#{key_exchange := null, + cipher := null, + mac := null, + prf := null}) -> + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; +suite_to_str(#{key_exchange := Kex, + cipher := Cipher, + mac := aead, + prf := PRF}) -> + "TLS_" ++ string:to_upper(atom_to_list(Kex)) ++ + "_WITH_" ++ string:to_upper(atom_to_list(Cipher)) ++ + "_" ++ string:to_upper(atom_to_list(PRF)); +suite_to_str(#{key_exchange := Kex, + cipher := Cipher, + mac := Mac}) -> + "TLS_" ++ string:to_upper(atom_to_list(Kex)) ++ + "_WITH_" ++ string:to_upper(atom_to_list(Cipher)) ++ + "_" ++ string:to_upper(atom_to_list(Mac)). + + %%-------------------------------------------------------------------- -spec openssl_suite(openssl_cipher_suite()) -> cipher_suite(). %% diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index ebbb633b22..71eeb00183 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -345,6 +345,7 @@ certify(#certificate{asn1_certificates = ASN1Certs}, CertDbHandle, CertDbRef, Opts#ssl_options.partial_chain), ValidationFunAndState = validation_fun_and_state(Opts#ssl_options.verify_fun, Role, CertDbHandle, CertDbRef, ServerName, + Opts#ssl_options.customize_hostname_check, Opts#ssl_options.crl_check, CRLDbHandle, CertPath), case public_key:pkix_path_validation(TrustedCert, CertPath, @@ -1243,7 +1244,7 @@ certificate_authorities_from_db(_CertDbHandle, {extracted, CertDbData}) -> %%-------------Handle handshake messages -------------------------------- validation_fun_and_state({Fun, UserState0}, Role, CertDbHandle, CertDbRef, - ServerNameIndication, CRLCheck, CRLDbHandle, CertPath) -> + ServerNameIndication, CustomizeHostCheck, CRLCheck, CRLDbHandle, CertPath) -> {fun(OtpCert, {extension, _} = Extension, {SslState, UserState}) -> case ssl_certificate:validate(OtpCert, Extension, @@ -1260,9 +1261,9 @@ validation_fun_and_state({Fun, UserState0}, Role, CertDbHandle, CertDbRef, (OtpCert, VerifyResult, {SslState, UserState}) -> apply_user_fun(Fun, OtpCert, VerifyResult, UserState, SslState, CertPath) - end, {{Role, CertDbHandle, CertDbRef, ServerNameIndication, CRLCheck, CRLDbHandle}, UserState0}}; + end, {{Role, CertDbHandle, CertDbRef, {ServerNameIndication, CustomizeHostCheck}, CRLCheck, CRLDbHandle}, UserState0}}; validation_fun_and_state(undefined, Role, CertDbHandle, CertDbRef, - ServerNameIndication, CRLCheck, CRLDbHandle, CertPath) -> + ServerNameIndication, CustomizeHostCheck, CRLCheck, CRLDbHandle, CertPath) -> {fun(OtpCert, {extension, _} = Extension, SslState) -> ssl_certificate:validate(OtpCert, Extension, @@ -1282,7 +1283,7 @@ validation_fun_and_state(undefined, Role, CertDbHandle, CertDbRef, ssl_certificate:validate(OtpCert, VerifyResult, SslState) - end, {Role, CertDbHandle, CertDbRef, ServerNameIndication, CRLCheck, CRLDbHandle}}. + end, {Role, CertDbHandle, CertDbRef, {ServerNameIndication, CustomizeHostCheck}, CRLCheck, CRLDbHandle}}. apply_user_fun(Fun, OtpCert, VerifyResult, UserState0, {_, CertDbHandle, CertDbRef, _, CRLCheck, CRLDbHandle} = SslState, CertPath) when diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl index 977d012fa7..b736047678 100644 --- a/lib/ssl/src/ssl_internal.hrl +++ b/lib/ssl/src/ssl_internal.hrl @@ -145,7 +145,8 @@ eccs, honor_ecc_order :: boolean(), max_handshake_size :: integer(), - handshake + handshake, + customize_hostname_check }). -record(socket_options, diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 162c63850f..e8fb25e0e4 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -108,7 +108,8 @@ basic_tests() -> clear_pem_cache, defaults, fallback, - cipher_format + cipher_format, + suite_to_str ]. basic_tests_tls() -> @@ -1227,7 +1228,27 @@ cipher_format(Config) when is_list(Config) -> ssl:close(Socket1), {ok, Socket2} = ssl:listen(0, [{ciphers, ssl:cipher_suites(openssl)}]), ssl:close(Socket2). - + +%%-------------------------------------------------------------------- +suite_to_str() -> + [{doc, "Test that the suite_to_str API works"}]. +suite_to_str(Config) when is_list(Config) -> + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" = + ssl:suite_to_str(#{key_exchange => null, + cipher => null, + mac => null, + prf => null}), + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" = + ssl:suite_to_str(#{key_exchange => ecdhe_ecdsa, + cipher => aes_128_gcm, + mac => aead, + prf => sha256}), + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256" = + ssl:suite_to_str(#{key_exchange => ecdh_rsa, + cipher => aes_128_cbc, + mac => sha256, + prf => sha256}). + %%-------------------------------------------------------------------- peername() -> diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl index 1de4c89d7f..dca25b774b 100644 --- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl +++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl @@ -87,7 +87,9 @@ tests() -> extended_key_usage_verify_server, critical_extension_verify_client, critical_extension_verify_server, - critical_extension_verify_none]. + critical_extension_verify_none, + customize_hostname_check + ]. error_handling_tests()-> [client_with_cert_cipher_suites_handshake, @@ -1145,6 +1147,58 @@ unknown_server_ca_accept_backwardscompatibility(Config) when is_list(Config) -> ssl_test_lib:close(Client). %%-------------------------------------------------------------------- + +customize_hostname_check() -> + [{doc,"Test option customize_hostname_check."}]. +customize_hostname_check(Config) when is_list(Config) -> + Ext = [#'Extension'{extnID = ?'id-ce-subjectAltName', + extnValue = [{dNSName, "*.example.org"}], + critical = false} + ], + {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_chain, + [[], + [], + [{extensions, Ext}] + ]}], + Config, "https_hostname_convention"), + ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config), + ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {ssl_test_lib, send_recv_result_active, []}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + CustomFun = public_key:pkix_verify_hostname_match_fun(https), + + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {ssl_test_lib, send_recv_result_active, []}}, + {options, + [{server_name_indication, "other.example.org"}, + {customize_hostname_check, + [{match_fun, CustomFun}]} | ClientOpts] + }]), + ssl_test_lib:check_result(Server, ok, Client, ok), + + Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}}, + + Client1 = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {ssl_test_lib, no_result, []}}, + {options, ClientOpts} + ]), + ssl_test_lib:check_result(Client1, {error, {tls_alert, "handshake failure"}}, + Server, {error, {tls_alert, "handshake failure"}}), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- diff --git a/lib/ssl/test/ssl_dist_bench_SUITE.erl b/lib/ssl/test/ssl_dist_bench_SUITE.erl index f827ea12bb..3c7904cf24 100644 --- a/lib/ssl/test/ssl_dist_bench_SUITE.erl +++ b/lib/ssl/test/ssl_dist_bench_SUITE.erl @@ -117,19 +117,14 @@ init_per_suite(Config) -> ?MODULE_STRING ++ " ROOT CA", CertOptions), SSLConf = [{verify, verify_peer}, - {fail_if_no_peer_cert, true}, {versions, [TLSVersion]}, {ciphers, [TLSCipher]}], ServerConf = - [{verify_fun, - {fun inet_tls_dist:verify_client/3, - fun inet_tls_dist:cert_nodes/1}} - | SSLConf], - ClientConf = - [{verify_fun, - {fun inet_tls_dist:verify_server/3, - fun inet_tls_dist:cert_nodes/1}} + [{fail_if_no_peer_cert, true}, + {verify_fun, + {fun inet_tls_dist:verify_client/3,[]}} | SSLConf], + ClientConf = SSLConf, %% write_node_conf( NodeAConfFile, NodeA, ServerConf, ClientConf, @@ -291,6 +286,8 @@ roundtrip(A, B, Prefix, HA, HB) -> Rounds = 40000, [] = ssl_apply(HA, erlang, nodes, []), [] = ssl_apply(HB, erlang, nodes, []), + ok = ssl_apply(HA, net_kernel, allow, [[B]]), + ok = ssl_apply(HB, net_kernel, allow, [[A]]), Time = ssl_apply(HA, fun () -> roundtrip_runner(A, B, Rounds) end), [B] = ssl_apply(HA, erlang, nodes, []), [A] = ssl_apply(HB, erlang, nodes, []), diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk index 10be907b4f..eb85a55717 100644 --- a/lib/ssl/vsn.mk +++ b/lib/ssl/vsn.mk @@ -1 +1 @@ -SSL_VSN = 9.0 +SSL_VSN = 8.2.6 diff --git a/lib/stdlib/doc/src/calendar.xml b/lib/stdlib/doc/src/calendar.xml index 8f2b6b747a..6b4fa7f98a 100644 --- a/lib/stdlib/doc/src/calendar.xml +++ b/lib/stdlib/doc/src/calendar.xml @@ -323,7 +323,9 @@ <type name="rfc3339_string"/> <type name="rfc3339_time_unit"/> <desc> - <p>Converts an RFC 3339 timestamp into system time.</p> + <p>Converts an RFC 3339 timestamp into system time. The data format + of RFC 3339 timestamps is described by + <url href="https://www.ietf.org/rfc/rfc3339.txt">RFC 3339</url>.</p> <p>Valid option:</p> <taglist> <tag><c>{unit, Unit}</c></tag> @@ -378,7 +380,10 @@ <type name="rfc3339_string"/> <type name="rfc3339_time_unit"/> <desc> - <p>Converts a system time into RFC 3339 timestamp.</p> + <p>Converts a system time into an RFC 3339 timestamp. The data format + of RFC 3339 timestamps is described by + <url href="https://www.ietf.org/rfc/rfc3339.txt">RFC 3339</url>. + The data format of offsets is also described by RFC 3339.</p> <p>Valid options:</p> <taglist> <tag><c>{offset, Offset}</c></tag> diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml index 305376a425..1995262145 100644 --- a/lib/stdlib/doc/src/ets.xml +++ b/lib/stdlib/doc/src/ets.xml @@ -49,14 +49,16 @@ associated with each key. A <c>bag</c> or <c>duplicate_bag</c> table can have many objects associated with each key.</p> + <marker id="max_ets_tables"></marker> <note> <p> The number of tables stored at one Erlang node <em>used</em> to be limited. This is no longer the case (except by memory usage). The previous default limit was about 1400 tables and could be increased by setting the environment variable - <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang runtime - system. This hard limit has been removed, but it is currently + <c>ERL_MAX_ETS_TABLES</c> or the command line option + <seealso marker="erts:erl#+e"><c>+e</c></seealso> before starting the + Erlang runtime system. This hard limit has been removed, but it is currently useful to set the <c>ERL_MAX_ETS_TABLES</c> anyway. It should be set to an approximate of the maximum amount of tables used. This since an internal table for named tables is sized using this value. If diff --git a/lib/stdlib/doc/src/gen_event.xml b/lib/stdlib/doc/src/gen_event.xml index 51378a6b73..6170801e87 100644 --- a/lib/stdlib/doc/src/gen_event.xml +++ b/lib/stdlib/doc/src/gen_event.xml @@ -207,7 +207,7 @@ gen_event:stop -----> Module:terminate/2 </item> <item> <p>If the event handler is deleted later, the event manager - sends a message<c>{gen_event_EXIT,Handler,Reason}</c> to + sends a message <c>{gen_event_EXIT,Handler,Reason}</c> to the calling process. <c>Reason</c> is one of the following:</p> <list type="bulleted"> <item> diff --git a/lib/stdlib/doc/src/io.xml b/lib/stdlib/doc/src/io.xml index f1037ec76b..d4a2713840 100644 --- a/lib/stdlib/doc/src/io.xml +++ b/lib/stdlib/doc/src/io.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2017</year> + <year>1996</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -332,11 +332,22 @@ Here T = [{attributes,[[{id,age,1.5}, {tag,{'PRIVATE',3}}, {mode,implicit}] ok</pre> + + <p>As from Erlang/OTP 21.0, a field width of value + <c>0</c> can be used for specifying that a line is + infinitely long, which means that no line breaks + are inserted. For example:</p> + + <pre> +5> <input>io:fwrite("~0p~n", [lists:seq(1, 30)]).</input> +[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30] +ok</pre> + <p>When the modifier <c>l</c> is specified, no detection of printable character lists takes place, for example:</p> <pre> -5> <input>S = [{a,"a"}, {b, "b"}].</input> -6> <input>io:fwrite("~15p~n", [S]).</input> +6> <input>S = [{a,"a"}, {b, "b"}], + io:fwrite("~15p~n", [S]).</input> [{a,"a"}, {b,"b"}] ok diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml index b925fa3b02..e26c4aba74 100644 --- a/lib/stdlib/doc/src/notes.xml +++ b/lib/stdlib/doc/src/notes.xml @@ -31,399 +31,6 @@ </header> <p>This document describes the changes made to the STDLIB application.</p> -<section><title>STDLIB 3.5</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p><c>gen_statem</c> improvements.</p> <p> When using an - exception that is valid but not allowed in a state enter - call, the reason has been changed from - <c>{bad_action_from_state_function,Action}</c> to - <c>{bad_state_enter_action_from_state_function,Action}</c>. - </p><p> Timer parsing has been improved. Many erroneous - timeout tuples was not handled correctly. </p><p> The - documentation has been updated, in particular the User's - Guide and the pointer to it from the Reference Manual is - much more obvious. </p> - <p> - Own Id: OTP-14015</p> - </item> - <item> - <p> - The type specifications for <c>file:posix/0</c> and - <c>inet:posix/0</c> have been updated according to which - errors file and socket operations should be able to - return.</p> - <p> - Own Id: OTP-14019 Aux Id: ERL-550 </p> - </item> - <item> - <p> File operations used to accept <seealso - marker="kernel:file#type-name_all">filenames</seealso> - containing null characters (integer value zero). This - caused the name to be truncated and in some cases - arguments to primitive operations to be mixed up. - Filenames containing null characters inside the filename - are now <em>rejected</em> and will cause primitive file - operations to fail. </p> <p> Also environment variable - operations used to accept <seealso - marker="kernel:os#type-env_var_name">names</seealso> and - <seealso - marker="kernel:os#type-env_var_value">values</seealso> of - environment variables containing null characters (integer - value zero). This caused operations to silently produce - erroneous results. Environment variable names and values - containing null characters inside the name or value are - now <em>rejected</em> and will cause environment variable - operations to fail. </p> <p>Primitive environment - variable operations also used to accept the <c>$=</c> - character in environment variable names causing various - problems. <c>$=</c> characters in environment variable - names are now also <em>rejected</em>. </p> <p>Also - <seealso - marker="kernel:os#cmd/1"><c>os:cmd/1</c></seealso> now - reject null characters inside its <seealso - marker="kernel:os#type-os_command">command</seealso>. - </p> <p><seealso - marker="erts:erlang#open_port/2"><c>erlang:open_port/2</c></seealso> - will also reject null characters inside the port name - from now on.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14543 Aux Id: ERL-370 </p> - </item> - <item> - <p> Make <c>io_lib:unscan_format/1</c> work with pad char - and default precision. </p> - <p> - Own Id: OTP-14958 Aux Id: PR-1735 </p> - </item> - <item> - <p> The control sequence modifiers <c>t</c> and <c>l</c> - can be used together in the same control sequence which - makes it possible to have Unicode atoms and no detection - of printable character lists at the same time. </p> - <p> - Own Id: OTP-14971 Aux Id: PR-1743 </p> - </item> - <item> - <p> Fix a bug in the Erlang code linter: the check of - guard expressions no longer returns <c>false</c> if the - map syntax is used. The bug affected the Erlang shell, - the Debugger, and other modules evaluating abstract code. - </p> - <p> - Own Id: OTP-15035 Aux Id: ERL-613 </p> - </item> - <item> - <p> - A sys debug fun of type {Fun,State} should not be - possible to install twice. This was, however, possible if - the current State was 'undefined', which was mistaken for - non-existing fun. This has been corrected.</p> - <p> - Own Id: OTP-15049</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - The <c>gen_server</c> has gotten a new callback - <c>handle_continue/2</c> for check pointing the state. - This is useful at least when implementing behaviours on - top of <c>gen_server</c> and for some start up scenarios.</p> - <p> - Own Id: OTP-13019 Aux Id: PR-1490 </p> - </item> - <item> - <p> The semantics of timeout parameter - <c>{clean_timeout,infinity}</c> to - <c>gen_statem:call/3</c> has been changed to use a proxy - process for the call. With this change - <c>clean_timeout</c> implicates a proxy process with no - exceptions. This may be a hard to observe - incompatibility: in the presence of network problems a - late reply could arrive in the caller's message queue - when catching errors. That will not happen after this - correction. </p><p> The semantics of timeout parameter - <c>infinity</c> has not been changed. </p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13073 Aux Id: PR-1595 </p> - </item> - <item> - <p>A new logging API is added to Erlang/OTP, see the - <seealso - marker="kernel:logger"><c>logger(3)</c></seealso> manual - page, and section <seealso - marker="kernel:logger_chapter">Logging</seealso> in the - Kernel User's Guide.</p> - <p>Calls to <c>error_logger</c> are automatically - redirected to the new API, and legacy error logger event - handlers can still be used. It is, however, recommended - to use the Logger API directly when writing new code.</p> - <p>Notice the following potential incompatibilities:</p> - <list> <item><p>Kernel configuration parameters - <c>error_logger</c> still works, but is overruled if the - default handler's output destination is configured with - Kernel configuration parameter <c>logger</c>.</p> <p>In - general, parameters for configuring error logger are - overwritten by new parameters for configuring - Logger.</p></item> <item><p>The concept of SASL error - logging is deprecated, meaning that by default the SASL - application does not affect which log events are - logged.</p> <p>By default, supervisor reports and crash - reports are logged by the default Logger handler started - by Kernel, and end up at the same destination (terminal - or file) as other standard log event from Erlang/OTP.</p> - <p>Progress reports are not logged by default, but can be - enabled with the Kernel configuration parameter - <c>logger_progress_reports</c>.</p> <p>To obtain - backwards compatibility with the SASL error logging - functionality from earlier releases, set Kernel - configuration parameter <c>logger_sasl_compatible</c> to - <c>true</c>. This prevents the default Logger handler - from logging any supervisor-, crash-, or progress - reports. Instead, SASL adds a separate Logger handler - during application start, which takes care of these log - events. The SASL configuration parameters - <c>sasl_error_logger</c> and <c>sasl_errlog_type</c> - specify the destination (terminal or file) and severity - level to log for these events.</p></item></list> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13295</p> - </item> - <item> - <p> Add functions - <c>calendar:system_time_to_local_time/2</c> and - <c>calendar:system_time_to_universal_time/2</c>. </p> - <p> - Own Id: OTP-13413</p> - </item> - <item> - <p> Functions <c>rand:uniform_real/0</c> and - <c>rand:uniform_real_s/1</c> have been added. They - produce uniformly distributed numbers in the range <c>0.0 - =< X < 1.0</c> that are as close to random real - numbers as Normalized IEEE 754 Double Precision allows. - Because the random real number exactly <c>0.0</c> is - infinitely improbable they will never return exactly - <c>0.0</c>. </p><p> These properties are useful when you - need to call for example <c>math:log(X)</c> or <c>1 / - X</c> on a random value <c>X</c>, since that will never - fail with a number from these new functions. </p> - <p> - Own Id: OTP-13764 Aux Id: PR-1574 </p> - </item> - <item> - <p> - Added maps:iterator/0 and maps:next/1 to be used for - iterating over the key-value associations in a map.</p> - <p> - Own Id: OTP-14012</p> - </item> - <item> - <p>Changed the default behaviour of <c>.erlang</c> - loading: <c>.erlang</c> is no longer loaded from the - current directory. <c>c:erlangrc(PathList)</c> can be - used to search and load an <c>.erlang</c> file from user - specified directories.</p> <p><c>escript</c>, - <c>erlc</c>, <c>dialyzer</c> and <c>typer</c> no longer - load an <c>.erlang</c> at all.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14439</p> - </item> - <item> - <p> - Added new uri_string module to stdlib for handling URIs - (RFC 3986).</p> - <p> - Own Id: OTP-14496</p> - </item> - <item> - <p> - Update Unicode specification to version 10.0.</p> - <p> - Own Id: OTP-14503</p> - </item> - <item> - <p><c>filelib:wildcard()</c> now allows characters with a - special meaning to be escaped using backslashes.</p> - <p>This is an incompatible change, but note that the use - of backslashes in wildcards would already work - differently on Windows and Unix. Existing calls to - <c>filelib:wildcard()</c> needs to be updated. On - Windows, directory separators must always be written as a - slash.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14577</p> - </item> - <item> - <p> - The supervisor now stores its child specifications in a - map instead of a list. This causes a significant - improvement when starting many children under a - non-simple_one_for_one supervisor.</p> - <p> - Own Id: OTP-14586</p> - </item> - <item> - <p> The <c>base64</c> module is optimized. </p> <p> Note - that the functions <c>encode/1</c>, <c>decode/1</c>, and - <c>mime_decode/1</c> fail unless called with an argument - of the documented type. They used to accept any - <c>iodata()</c>. </p> - <p> - Own Id: OTP-14624 Aux Id: PR-1565 </p> - </item> - <item> - <p> Add function <c>lists:search/2</c>. </p> - <p> - Own Id: OTP-14675 Aux Id: PR-102 </p> - </item> - <item> - <p> - uri_string module extended with functions for handling - application/x-www-form-urlencoded query strings based on - the HTML5 specification.</p> - <p> - Own Id: OTP-14747</p> - </item> - <item> - <p> Add functions - <c>calendar:rfc3339_to_system_time/1,2</c> and - <c>calendar:system_time_to_rfc3339/1,2</c>. </p> - <p> - Own Id: OTP-14764</p> - </item> - <item> - <p> The stack traces returned by the functions of the - <c>erl_eval</c> module more accurately reflect where the - exception occurred. </p> - <p> - Own Id: OTP-14826 Aux Id: PR 1540 </p> - </item> - <item> - <p> Add options <c>atime</c>, <c>mtime</c>, <c>ctime</c>, - <c>uid</c>, and <c>gid</c> to the <c>erl_tar:add/3,4</c> - functions. </p> - <p> - Own Id: OTP-14834 Aux Id: PR 1608 </p> - </item> - <item> - <p>Added <c>ets:whereis/1</c> for retrieving the table - identifier of a named table.</p> - <p> - Own Id: OTP-14884</p> - </item> - <item> - <p> - Improved URI normalization functions in the uri_string - module.</p> - <p> - Own Id: OTP-14910</p> - </item> - <item> - <p> The new functions <c>io_lib:fwrite/3</c> and - <c>io_lib:format/3</c> take a third argument, an option - list. The only option is <c>chars_limit</c>, which is - used for limiting the number of returned characters. The - limit is soft, which means that the number of returned - characters exceeds the limit with at most a smallish - amount. If the limit is set, the functions - <c>format/3</c> and <c>fwrite/3</c> try to distribute the - number of characters evenly over the control sequences - <c>pPswW</c>. Furthermore, the control sequences - <c>pPwP</c> try to distribute the number of characters - evenly over substructures. </p> <p> A modification of the - control sequences <c>pPwW</c> is that even if there is no - limit on the number of returned characters, all - associations of a map are printed to the same depth. The - aim is to give a more consistent output as the order of - map keys is not defined. As before, if the depth is less - than the number of associations of a map, the selection - of associations to print is arbitrary. </p> - <p> - Own Id: OTP-14983</p> - </item> - <item> - <p> Add functions <c>ordsets:is_empty/1</c> and - <c>sets:is_empty/1</c>. </p> - <p> - Own Id: OTP-14996 Aux Id: ERL-557, PR-1703 </p> - </item> - <item> - <p> - Improve performance of <c>string:uppercase/1</c>, - <c>string:lowercase/1</c> and <c>string:casefold/1</c> - when handling ASCII characters.</p> - <p> - Own Id: OTP-14998</p> - </item> - <item> - <p>External funs with literal values for module, name, - and arity (e.g. <c>erlang:abs/1</c>) are now treated as - literals. That means more efficient code that produces - less garbage on the heap.</p> - <p> - Own Id: OTP-15003</p> - </item> - <item> - <p> - sys:statistics(Pid,get) did not report 'out' messages - from gen_server. This is now corrected.</p> - <p> - Own Id: OTP-15047</p> - </item> - <item> - <p> - A sys debug function can now have the format - {Id,Fun,State} in addition to the old {Fun,State}. This - allows installing multiple instances of a debug fun.</p> - <p> - Own Id: OTP-15048</p> - </item> - <item> - <p> The <c>lib</c> module is removed:</p> <list - type="bulleted"> <item><c>lib:error_message/2</c> is - removed.</item> <item><c>lib:flush_receive/0</c> is - removed.</item> <item><c>lib:nonl/1</c> is - removed.</item> <item><c>lib:progname/0</c> is replaced - by <c>ct:get_progname/0</c>.</item> - <item><c>lib:send/2</c> is removed.</item> - <item><c>lib:sendw/2</c> is removed.</item> </list> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-15072 Aux Id: PR 1786 </p> - </item> - <item> - <p> - Function <c>ets:delete_all_objects/1</c> now yields the - scheduler thread for large tables that take significant - time to clear. This to improve real time characteristics - of other runnable processes.</p> - <p> - Own Id: OTP-15078</p> - </item> - </list> - </section> - -</section> - <section><title>STDLIB 3.4.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/stdlib/src/array.erl b/lib/stdlib/src/array.erl index a237eaa489..939b1fb488 100644 --- a/lib/stdlib/src/array.erl +++ b/lib/stdlib/src/array.erl @@ -290,7 +290,7 @@ new(Size, Fixed, Default) -> end, #array{size = Size, max = M, default = Default, elements = E}. --spec find_max(integer(), integer()) -> integer(). +-spec find_max(integer(), non_neg_integer()) -> non_neg_integer(). find_max(I, M) when I >= M -> find_max(I, ?extend(M)); diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl index 0f6d48b9a3..31c0e60fe1 100644 --- a/lib/stdlib/src/erl_eval.erl +++ b/lib/stdlib/src/erl_eval.erl @@ -29,7 +29,7 @@ -export([new_bindings/0,bindings/1,binding/2,add_binding/3,del_binding/2]). -export([extended_parse_exprs/1, extended_parse_term/1, subst_values_for_vars/2]). --export([is_constant_expr/1, partial_eval/1]). +-export([is_constant_expr/1, partial_eval/1, eval_str/1]). %% Is used by standalone Erlang (escript). %% Also used by shell.erl. @@ -1557,6 +1557,50 @@ ev_expr({cons,_,H,T}) -> [ev_expr(H) | ev_expr(T)]. %% true = erl_internal:guard_bif(F, length(As)), %% apply(erlang, F, [ev_expr(X) || X <- As]); +%% eval_str(InStr) -> {ok, OutStr} | {error, ErrStr'} +%% InStr must represent a body +%% Note: If InStr is a binary it has to be a Latin-1 string. +%% If you have a UTF-8 encoded binary you have to call +%% unicode:characters_to_list/1 before the call to eval_str(). + +-define(result(F,D), lists:flatten(io_lib:format(F, D))). + +-spec eval_str(string() | unicode:latin1_binary()) -> + {'ok', string()} | {'error', string()}. + +eval_str(Str) when is_list(Str) -> + case erl_scan:tokens([], Str, 0) of + {more, _} -> + {error, "Incomplete form (missing .<cr>)??"}; + {done, {ok, Toks, _}, Rest} -> + case all_white(Rest) of + true -> + case erl_parse:parse_exprs(Toks) of + {ok, Exprs} -> + case catch erl_eval:exprs(Exprs, erl_eval:new_bindings()) of + {value, Val, _} -> + {ok, Val}; + Other -> + {error, ?result("*** eval: ~p", [Other])} + end; + {error, {_Line, Mod, Args}} -> + Msg = ?result("*** ~ts",[Mod:format_error(Args)]), + {error, Msg} + end; + false -> + {error, ?result("Non-white space found after " + "end-of-form :~ts", [Rest])} + end + end; +eval_str(Bin) when is_binary(Bin) -> + eval_str(binary_to_list(Bin)). + +all_white([$\s|T]) -> all_white(T); +all_white([$\n|T]) -> all_white(T); +all_white([$\t|T]) -> all_white(T); +all_white([]) -> true; +all_white(_) -> false. + ret_expr(_Old, New) -> %% io:format("~w: reduced ~s => ~s~n", %% [line(Old), erl_pp:expr(Old), erl_pp:expr(New)]), diff --git a/lib/stdlib/src/gen_event.erl b/lib/stdlib/src/gen_event.erl index 3ee2031d02..8213282867 100644 --- a/lib/stdlib/src/gen_event.erl +++ b/lib/stdlib/src/gen_event.erl @@ -589,7 +589,7 @@ server_update(Handler1, Func, Event, SName) -> ?LOG_WARNING(#{label=>{gen_event,no_handle_info}, module=>Mod1, message=>Event}, - #{domain=>[beam,erlang,otp], + #{domain=>[otp], report_cb=>fun gen_event:format_log/1, error_logger=>#{tag=>warning_msg}}), % warningmap?? {ok, Handler1}; @@ -751,7 +751,7 @@ report_error(Handler, Reason, State, LastIn, SName) -> state=>format_status(terminate,Handler#handler.module, get(),State), reason=>Reason}, - #{domain=>[beam,erlang,otp], + #{domain=>[otp], report_cb=>fun gen_event:format_log/1, error_logger=>#{tag=>error}}). diff --git a/lib/stdlib/src/gen_fsm.erl b/lib/stdlib/src/gen_fsm.erl index 1646186761..caaaf8fa2e 100644 --- a/lib/stdlib/src/gen_fsm.erl +++ b/lib/stdlib/src/gen_fsm.erl @@ -505,7 +505,7 @@ handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time, HibernateAfterTi ?LOG_WARNING(#{label=>{gen_fsm,no_handle_info}, module=>Mod, message=>Msg}, - #{domain=>[beam,erlang,otp], + #{domain=>[otp], report_cb=>fun gen_fsm:format_log/1, error_logger=>#{tag=>warning_msg}}), loop(Parent, Name, StateName, StateData, Mod, infinity, HibernateAfterTimeout, []); @@ -616,7 +616,7 @@ error_info(Reason, Name, Msg, StateName, StateData, Debug) -> state_name=>StateName, state_data=>StateData, reason=>Reason}, - #{domain=>[beam,erlang,otp], + #{domain=>[otp], report_cb=>fun gen_fsm:format_log/1, error_logger=>#{tag=>error}}), sys:print_log(Debug), diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl index 09f77c0810..342cc2a8e3 100644 --- a/lib/stdlib/src/gen_server.erl +++ b/lib/stdlib/src/gen_server.erl @@ -645,7 +645,7 @@ try_dispatch(Mod, Func, Msg, State) -> #{label=>{gen_server,no_handle_info}, module=>Mod, message=>Msg}, - #{domain=>[beam,erlang,otp], + #{domain=>[otp], report_cb=>fun gen_server:format_log/1, error_logger=>#{tag=>warning_msg}}), {ok, {noreply, State}}; @@ -891,7 +891,7 @@ error_info(Reason, Name, From, Msg, Mod, State, Debug) -> state=>format_status(terminate, Mod, get(), State), reason=>Reason, client_info=>client_stacktrace(From)}, - #{domain=>[beam,erlang,otp], + #{domain=>[otp], report_cb=>fun gen_server:format_log/1, error_logger=>#{tag=>error}}), sys:print_log(Debug), diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl index b36b8cd5a5..19d22f24f0 100644 --- a/lib/stdlib/src/gen_statem.erl +++ b/lib/stdlib/src/gen_statem.erl @@ -1900,7 +1900,7 @@ error_info( state_enter=>StateEnter, state=>format_status(terminate, get(), S), reason=>{Class,Reason,Stacktrace}}, - #{domain=>[beam,erlang,otp], + #{domain=>[otp], report_cb=>fun gen_statem:format_log/1, error_logger=>#{tag=>error}}). diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl index f510f61e9f..5d5773c80c 100644 --- a/lib/stdlib/src/io.erl +++ b/lib/stdlib/src/io.erl @@ -86,7 +86,16 @@ put_chars(Chars) -> CharData :: unicode:chardata(). put_chars(Io, Chars) -> - o_request(Io, {put_chars,unicode,Chars}, put_chars). + put_chars(Io, unicode, Chars). + +%% This function is here to make the erlang:raise in o_request actually raise to +%% a valid function. +-spec put_chars(IoDevice, Encoding, CharData) -> 'ok' when + IoDevice :: device(), + Encoding :: unicode, + CharData :: unicode:chardata(). +put_chars(Io, Encoding, Chars) -> + o_request(Io, {put_chars,Encoding,Chars}, put_chars). -spec nl() -> 'ok'. diff --git a/lib/stdlib/src/io_lib_pretty.erl b/lib/stdlib/src/io_lib_pretty.erl index 3d5a979b3e..dca1b37ef3 100644 --- a/lib/stdlib/src/io_lib_pretty.erl +++ b/lib/stdlib/src/io_lib_pretty.erl @@ -131,6 +131,8 @@ print(Term, Col, Ll, D, M0, T, RecDefFun, Enc, Str) when is_tuple(Term); %% use Len as CHAR_MAX if M0 = -1 M = max_cs(M0, Len), if + Ll =:= 0 -> + write(If); Len < Ll - Col, Len =< M -> %% write the whole thing on a single line when there is room write(If); diff --git a/lib/stdlib/src/maps.erl b/lib/stdlib/src/maps.erl index a13f340709..a1634547f3 100644 --- a/lib/stdlib/src/maps.erl +++ b/lib/stdlib/src/maps.erl @@ -249,7 +249,7 @@ fold(Fun,Init,Map) when is_function(Fun,3), is_map(Map) -> fold(Fun,Init,Iterator) when is_function(Fun,3), ?IS_ITERATOR(Iterator) -> fold_1(Fun,Init,Iterator); fold(Fun,Init,Map) -> - erlang:error(error_type(Map),[Fun,Init,Map]). + erlang:error(error_type_iter(Map),[Fun,Init,Map]). fold_1(Fun, Acc, Iter) -> case next(Iter) of @@ -272,7 +272,7 @@ map(Fun,Map) when is_function(Fun, 2), is_map(Map) -> map(Fun,Iterator) when is_function(Fun, 2), ?IS_ITERATOR(Iterator) -> maps:from_list(map_1(Fun, Iterator)); map(Fun,Map) -> - erlang:error(error_type(Map),[Fun,Map]). + erlang:error(error_type_iter(Map),[Fun,Map]). map_1(Fun, Iter) -> case next(Iter) of @@ -342,5 +342,8 @@ with(Ks,M) -> erlang:error(error_type(M),[Ks,M]). -error_type(M) when is_map(M); ?IS_ITERATOR(M) -> badarg; +error_type(M) when is_map(M) -> badarg; error_type(V) -> {badmap, V}. + +error_type_iter(M) when is_map(M); ?IS_ITERATOR(M) -> badarg; +error_type_iter(V) -> {badmap, V}. diff --git a/lib/stdlib/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl index 5f14e78f91..cca1628aba 100644 --- a/lib/stdlib/src/proc_lib.erl +++ b/lib/stdlib/src/proc_lib.erl @@ -508,7 +508,7 @@ crash_report(Class, Reason, StartF, Stacktrace) -> ?LOG_ERROR(#{label=>{proc_lib,crash}, report=>[my_info(Class, Reason, StartF, Stacktrace), linked_info(self())]}, - #{domain=>[beam,erlang,otp,sasl], + #{domain=>[otp,sasl], report_cb=>fun proc_lib:report_cb/1, logger_formatter=>#{title=>"CRASH REPORT"}, error_logger=>#{tag=>error_report,type=>crash_report}}). diff --git a/lib/stdlib/src/string.erl b/lib/stdlib/src/string.erl index f5d271c06d..cf48b882e4 100644 --- a/lib/stdlib/src/string.erl +++ b/lib/stdlib/src/string.erl @@ -691,9 +691,9 @@ uppercase_list(CPs0, Changed) -> uppercase_bin(CP1, <<CP2/utf8, Bin/binary>>, _Changed) when $a =< CP1, CP1 =< $z, CP2 < 256 -> [CP1-32|uppercase_bin(CP2, Bin, true)]; -uppercase_bin(CP1, <<CP2/utf8, Bin/binary>>, _Changed) +uppercase_bin(CP1, <<CP2/utf8, Bin/binary>>, Changed) when CP1 < 128, CP2 < 256 -> - [CP1|uppercase_bin(CP2, Bin, false)]; + [CP1|uppercase_bin(CP2, Bin, Changed)]; uppercase_bin(CP1, Bin, Changed) -> case unicode_util:uppercase([CP1|Bin]) of [CP1|CPs] -> @@ -732,9 +732,9 @@ lowercase_list(CPs0, Changed) -> lowercase_bin(CP1, <<CP2/utf8, Bin/binary>>, _Changed) when $A =< CP1, CP1 =< $Z, CP2 < 256 -> [CP1+32|lowercase_bin(CP2, Bin, true)]; -lowercase_bin(CP1, <<CP2/utf8, Bin/binary>>, _Changed) +lowercase_bin(CP1, <<CP2/utf8, Bin/binary>>, Changed) when CP1 < 128, CP2 < 256 -> - [CP1|lowercase_bin(CP2, Bin, false)]; + [CP1|lowercase_bin(CP2, Bin, Changed)]; lowercase_bin(CP1, Bin, Changed) -> case unicode_util:lowercase([CP1|Bin]) of [CP1|CPs] -> @@ -773,9 +773,9 @@ casefold_list(CPs0, Changed) -> casefold_bin(CP1, <<CP2/utf8, Bin/binary>>, _Changed) when $A =< CP1, CP1 =< $Z, CP2 < 256 -> [CP1+32|casefold_bin(CP2, Bin, true)]; -casefold_bin(CP1, <<CP2/utf8, Bin/binary>>, _Changed) +casefold_bin(CP1, <<CP2/utf8, Bin/binary>>, Changed) when CP1 < 128, CP2 < 256 -> - [CP1|casefold_bin(CP2, Bin, false)]; + [CP1|casefold_bin(CP2, Bin, Changed)]; casefold_bin(CP1, Bin, Changed) -> case unicode_util:casefold([CP1|Bin]) of [CP1|CPs] -> diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl index eb46ac611a..9b6c2a5f0b 100644 --- a/lib/stdlib/src/supervisor.erl +++ b/lib/stdlib/src/supervisor.erl @@ -43,7 +43,7 @@ {errorContext,Error}, {reason,Reason}, {offender,extract_child(Child)}]}, - #{domain=>[beam,erlang,otp,sasl], + #{domain=>[otp,sasl], report_cb=>fun logger:format_otp_report/1, logger_formatter=>#{title=>"SUPERVISOR REPORT"}, error_logger=>#{tag=>error_report, @@ -580,7 +580,7 @@ handle_info({'EXIT', Pid, Reason}, State) -> handle_info(Msg, State) -> ?LOG_ERROR("Supervisor received unexpected message: ~tp~n",[Msg], - #{domain=>[beam,erlang,otp], + #{domain=>[otp], error_logger=>#{tag=>error}}), {noreply, State}. @@ -1419,7 +1419,7 @@ report_progress(Child, SupName) -> ?LOG_INFO(#{label=>{supervisor,progress}, report=>[{supervisor,SupName}, {started,extract_child(Child)}]}, - #{domain=>[beam,erlang,otp,sasl], + #{domain=>[otp,sasl], report_cb=>fun logger:format_otp_report/1, logger_formatter=>#{title=>"PROGRESS REPORT"}, error_logger=>#{tag=>info_report,type=>progress}}). diff --git a/lib/stdlib/src/supervisor_bridge.erl b/lib/stdlib/src/supervisor_bridge.erl index 39372935fa..2db0a895d6 100644 --- a/lib/stdlib/src/supervisor_bridge.erl +++ b/lib/stdlib/src/supervisor_bridge.erl @@ -135,7 +135,7 @@ report_progress(Pid, Mod, StartArgs, SupName) -> report=>[{supervisor, SupName}, {started, [{pid, Pid}, {mfa, {Mod, init, [StartArgs]}}]}]}, - #{domain=>[beam,erlang,otp,sasl], + #{domain=>[otp,sasl], report_cb=>fun logger:format_otp_report/1, logger_formatter=>#{title=>"PROGRESS REPORT"}, error_logger=>#{tag=>info_report,type=>progress}}). @@ -146,7 +146,7 @@ report_error(Error, Reason, #state{name = Name, pid = Pid, mod = Mod}) -> {errorContext, Error}, {reason, Reason}, {offender, [{pid, Pid}, {mod, Mod}]}]}, - #{domain=>[beam,erlang,otp,sasl], + #{domain=>[otp,sasl], report_cb=>fun logger:format_otp_report/1, logger_formatter=>#{title=>"SUPERVISOR REPORT"}, error_logger=>#{tag=>error_report,type=>supervisor_report}}). diff --git a/lib/stdlib/src/uri_string.erl b/lib/stdlib/src/uri_string.erl index 28d36ea229..48cce90d68 100644 --- a/lib/stdlib/src/uri_string.erl +++ b/lib/stdlib/src/uri_string.erl @@ -297,7 +297,10 @@ NormalizedURI :: uri_string() | error(). normalize(URIMap) -> - normalize(URIMap, []). + try normalize(URIMap, []) + catch + throw:{error, Atom, RestData} -> {error, Atom, RestData} + end. -spec normalize(URI, Options) -> NormalizedURI when @@ -523,34 +526,34 @@ parse_relative_part(?STRING_REST("//", Rest), URI) -> {T, URI1} -> Userinfo = calculate_parsed_userinfo(Rest, T), URI2 = maybe_add_path(URI1), - URI2#{userinfo => decode_userinfo(Userinfo)} + URI2#{userinfo => Userinfo} catch throw:{_,_,_} -> {T, URI1} = parse_host(Rest, URI), Host = calculate_parsed_host_port(Rest, T), URI2 = maybe_add_path(URI1), - URI2#{host => decode_host(remove_brackets(Host))} + URI2#{host => remove_brackets(Host)} end; parse_relative_part(?STRING_REST($/, Rest), URI) -> {T, URI1} = parse_segment(Rest, URI), % path-absolute Path = calculate_parsed_part(Rest, T), - URI1#{path => decode_path(?STRING_REST($/, Path))}; + URI1#{path => ?STRING_REST($/, Path)}; parse_relative_part(?STRING_REST($?, Rest), URI) -> {T, URI1} = parse_query(Rest, URI), % path-empty ?query Query = calculate_parsed_query_fragment(Rest, T), URI2 = maybe_add_path(URI1), - URI2#{query => decode_query(Query)}; + URI2#{query => Query}; parse_relative_part(?STRING_REST($#, Rest), URI) -> {T, URI1} = parse_fragment(Rest, URI), % path-empty Fragment = calculate_parsed_query_fragment(Rest, T), URI2 = maybe_add_path(URI1), - URI2#{fragment => decode_fragment(Fragment)}; + URI2#{fragment => Fragment}; parse_relative_part(?STRING_REST(Char, Rest), URI) -> case is_segment_nz_nc(Char) of true -> {T, URI1} = parse_segment_nz_nc(Rest, URI), % path-noscheme Path = calculate_parsed_part(Rest, T), - URI1#{path => decode_path(?STRING_REST(Char, Path))}; + URI1#{path => ?STRING_REST(Char, Path)}; false -> throw({error,invalid_uri,[Char]}) end. @@ -593,11 +596,11 @@ parse_segment(?STRING_REST($/, Rest), URI) -> parse_segment(?STRING_REST($?, Rest), URI) -> {T, URI1} = parse_query(Rest, URI), % ?query Query = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{query => decode_query(Query)}}; + {Rest, URI1#{query => Query}}; parse_segment(?STRING_REST($#, Rest), URI) -> {T, URI1} = parse_fragment(Rest, URI), Fragment = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{fragment => decode_fragment(Fragment)}}; + {Rest, URI1#{fragment => Fragment}}; parse_segment(?STRING_REST(Char, Rest), URI) -> case is_pchar(Char) of true -> parse_segment(Rest, URI); @@ -616,11 +619,11 @@ parse_segment_nz_nc(?STRING_REST($/, Rest), URI) -> parse_segment_nz_nc(?STRING_REST($?, Rest), URI) -> {T, URI1} = parse_query(Rest, URI), % ?query Query = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{query => decode_query(Query)}}; + {Rest, URI1#{query => Query}}; parse_segment_nz_nc(?STRING_REST($#, Rest), URI) -> {T, URI1} = parse_fragment(Rest, URI), Fragment = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{fragment => decode_fragment(Fragment)}}; + {Rest, URI1#{fragment => Fragment}}; parse_segment_nz_nc(?STRING_REST(Char, Rest), URI) -> case is_segment_nz_nc(Char) of true -> parse_segment_nz_nc(Rest, URI); @@ -709,31 +712,31 @@ parse_hier(?STRING_REST("//", Rest), URI) -> try parse_userinfo(Rest, URI) of {T, URI1} -> Userinfo = calculate_parsed_userinfo(Rest, T), - {Rest, URI1#{userinfo => decode_userinfo(Userinfo)}} + {Rest, URI1#{userinfo => Userinfo}} catch throw:{_,_,_} -> {T, URI1} = parse_host(Rest, URI), Host = calculate_parsed_host_port(Rest, T), - {Rest, URI1#{host => decode_host(remove_brackets(Host))}} + {Rest, URI1#{host => remove_brackets(Host)}} end; parse_hier(?STRING_REST($/, Rest), URI) -> {T, URI1} = parse_segment(Rest, URI), % path-absolute Path = calculate_parsed_part(Rest, T), - {Rest, URI1#{path => decode_path(?STRING_REST($/, Path))}}; + {Rest, URI1#{path => ?STRING_REST($/, Path)}}; parse_hier(?STRING_REST($?, Rest), URI) -> {T, URI1} = parse_query(Rest, URI), % path-empty ?query Query = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{query => decode_query(Query)}}; + {Rest, URI1#{query => Query}}; parse_hier(?STRING_REST($#, Rest), URI) -> {T, URI1} = parse_fragment(Rest, URI), % path-empty Fragment = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{fragment => decode_fragment(Fragment)}}; + {Rest, URI1#{fragment => Fragment}}; parse_hier(?STRING_REST(Char, Rest), URI) -> % path-rootless case is_pchar(Char) of true -> % segment_nz {T, URI1} = parse_segment(Rest, URI), Path = calculate_parsed_part(Rest, T), - {Rest, URI1#{path => decode_path(?STRING_REST(Char, Path))}}; + {Rest, URI1#{path => ?STRING_REST(Char, Path)}}; false -> throw({error,invalid_uri,[Char]}) end; parse_hier(?STRING_EMPTY, URI) -> @@ -770,7 +773,7 @@ parse_userinfo(?CHAR($@), URI) -> parse_userinfo(?STRING_REST($@, Rest), URI) -> {T, URI1} = parse_host(Rest, URI), Host = calculate_parsed_host_port(Rest, T), - {Rest, URI1#{host => decode_host(remove_brackets(Host))}}; + {Rest, URI1#{host => remove_brackets(Host)}}; parse_userinfo(?STRING_REST(Char, Rest), URI) -> case is_userinfo(Char) of true -> parse_userinfo(Rest, URI); @@ -836,20 +839,25 @@ parse_host(?STRING_REST($:, Rest), URI) -> parse_host(?STRING_REST($/, Rest), URI) -> {T, URI1} = parse_segment(Rest, URI), % path-abempty Path = calculate_parsed_part(Rest, T), - {Rest, URI1#{path => decode_path(?STRING_REST($/, Path))}}; + {Rest, URI1#{path => ?STRING_REST($/, Path)}}; parse_host(?STRING_REST($?, Rest), URI) -> {T, URI1} = parse_query(Rest, URI), % path-empty ?query Query = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{query => decode_query(Query)}}; + {Rest, URI1#{query => Query}}; parse_host(?STRING_REST($[, Rest), URI) -> parse_ipv6_bin(Rest, [], URI); parse_host(?STRING_REST($#, Rest), URI) -> {T, URI1} = parse_fragment(Rest, URI), % path-empty Fragment = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{fragment => decode_fragment(Fragment)}}; + {Rest, URI1#{fragment => Fragment}}; parse_host(?STRING_REST(Char, Rest), URI) -> case is_digit(Char) of - true -> parse_ipv4_bin(Rest, [Char], URI); + true -> + try parse_ipv4_bin(Rest, [Char], URI) + catch + throw:{_,_,_} -> + parse_reg_name(?STRING_REST(Char, Rest), URI) + end; false -> parse_reg_name(?STRING_REST(Char, Rest), URI) end; parse_host(?STRING_EMPTY, URI) -> @@ -865,15 +873,15 @@ parse_reg_name(?STRING_REST($:, Rest), URI) -> parse_reg_name(?STRING_REST($/, Rest), URI) -> {T, URI1} = parse_segment(Rest, URI), % path-abempty Path = calculate_parsed_part(Rest, T), - {Rest, URI1#{path => decode_path(?STRING_REST($/, Path))}}; + {Rest, URI1#{path => ?STRING_REST($/, Path)}}; parse_reg_name(?STRING_REST($?, Rest), URI) -> {T, URI1} = parse_query(Rest, URI), % path-empty ?query Query = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{query => decode_query(Query)}}; + {Rest, URI1#{query => Query}}; parse_reg_name(?STRING_REST($#, Rest), URI) -> {T, URI1} = parse_fragment(Rest, URI), % path-empty Fragment = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{fragment => decode_fragment(Fragment)}}; + {Rest, URI1#{fragment => Fragment}}; parse_reg_name(?STRING_REST(Char, Rest), URI) -> case is_reg_name(Char) of true -> parse_reg_name(Rest, URI); @@ -899,17 +907,17 @@ parse_ipv4_bin(?STRING_REST($/, Rest), Acc, URI) -> _ = validate_ipv4_address(lists:reverse(Acc)), {T, URI1} = parse_segment(Rest, URI), % path-abempty Path = calculate_parsed_part(Rest, T), - {Rest, URI1#{path => decode_path(?STRING_REST($/, Path))}}; + {Rest, URI1#{path => ?STRING_REST($/, Path)}}; parse_ipv4_bin(?STRING_REST($?, Rest), Acc, URI) -> _ = validate_ipv4_address(lists:reverse(Acc)), {T, URI1} = parse_query(Rest, URI), % path-empty ?query Query = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{query => decode_query(Query)}}; + {Rest, URI1#{query => Query}}; parse_ipv4_bin(?STRING_REST($#, Rest), Acc, URI) -> _ = validate_ipv4_address(lists:reverse(Acc)), {T, URI1} = parse_fragment(Rest, URI), % path-empty Fragment = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{fragment => decode_fragment(Fragment)}}; + {Rest, URI1#{fragment => Fragment}}; parse_ipv4_bin(?STRING_REST(Char, Rest), Acc, URI) -> case is_ipv4(Char) of true -> parse_ipv4_bin(Rest, [Char|Acc], URI); @@ -961,15 +969,15 @@ parse_ipv6_bin_end(?STRING_REST($:, Rest), URI) -> parse_ipv6_bin_end(?STRING_REST($/, Rest), URI) -> {T, URI1} = parse_segment(Rest, URI), % path-abempty Path = calculate_parsed_part(Rest, T), - {Rest, URI1#{path => decode_path(?STRING_REST($/, Path))}}; + {Rest, URI1#{path => ?STRING_REST($/, Path)}}; parse_ipv6_bin_end(?STRING_REST($?, Rest), URI) -> {T, URI1} = parse_query(Rest, URI), % path-empty ?query Query = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{query => decode_query(Query)}}; + {Rest, URI1#{query => Query}}; parse_ipv6_bin_end(?STRING_REST($#, Rest), URI) -> {T, URI1} = parse_fragment(Rest, URI), % path-empty Fragment = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{fragment => decode_fragment(Fragment)}}; + {Rest, URI1#{fragment => Fragment}}; parse_ipv6_bin_end(?STRING_REST(Char, Rest), URI) -> case is_ipv6(Char) of true -> parse_ipv6_bin_end(Rest, URI); @@ -999,15 +1007,15 @@ validate_ipv6_address(Addr) -> parse_port(?STRING_REST($/, Rest), URI) -> {T, URI1} = parse_segment(Rest, URI), % path-abempty Path = calculate_parsed_part(Rest, T), - {Rest, URI1#{path => decode_path(?STRING_REST($/, Path))}}; + {Rest, URI1#{path => ?STRING_REST($/, Path)}}; parse_port(?STRING_REST($?, Rest), URI) -> {T, URI1} = parse_query(Rest, URI), % path-empty ?query Query = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{query => decode_query(Query)}}; + {Rest, URI1#{query => Query}}; parse_port(?STRING_REST($#, Rest), URI) -> {T, URI1} = parse_fragment(Rest, URI), % path-empty Fragment = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{fragment => decode_fragment(Fragment)}}; + {Rest, URI1#{fragment => Fragment}}; parse_port(?STRING_REST(Char, Rest), URI) -> case is_digit(Char) of true -> parse_port(Rest, URI); @@ -1033,7 +1041,7 @@ parse_port(?STRING_EMPTY, URI) -> parse_query(?STRING_REST($#, Rest), URI) -> {T, URI1} = parse_fragment(Rest, URI), Fragment = calculate_parsed_query_fragment(Rest, T), - {Rest, URI1#{fragment => decode_fragment(Fragment)}}; + {Rest, URI1#{fragment => Fragment}}; parse_query(?STRING_REST(Char, Rest), URI) -> case is_query(Char) of true -> parse_query(Rest, URI); @@ -1088,6 +1096,31 @@ is_fragment(Char) -> is_pchar(Char). %% %%------------------------------------------------------------------------- +%% Return true if input char is reserved. +-spec is_reserved(char()) -> boolean(). +is_reserved($:) -> true; +is_reserved($/) -> true; +is_reserved($?) -> true; +is_reserved($#) -> true; +is_reserved($[) -> true; +is_reserved($]) -> true; +is_reserved($@) -> true; + +is_reserved($!) -> true; +is_reserved($$) -> true; +is_reserved($&) -> true; +is_reserved($') -> true; +is_reserved($() -> true; +is_reserved($)) -> true; + +is_reserved($*) -> true; +is_reserved($+) -> true; +is_reserved($,) -> true; +is_reserved($;) -> true; +is_reserved($=) -> true; +is_reserved(_) -> false. + + %% Check if char is sub-delim. -spec is_sub_delim(char()) -> boolean(). is_sub_delim($!) -> true; @@ -1276,36 +1309,6 @@ byte_size_exl_head(Binary) -> byte_size(Binary) + 1. %% %% pct-encoded = "%" HEXDIG HEXDIG %%------------------------------------------------------------------------- --spec decode_userinfo(binary()) -> binary(). -decode_userinfo(Cs) -> - check_utf8(decode(Cs, fun is_userinfo/1, <<>>)). - --spec decode_host(binary()) -> binary(). -decode_host(Cs) -> - check_utf8(decode(Cs, fun is_host/1, <<>>)). - --spec decode_path(binary()) -> binary(). -decode_path(Cs) -> - check_utf8(decode(Cs, fun is_path/1, <<>>)). - --spec decode_query(binary()) -> binary(). -decode_query(Cs) -> - check_utf8(decode(Cs, fun is_query/1, <<>>)). - --spec decode_fragment(binary()) -> binary(). -decode_fragment(Cs) -> - check_utf8(decode(Cs, fun is_fragment/1, <<>>)). - - -%% Returns Cs if it is utf8 encoded. -check_utf8(Cs) -> - case unicode:characters_to_list(Cs) of - {incomplete,_,_} -> - throw({error,invalid_utf8,Cs}); - {error,_,_} -> - throw({error,invalid_utf8,Cs}); - _ -> Cs - end. %%------------------------------------------------------------------------- %% Percent-encode @@ -1351,20 +1354,56 @@ encode_fragment(Cs) -> %%------------------------------------------------------------------------- %% Helper funtions for percent-decode %%------------------------------------------------------------------------- -decode(<<$%,C0,C1,Cs/binary>>, Fun, Acc) -> + +-spec decode(list()|binary()) -> list() | binary(). +decode(Cs) -> + decode(Cs, <<>>). +%% +decode(L, Acc) when is_list(L) -> + B0 = unicode:characters_to_binary(L), + B1 = decode(B0, Acc), + unicode:characters_to_list(B1); +decode(<<$%,C0,C1,Cs/binary>>, Acc) -> case is_hex_digit(C0) andalso is_hex_digit(C1) of true -> B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), - decode(Cs, Fun, <<Acc/binary, B>>); + case is_reserved(B) of + true -> + %% [2.2] Characters in the reserved set are protected from + %% normalization. + %% [2.1] For consistency, URI producers and normalizers should + %% use uppercase hexadecimal digits for all percent- + %% encodings. + H0 = hex_to_upper(C0), + H1 = hex_to_upper(C1), + decode(Cs, <<Acc/binary,$%,H0,H1>>); + false -> + decode(Cs, <<Acc/binary, B>>) + end; false -> throw({error,invalid_percent_encoding,<<$%,C0,C1>>}) end; -decode(<<C,Cs/binary>>, Fun, Acc) -> - case Fun(C) of - true -> decode(Cs, Fun, <<Acc/binary, C>>); - false -> throw({error,invalid_percent_encoding,<<C,Cs/binary>>}) - end; -decode(<<>>, _Fun, Acc) -> - Acc. +decode(<<C,Cs/binary>>, Acc) -> + decode(Cs, <<Acc/binary, C>>); +decode(<<>>, Acc) -> + check_utf8(Acc). + +%% Returns Cs if it is utf8 encoded. +check_utf8(Cs) -> + case unicode:characters_to_list(Cs) of + {incomplete,_,_} -> + throw({error,invalid_utf8,Cs}); + {error,_,_} -> + throw({error,invalid_utf8,Cs}); + _ -> Cs + end. + +%% Convert hex digit to uppercase form +hex_to_upper(H) when $a =< H, H =< $f -> + H - 32; +hex_to_upper(H) when $0 =< H, H =< $9;$A =< H, H =< $F-> + H; +hex_to_upper(H) -> + throw({error,invalid_input, H}). %% Check if char is allowed in host -spec is_host(char()) -> boolean(). @@ -1925,9 +1964,10 @@ base10_decode_unicode(<<H,_/binary>>, _, _) -> %%------------------------------------------------------------------------- normalize_map(URIMap) -> - normalize_path_segment( - normalize_scheme_based( - normalize_case(URIMap))). + normalize_path_segment( + normalize_scheme_based( + normalize_percent_encoding( + normalize_case(URIMap)))). %% 6.2.2.1. Case Normalization @@ -1942,6 +1982,18 @@ normalize_case(#{} = Map) -> Map. +%% 6.2.2.2. Percent-Encoding Normalization +normalize_percent_encoding(Map) -> + Fun = fun (K,V) when K =:= userinfo; K =:= host; K =:= path; + K =:= query; K =:= fragment -> + decode(V); + %% Handle port and scheme + (_,V) -> + V + end, + maps:map(Fun, Map). + + to_lower(Cs) when is_list(Cs) -> B = convert_to_binary(Cs, utf8, utf8), convert_to_list(to_lower(B), utf8); diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile index ae2e3d0e2b..bbe3cefa42 100644 --- a/lib/stdlib/test/Makefile +++ b/lib/stdlib/test/Makefile @@ -88,6 +88,7 @@ MODULES= \ unicode_SUITE \ unicode_util_SUITE \ uri_string_SUITE \ + uri_string_property_test_SUITE \ win32reg_SUITE \ y2k_SUITE \ select_SUITE \ @@ -152,6 +153,6 @@ release_tests_spec: make_emakefile $(INSTALL_DATA) stdlib.spec stdlib_bench.spec $(EMAKEFILE) \ $(ERL_FILES) $(COVERFILE) "$(RELSYSDIR)" chmod -R u+w "$(RELSYSDIR)" - @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) + @tar cf - *_SUITE_data property_test | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 574aac96c8..a97fe4a5d9 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -6209,20 +6209,23 @@ spawn_logger(Procs) -> ok; (Proc) -> Mon = erlang:monitor(process, Proc), - receive + ok = receive {'DOWN', Mon, _, _, _} -> ok after 0 -> case Kill of true -> exit(Proc, kill); - _ -> - erlang:display({"Waiting for 'DOWN' from", Proc, - process_info(Proc), - pid_status(Proc)}) + _ -> ok end, receive {'DOWN', Mon, _, _, _} -> ok + after 5000 -> + io:format("Waiting for 'DOWN' from ~w, status=~w\n" + "info = ~p\n", [Proc, + pid_status(Proc), + process_info(Proc)]), + timeout end end end, Procs), diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl index 13f2cbd27b..91fe1133f6 100644 --- a/lib/stdlib/test/io_SUITE.erl +++ b/lib/stdlib/test/io_SUITE.erl @@ -31,7 +31,7 @@ otp_10836/1, io_lib_width_too_small/1, io_with_huge_message_queue/1, format_string/1, maps/1, coverage/1, otp_14178_unicode_atoms/1, otp_14175/1, - otp_14285/1, limit_term/1, otp_14983/1]). + otp_14285/1, limit_term/1, otp_14983/1, otp_15103/1]). -export([pretty/2, trf/3]). @@ -63,7 +63,7 @@ all() -> io_lib_print_binary_depth_one, otp_10302, otp_10755, otp_10836, io_lib_width_too_small, io_with_huge_message_queue, format_string, maps, coverage, otp_14178_unicode_atoms, otp_14175, - otp_14285, limit_term, otp_14983]. + otp_14285, limit_term, otp_14983, otp_15103]. %% Error cases for output. error_1(Config) when is_list(Config) -> @@ -2615,3 +2615,21 @@ trf(Format, Args, T) -> trf(Format, Args, T, Opts) -> lists:flatten(io_lib:format(Format, Args, [{chars_limit, T}|Opts])). + +otp_15103(_Config) -> + T = lists:duplicate(5, {a,b,c}), + + S1 = io_lib:format("~0p", [T]), + "[{a,b,c},{a,b,c},{a,b,c},{a,b,c},{a,b,c}]" = lists:flatten(S1), + S2 = io_lib:format("~-0p", [T]), + "[{a,b,c},{a,b,c},{a,b,c},{a,b,c},{a,b,c}]" = lists:flatten(S2), + S3 = io_lib:format("~1p", [T]), + "[{a,\n b,\n c},\n {a,\n b,\n c},\n {a,\n b,\n c},\n {a,\n b,\n" + " c},\n {a,\n b,\n c}]" = lists:flatten(S3), + + S4 = io_lib:format("~0P", [T, 5]), + "[{a,b,c},{a,b,...},{a,...},{...}|...]" = lists:flatten(S4), + S5 = io_lib:format("~1P", [T, 5]), + "[{a,\n b,\n c},\n {a,\n b,...},\n {a,...},\n {...}|...]" = + lists:flatten(S5), + ok. diff --git a/lib/stdlib/test/maps_SUITE.erl b/lib/stdlib/test/maps_SUITE.erl index a75751b31d..6374daa1d3 100644 --- a/lib/stdlib/test/maps_SUITE.erl +++ b/lib/stdlib/test/maps_SUITE.erl @@ -108,6 +108,8 @@ t_without_2(_Config) -> %% error case ?badmap(a,without,[[a,b],a]) = (catch maps:without([a,b],id(a))), ?badmap(a,without,[{a,b},a]) = (catch maps:without({a,b},id(a))), + ?badmap({0,<<>>,97},without,[[],{0,<<>>,97}]) = (catch maps:without([], {0,<<>>,97})), + ?badmap({0,<<>>,97},without,[[false, -20, -8],{0,<<>>,97}]) = (catch maps:without([false, -20, -8], {0, <<>>, 97})), ?badarg(without,[a,#{}]) = (catch maps:without(a,#{})), ok. @@ -120,6 +122,8 @@ t_with_2(_Config) -> %% error case ?badmap(a,with,[[a,b],a]) = (catch maps:with([a,b],id(a))), ?badmap(a,with,[{a,b},a]) = (catch maps:with({a,b},id(a))), + ?badmap({0,<<>>,97},with,[[],{0,<<>>,97}]) = (catch maps:with([], {0,<<>>,97})), + ?badmap({0,<<>>,97},with,[[false, -20, -8],{0,<<>>,97}]) = (catch maps:with([false, -20, -8], {0, <<>>, 97})), ?badarg(with,[a,#{}]) = (catch maps:with(a,#{})), ok. diff --git a/lib/stdlib/test/proc_lib_SUITE.erl b/lib/stdlib/test/proc_lib_SUITE.erl index 81bf9020b8..a283aa992f 100644 --- a/lib/stdlib/test/proc_lib_SUITE.erl +++ b/lib/stdlib/test/proc_lib_SUITE.erl @@ -542,13 +542,14 @@ system_terminate(Reason,_Parent,_Deb,_State) -> t_format(_Config) -> - logger:add_handler_filter(logger_std_h,stop_all,{fun(_,_) -> stop end,ok}), + {ok,#{level:=Level}} = logger:get_handler_config(default), + logger:set_handler_config(default,level,none), error_logger:add_report_handler(?MODULE, self()), try t_format() after error_logger:delete_report_handler(?MODULE), - logger:remove_handler_filter(logger_std_h,stop_all) + logger:set_handler_config(default,level,Level) end, ok. @@ -585,11 +586,12 @@ t_format() -> ok. t_format_arbitrary(_Config) -> - logger:add_handler_filter(logger_std_h,stop_all,{fun(_,_) -> stop end,ok}), + {ok,#{level:=Level}} = logger:get_handler_config(default), + logger:set_handler_config(default,level,none), try t_format_arbitrary() after - logger:remove_handler_filter(logger_std_h,stop_all) + logger:set_handler_config(default,level,Level) end, ok. diff --git a/lib/stdlib/test/property_test/uri_string_recompose.erl b/lib/stdlib/test/property_test/uri_string_recompose.erl index e51a671172..35b3a50b9c 100644 --- a/lib/stdlib/test/property_test/uri_string_recompose.erl +++ b/lib/stdlib/test/property_test/uri_string_recompose.erl @@ -65,15 +65,29 @@ -define(QUERY, {query, query_map()}). -define(FRAGMENT, {fragment, fragment_map()}). +%% Non-unicode +-define(USER_NU, {userinfo, non_unicode()}). +-define(HOST_NU, {host, host_map_nu()}). +-define(PATH_ABE_NU, {path, path_abempty_map_nu()}). +-define(PATH_ABS_NU, {path, path_absolute_map_nu()}). +-define(PATH_NOS_NU, {path, path_noscheme_map_nu()}). +-define(PATH_ROO_NU, {path, path_rootless_map_nu()}). +-define(QUERY_NU, {query, query_map_nu()}). +-define(FRAGMENT_NU, {fragment, fragment_map_nu()}). %%%======================================================================== %%% Properties %%%======================================================================== prop_recompose() -> + ?FORALL(Map, map_no_unicode(), + Map =:= uri_string:parse(uri_string:recompose(Map))). + +prop_normalize() -> ?FORALL(Map, map(), - Map =:= uri_string:parse(uri_string:recompose(Map)) - ). + uri_string:normalize(Map, [return_map]) =:= + uri_string:normalize(uri_string:parse(uri_string:recompose(Map)), + [return_map])). %% Stats prop_map_key_length_collect() -> @@ -96,6 +110,9 @@ prop_scheme_collect() -> map() -> ?LET(Gen, comp_proplist(), proplist_to_map(Gen)). +map_no_unicode() -> + ?LET(Gen, comp_proplist_nu(), proplist_to_map(Gen)). + comp_proplist() -> frequency([ {2, [?SCHEME,?PATH_ABS]}, @@ -166,6 +183,76 @@ comp_proplist() -> {2, [?USER,?HOST,?PORT,?PATH_ABE,?QUERY,?FRAGMENT]} ]). +comp_proplist_nu() -> + frequency([ + {2, [?SCHEME,?PATH_ABS_NU]}, + {2, [?SCHEME,?PATH_ROO_NU]}, + {2, [?SCHEME,?PATH_EMP]}, + {2, [?SCHEME,?HOST_NU,?PATH_ABE_NU]}, + {2, [?SCHEME,?USER_NU,?HOST_NU,?PATH_ABE_NU]}, + {2, [?SCHEME,?HOST_NU,?PORT,?PATH_ABE_NU]}, + {2, [?SCHEME,?USER_NU,?HOST_NU,?PORT,?PATH_ABE_NU]}, + + {2, [?PATH_ABS_NU]}, + {2, [?PATH_NOS_NU]}, + {2, [?PATH_EMP]}, + {2, [?HOST_NU,?PATH_ABE_NU]}, + {2, [?USER_NU,?HOST_NU,?PATH_ABE_NU]}, + {2, [?HOST_NU,?PORT,?PATH_ABE_NU]}, + {2, [?USER_NU,?HOST_NU,?PORT,?PATH_ABE_NU]}, + + + {2, [?SCHEME,?PATH_ABS_NU,?QUERY_NU]}, + {2, [?SCHEME,?PATH_ROO_NU,?QUERY_NU]}, + {2, [?SCHEME,?PATH_EMP,?QUERY_NU]}, + {2, [?SCHEME,?HOST_NU,?PATH_ABE_NU,?QUERY_NU]}, + {2, [?SCHEME,?USER_NU,?HOST_NU,?PATH_ABE_NU,?QUERY_NU]}, + {2, [?SCHEME,?HOST_NU,?PORT,?PATH_ABE_NU,?QUERY_NU]}, + {2, [?SCHEME,?USER_NU,?HOST_NU,?PORT,?PATH_ABE_NU,?QUERY_NU]}, + + {2, [?PATH_ABS_NU,?QUERY_NU]}, + {2, [?PATH_NOS_NU,?QUERY_NU]}, + {2, [?PATH_EMP,?QUERY_NU]}, + {2, [?HOST_NU,?PATH_ABE_NU,?QUERY_NU]}, + {2, [?USER_NU,?HOST_NU,?PATH_ABE_NU,?QUERY_NU]}, + {2, [?HOST_NU,?PORT,?PATH_ABE_NU,?QUERY_NU]}, + {2, [?USER_NU,?HOST_NU,?PORT,?PATH_ABE_NU,?QUERY_NU]}, + + + {2, [?SCHEME,?PATH_ABS_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?PATH_ROO_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?PATH_EMP,?FRAGMENT_NU]}, + {2, [?SCHEME,?HOST_NU,?PATH_ABE_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?USER_NU,?HOST_NU,?PATH_ABE_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?HOST_NU,?PORT,?PATH_ABE_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?USER_NU,?HOST_NU,?PORT,?PATH_ABE_NU,?FRAGMENT_NU]}, + + {2, [?PATH_ABS_NU,?FRAGMENT_NU]}, + {2, [?PATH_NOS_NU,?FRAGMENT_NU]}, + {2, [?PATH_EMP,?FRAGMENT_NU]}, + {2, [?HOST_NU,?PATH_ABE_NU,?FRAGMENT_NU]}, + {2, [?USER_NU,?HOST_NU,?PATH_ABE_NU,?FRAGMENT_NU]}, + {2, [?HOST_NU,?PORT,?PATH_ABE_NU,?FRAGMENT_NU]}, + {2, [?USER_NU,?HOST_NU,?PORT,?PATH_ABE_NU,?FRAGMENT_NU]}, + + + {2, [?SCHEME,?PATH_ABS_NU,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?PATH_ROO_NU,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?PATH_EMP,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?HOST_NU,?PATH_ABE_NU,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?USER_NU,?HOST_NU,?PATH_ABE_NU,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?HOST_NU,?PORT,?PATH_ABE_NU,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?SCHEME,?USER_NU,?HOST_NU,?PORT,?PATH_ABE_NU,?QUERY_NU,?FRAGMENT_NU]}, + + {2, [?PATH_ABS_NU,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?PATH_NOS_NU,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?PATH_EMP,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?HOST_NU,?PATH_ABE_NU,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?USER_NU,?HOST_NU,?PATH_ABE_NU,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?HOST_NU,?PORT,?PATH_ABE_NU,?QUERY_NU,?FRAGMENT_NU]}, + {2, [?USER_NU,?HOST_NU,?PORT,?PATH_ABE_NU,?QUERY_NU,?FRAGMENT_NU]} + ]). + %%------------------------------------------------------------------------- %% Path @@ -174,6 +261,11 @@ path_abempty_map() -> frequency([{90, path_abe_map()}, {10, path_empty_map()}]). +path_abempty_map_nu() -> + frequency([{90, path_abe_map_nu()}, + {10, path_empty_map()}]). + + path_abe_map() -> ?SIZED(Length, path_abe_map(Length, [])). %% @@ -182,6 +274,14 @@ path_abe_map(0, Segments) -> path_abe_map(N, Segments) -> path_abe_map(N-1, [slash(),segment()|Segments]). +path_abe_map_nu() -> + ?SIZED(Length, path_abe_map_nu(Length, [])). +%% +path_abe_map_nu(0, Segments) -> + ?LET(Gen, Segments, lists:append(Gen)); +path_abe_map_nu(N, Segments) -> + path_abe_map_nu(N-1, [slash(),segment_nu()|Segments]). + path_absolute_map() -> ?SIZED(Length, path_absolute_map(Length, [])). @@ -191,6 +291,14 @@ path_absolute_map(0, Segments) -> path_absolute_map(N, Segments) -> path_absolute_map(N-1, [slash(),segment()|Segments]). +path_absolute_map_nu() -> + ?SIZED(Length, path_absolute_map_nu(Length, [])). +%% +path_absolute_map_nu(0, Segments) -> + ?LET(Gen, [slash(),segment_nz_nu()|Segments], lists:append(Gen)); +path_absolute_map_nu(N, Segments) -> + path_absolute_map_nu(N-1, [slash(),segment_nu()|Segments]). + path_noscheme_map() -> ?SIZED(Length, path_noscheme_map(Length, [])). @@ -200,6 +308,15 @@ path_noscheme_map(0, Segments) -> path_noscheme_map(N, Segments) -> path_noscheme_map(N-1, [slash(),segment()|Segments]). +path_noscheme_map_nu() -> + ?SIZED(Length, path_noscheme_map_nu(Length, [])). +%% +path_noscheme_map_nu(0, Segments) -> + ?LET(Gen, [segment_nz_nc_nu()|Segments], lists:append(Gen)); +path_noscheme_map_nu(N, Segments) -> + path_noscheme_map_nu(N-1, [slash(),segment_nu()|Segments]). + + path_rootless_map() -> ?SIZED(Length, path_rootless_map(Length, [])). %% @@ -208,24 +325,59 @@ path_rootless_map(0, Segments) -> path_rootless_map(N, Segments) -> path_rootless_map(N-1, [slash(),segment()|Segments]). +path_rootless_map_nu() -> + ?SIZED(Length, path_rootless_map_nu(Length, [])). +%% +path_rootless_map_nu(0, Segments) -> + ?LET(Gen, [segment_nz_nu()|Segments], lists:append(Gen)); +path_rootless_map_nu(N, Segments) -> + path_rootless_map_nu(N-1, [slash(),segment_nu()|Segments]). + segment_nz() -> non_empty(segment()). -segment_nz_nc() -> - non_empty(list(frequency([{30, unreserved()}, - {10, sub_delims()}, - {10, unicode_char()}, - {5, oneof([$@])} - ]))). +segment_nz_nu() -> + non_empty(segment_nu()). +segment_nz_nc() -> + ?LET(Gen, + non_empty(list(frequency([{30, unreserved()}, + {10, ptc_encoded_reserved()}, + {10, sub_delims()}, + {10, unicode_char()}, + {5, oneof([$@])} + ]))), + lists:flatten(Gen)). + +segment_nz_nc_nu() -> + ?LET(Gen, + non_empty(list(frequency([{30, unreserved()}, + {10, ptc_encoded_reserved()}, + {10, sub_delims()}, + {5, oneof([$@])} + ]))), + lists:flatten(Gen)). + segment() -> - list(frequency([{30, unreserved()}, - {10, sub_delims()}, - {10, unicode_char()}, - {5, oneof([$:, $@])} - ])). + ?LET(Gen, + list(frequency([{30, unreserved()}, + {10, ptc_encoded_reserved()}, + {10, sub_delims()}, + {10, unicode_char()}, + {5, oneof([$:, $@])} + ])), + lists:flatten(Gen)). + +segment_nu() -> + ?LET(Gen, + list(frequency([{30, unreserved()}, + {10, ptc_encoded_reserved()}, + {10, sub_delims()}, + {5, oneof([$:, $@])} + ])), + lists:flatten(Gen)). slash() -> "/". @@ -235,19 +387,35 @@ path_empty_map() -> %%------------------------------------------------------------------------- -%% Path +%% Host %%------------------------------------------------------------------------- host_map() -> frequency([{30, reg_name()}, {30, ip_address()} ]). +host_map_nu() -> + frequency([{30, reg_name_nu()}, + {30, ip_address()} + ]). reg_name() -> - list(frequency([{30, alpha()}, - {10, sub_delims()}, - {10, unicode_char()} - ])). + ?LET(Gen, + list(frequency([{30, alpha()}, + {10, sub_delims()}, + {10, ptc_encoded_reserved()}, + {10, unicode_char()} + ])), + lists:flatten(Gen)). + +reg_name_nu() -> + ?LET(Gen, + list(frequency([{30, alpha()}, + {10, sub_delims()}, + {10, ptc_encoded_reserved()} + ])), + lists:flatten(Gen)). + ip_address() -> oneof(["127.0.0.1", "::127.0.0.1", @@ -258,10 +426,13 @@ ip_address() -> %% Generating only reg-names host_uri() -> - non_empty(list(frequency([{30, unreserved()}, - {10, sub_delims()}, - {10, pct_encoded()} - ]))). + ?LET(Gen, + non_empty(list(frequency([{30, unreserved()}, + {10, sub_delims()}, + {10, ptc_encoded_reserved()}, + {10, pct_encoded()} + ]))), + lists:flatten(Gen)). %%------------------------------------------------------------------------- %% Port, Query, Fragment @@ -274,6 +445,9 @@ port() -> query_map() -> unicode(). +query_map_nu() -> + non_unicode(). + query_uri() -> [$?| non_empty(list(frequency([{20, pchar()}, @@ -283,6 +457,10 @@ query_uri() -> fragment_map() -> unicode(). +fragment_map_nu() -> + non_unicode(). + + fragment_uri() -> [$?| non_empty(list(frequency([{20, pchar()}, {5, oneof([$/, $?])} % punctuation @@ -311,9 +489,14 @@ scheme(N, L) -> %%------------------------------------------------------------------------- unicode() -> list(frequency([{20, alpha()}, % alpha - {10, digit()}, % digit - {10, unicode_char()} % unicode - ])). + {10, digit()}, % digit + {10, unicode_char()} % unicode + ])). + +non_unicode() -> + list(frequency([{20, alpha()}, % alpha + {10, digit()} % digit + ])). scheme_char() -> frequency([{20, alpha()}, % alpha @@ -327,6 +510,7 @@ sub_delims() -> pchar() -> frequency([{20, unreserved()}, + {5, ptc_encoded_reserved()}, {5, pct_encoded()}, {5, sub_delims()}, {1, oneof([$:, $@])} % punctuation @@ -351,6 +535,22 @@ digit() -> pct_encoded() -> oneof(["%C3%A4", "%C3%A5", "%C3%B6"]). +%%------------------------------------------------------------------------- +%% [RFC 3986, Chapter 2.2. Reserved Characters] +%% +%% reserved = gen-delims / sub-delims +%% +%% gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" +%% 3A 2F 3F 23 5B 5D 40 +%% sub-delims = "!" / "$" / "&" / "'" / "(" / ")" +%% 21 24 26 27 28 29 +%% / "*" / "+" / "," / ";" / "=" +%% 2A 2B 2C 3B 3D +%%------------------------------------------------------------------------- +ptc_encoded_reserved() -> + oneof(["%3A","%2F","%3F","%23","%5B","%5D","%40", + "%21","%24","%26","%27","%28","%29", + "%2A","%2B","%2C","%3B","3D"]). %%%======================================================================== %%% Helpers @@ -359,3 +559,13 @@ proplist_to_map(L) -> lists:foldl(fun({K,V},M) -> M#{K => V}; (_,M) -> M end, #{}, L). + +map_scheme_host_to_lower(Map) -> + Fun = fun (scheme,V) -> + string:to_lower(V); + (host,V) -> + string:to_lower(V); + (_,V) -> + V + end, + maps:map(Fun, Map). diff --git a/lib/stdlib/test/string_SUITE.erl b/lib/stdlib/test/string_SUITE.erl index 29fabb4583..ab412dcc70 100644 --- a/lib/stdlib/test/string_SUITE.erl +++ b/lib/stdlib/test/string_SUITE.erl @@ -409,8 +409,8 @@ uppercase(_) -> ?TEST("abc", [], "ABC"), ?TEST("ABC", [], "ABC"), ?TEST("abcdefghiljklmnopqrstvxyzåäö",[], "ABCDEFGHILJKLMNOPQRSTVXYZÅÄÖ"), - ?TEST("åäö", [], "ÅÄÖ"), - ?TEST("ÅÄÖ", [], "ÅÄÖ"), + ?TEST("åäö ", [], "ÅÄÖ "), + ?TEST("ÅÄÖ ", [], "ÅÄÖ "), ?TEST("Michał", [], "MICHAŁ"), ?TEST(["Mic",<<"hał"/utf8>>], [], "MICHAŁ"), ?TEST("ljLJ", [], "LJLJ"), @@ -423,8 +423,8 @@ lowercase(_) -> ?TEST("123", [], "123"), ?TEST("abc", [], "abc"), ?TEST("ABC", [], "abc"), - ?TEST("åäö", [], "åäö"), - ?TEST("ÅÄÖ", [], "åäö"), + ?TEST("åäö ", [], "åäö "), + ?TEST("ÅÄÖ ", [], "åäö "), ?TEST("MICHAŁ", [], "michał"), ?TEST(["Mic",<<"HAŁ"/utf8>>], [], "michał"), ?TEST("ß SHARP S", [], "ß sharp s"), @@ -449,8 +449,8 @@ casefold(_) -> ?TEST("123", [], "123"), ?TEST("abc", [], "abc"), ?TEST("ABC", [], "abc"), - ?TEST("åäö", [], "åäö"), - ?TEST("ÅÄÖ", [], "åäö"), + ?TEST("åäö ", [], "åäö "), + ?TEST("ÅÄÖ ", [], "åäö "), ?TEST("MICHAŁ", [], "michał"), ?TEST(["Mic",<<"HAŁ"/utf8>>], [], "michał"), ?TEST("ß SHARP S", [], "ss sharp s"), diff --git a/lib/stdlib/test/uri_string_SUITE.erl b/lib/stdlib/test/uri_string_SUITE.erl index 92f8bb3292..2aa399525d 100644 --- a/lib/stdlib/test/uri_string_SUITE.erl +++ b/lib/stdlib/test/uri_string_SUITE.erl @@ -23,6 +23,12 @@ -export([all/0, suite/0,groups/0, normalize/1, normalize_map/1, normalize_return_map/1, normalize_negative/1, + normalize_binary_pct_encoded_userinfo/1, + normalize_binary_pct_encoded_query/1, + normalize_binary_pct_encoded_fragment/1, + normalize_pct_encoded_userinfo/1, + normalize_pct_encoded_query/1, + normalize_pct_encoded_fragment/1, parse_binary_fragment/1, parse_binary_host/1, parse_binary_host_ipv4/1, parse_binary_host_ipv6/1, parse_binary_path/1, parse_binary_pct_encoded_fragment/1, parse_binary_pct_encoded_query/1, @@ -41,7 +47,8 @@ transcode_basic/1, transcode_options/1, transcode_mixed/1, transcode_negative/1, compose_query/1, compose_query_latin1/1, compose_query_negative/1, dissect_query/1, dissect_query_negative/1, - interop_query_latin1/1, interop_query_utf8/1 + interop_query_latin1/1, interop_query_utf8/1, + regression_parse/1, regression_recompose/1, regression_normalize/1 ]). @@ -71,6 +78,12 @@ all() -> normalize_map, normalize_return_map, normalize_negative, + normalize_binary_pct_encoded_userinfo, + normalize_binary_pct_encoded_query, + normalize_binary_pct_encoded_fragment, + normalize_pct_encoded_userinfo, + normalize_pct_encoded_query, + normalize_pct_encoded_fragment, parse_binary_scheme, parse_binary_userinfo, parse_binary_pct_encoded_userinfo, @@ -120,7 +133,10 @@ all() -> dissect_query, dissect_query_negative, interop_query_latin1, - interop_query_utf8 + interop_query_utf8, + regression_parse, + regression_recompose, + regression_normalize ]. groups() -> @@ -338,20 +354,23 @@ parse_binary_userinfo(_Config) -> uri_string:parse(<<"foo://user:password@localhost">>). parse_binary_pct_encoded_userinfo(_Config) -> - #{scheme := <<"user">>, path := <<"合@気道"/utf8>>} = + #{scheme := <<"user">>, path := <<"%E5%90%88@%E6%B0%97%E9%81%93">>} = uri_string:parse(<<"user:%E5%90%88@%E6%B0%97%E9%81%93">>), - #{path := <<"合気道@"/utf8>>} = uri_string:parse(<<"%E5%90%88%E6%B0%97%E9%81%93@">>), - #{path := <<"/合気道@"/utf8>>} = uri_string:parse(<<"/%E5%90%88%E6%B0%97%E9%81%93@">>), - #{path := <<"合@気道"/utf8>>} = uri_string:parse(<<"%E5%90%88@%E6%B0%97%E9%81%93">>), - #{userinfo := <<"合"/utf8>>, host := <<"気道"/utf8>>} = + #{path := <<"%E5%90%88%E6%B0%97%E9%81%93@">>} = + uri_string:parse(<<"%E5%90%88%E6%B0%97%E9%81%93@">>), + #{path := <<"/%E5%90%88%E6%B0%97%E9%81%93@">>} = + uri_string:parse(<<"/%E5%90%88%E6%B0%97%E9%81%93@">>), + #{path := <<"%E5%90%88@%E6%B0%97%E9%81%93">>} = + uri_string:parse(<<"%E5%90%88@%E6%B0%97%E9%81%93">>), + #{userinfo := <<"%E5%90%88">>, host := <<"%E6%B0%97%E9%81%93">>} = uri_string:parse(<<"//%E5%90%88@%E6%B0%97%E9%81%93">>), - #{userinfo := <<"合:気"/utf8>>, host := <<"道"/utf8>>} = + #{userinfo := <<"%E5%90%88:%E6%B0%97">>, host := <<"%E9%81%93">>} = uri_string:parse(<<"//%E5%90%88:%E6%B0%97@%E9%81%93">>), - #{scheme := <<"foo">>, path := <<"/合気道@"/utf8>>} = + #{scheme := <<"foo">>, path := <<"/%E5%90%88%E6%B0%97%E9%81%93@">>} = uri_string:parse(<<"foo:/%E5%90%88%E6%B0%97%E9%81%93@">>), - #{scheme := <<"foo">>, userinfo := <<"合"/utf8>>, host := <<"気道"/utf8>>} = + #{scheme := <<"foo">>, userinfo := <<"%E5%90%88">>, host := <<"%E6%B0%97%E9%81%93">>} = uri_string:parse(<<"foo://%E5%90%88@%E6%B0%97%E9%81%93">>), - #{scheme := <<"foo">>, userinfo := <<"合:気"/utf8>>, host := <<"道"/utf8>>} = + #{scheme := <<"foo">>, userinfo := <<"%E5%90%88:%E6%B0%97">>, host := <<"%E9%81%93">>} = uri_string:parse(<<"foo://%E5%90%88:%E6%B0%97@%E9%81%93">>), {error,invalid_uri,"@"} = uri_string:parse(<<"//%E5%90%88@%E6%B0%97%E9%81%93@">>), {error,invalid_uri,":"} = uri_string:parse(<<"foo://%E5%90%88@%E6%B0%97%E9%81%93@">>). @@ -369,8 +388,8 @@ parse_binary_host_ipv4(_Config) -> #{host := <<"127.0.0.1">>, query := <<"name=ferret">>} = uri_string:parse(<<"//127.0.0.1?name=ferret">>), #{host := <<"127.0.0.1">>, fragment := <<"nose">>} = uri_string:parse(<<"//127.0.0.1#nose">>), - {error,invalid_uri,"x"} = uri_string:parse(<<"//127.0.0.x">>), - {error,invalid_uri,"1227.0.0.1"} = uri_string:parse(<<"//1227.0.0.1">>). + #{host := <<"127.0.0.x">>,path := <<>>} = uri_string:parse(<<"//127.0.0.x">>), + #{host := <<"1227.0.0.1">>,path := <<>>} = uri_string:parse(<<"//1227.0.0.1">>). parse_binary_host_ipv6(_Config) -> #{host := <<"::127.0.0.1">>} = uri_string:parse(<<"//[::127.0.0.1]">>), @@ -439,9 +458,9 @@ parse_binary_query(_Config) -> parse_binary_pct_encoded_query(_Config) -> #{scheme := <<"foo">>, host := <<"example.com">>, path := <<"/">>, - query := <<"name=合気道"/utf8>>} = + query := <<"name=%E5%90%88%E6%B0%97%E9%81%93">>} = uri_string:parse(<<"foo://example.com/?name=%E5%90%88%E6%B0%97%E9%81%93">>), - #{host := <<"example.com">>, path := <<"/">>, query := <<"name=合気道"/utf8>>} = + #{host := <<"example.com">>, path := <<"/">>, query := <<"name=%E5%90%88%E6%B0%97%E9%81%93">>} = uri_string:parse(<<"//example.com/?name=%E5%90%88%E6%B0%97%E9%81%93">>). parse_binary_fragment(_Config) -> @@ -472,9 +491,11 @@ parse_binary_fragment(_Config) -> uri_string:parse(<<"//example.com/#nose">>). parse_binary_pct_encoded_fragment(_Config) -> - #{scheme := <<"foo">>, host := <<"example.com">>, fragment := <<"合気道"/utf8>>} = + #{scheme := <<"foo">>, host := <<"example.com">>, + fragment := <<"%E5%90%88%E6%B0%97%E9%81%93">>} = uri_string:parse(<<"foo://example.com#%E5%90%88%E6%B0%97%E9%81%93">>), - #{host := <<"example.com">>, path := <<"/">>, fragment := <<"合気道"/utf8>>} = + #{host := <<"example.com">>, path := <<"/">>, + fragment := <<"%E5%90%88%E6%B0%97%E9%81%93">>} = uri_string:parse(<<"//example.com/#%E5%90%88%E6%B0%97%E9%81%93">>). parse_scheme(_Config) -> @@ -506,25 +527,27 @@ parse_userinfo(_Config) -> uri_string:parse("foo://user:password@localhost"). parse_pct_encoded_userinfo(_Config) -> - #{scheme := "user", path := "合@気道"} = + #{scheme := "user", path := "%E5%90%88@%E6%B0%97%E9%81%93"} = uri_string:parse("user:%E5%90%88@%E6%B0%97%E9%81%93"), - #{path := "合気道@"} = uri_string:parse("%E5%90%88%E6%B0%97%E9%81%93@"), - #{path := "/合気道@"} = uri_string:parse("/%E5%90%88%E6%B0%97%E9%81%93@"), - #{path := "合@気道"} = uri_string:parse("%E5%90%88@%E6%B0%97%E9%81%93"), - #{userinfo := "合", host := "気道"} = + #{path := "%E5%90%88%E6%B0%97%E9%81%93@"} = + uri_string:parse("%E5%90%88%E6%B0%97%E9%81%93@"), + #{path := "/%E5%90%88%E6%B0%97%E9%81%93@"} = + uri_string:parse("/%E5%90%88%E6%B0%97%E9%81%93@"), + #{path := "%E5%90%88@%E6%B0%97%E9%81%93"} = + uri_string:parse("%E5%90%88@%E6%B0%97%E9%81%93"), + #{userinfo := "%E5%90%88", host := "%E6%B0%97%E9%81%93"} = uri_string:parse("//%E5%90%88@%E6%B0%97%E9%81%93"), - #{userinfo := "合:気", host := "道"} = + #{userinfo := "%E5%90%88:%E6%B0%97", host := "%E9%81%93"} = uri_string:parse("//%E5%90%88:%E6%B0%97@%E9%81%93"), - #{scheme := "foo", path := "/合気道@"} = + #{scheme := "foo", path := "/%E5%90%88%E6%B0%97%E9%81%93@"} = uri_string:parse("foo:/%E5%90%88%E6%B0%97%E9%81%93@"), - #{scheme := "foo", userinfo := "合", host := "気道"} = + #{scheme := "foo", userinfo := "%E5%90%88", host := "%E6%B0%97%E9%81%93"} = uri_string:parse("foo://%E5%90%88@%E6%B0%97%E9%81%93"), - #{scheme := "foo", userinfo := "合:気", host := "道"} = + #{scheme := "foo", userinfo := "%E5%90%88:%E6%B0%97", host := "%E9%81%93"} = uri_string:parse("foo://%E5%90%88:%E6%B0%97@%E9%81%93"), {error,invalid_uri,"@"} = uri_string:parse("//%E5%90%88@%E6%B0%97%E9%81%93@"), {error,invalid_uri,":"} = uri_string:parse("foo://%E5%90%88@%E6%B0%97%E9%81%93@"). - parse_host(_Config) -> #{host := "hostname"} = uri_string:parse("//hostname"), #{host := "hostname",scheme := "foo"} = uri_string:parse("foo://hostname"), @@ -538,8 +561,8 @@ parse_host_ipv4(_Config) -> #{host := "127.0.0.1", path := "/over/there"} = uri_string:parse("//127.0.0.1/over/there"), #{host := "127.0.0.1", query := "name=ferret"} = uri_string:parse("//127.0.0.1?name=ferret"), #{host := "127.0.0.1", fragment := "nose"} = uri_string:parse("//127.0.0.1#nose"), - {error,invalid_uri,"x"} = uri_string:parse("//127.0.0.x"), - {error,invalid_uri,"1227.0.0.1"} = uri_string:parse("//1227.0.0.1"). + #{host := "127.0.0.x",path := []} = uri_string:parse("//127.0.0.x"), + #{host := "1227.0.0.1",path := []} = uri_string:parse("//1227.0.0.1"). parse_host_ipv6(_Config) -> #{host := "::127.0.0.1"} = uri_string:parse("//[::127.0.0.1]"), @@ -602,9 +625,9 @@ parse_query(_Config) -> parse_pct_encoded_query(_Config) -> #{scheme := "foo", host := "example.com", path := "/", - query := "name=合気道"} = + query := "name=%E5%90%88%E6%B0%97%E9%81%93"} = uri_string:parse("foo://example.com/?name=%E5%90%88%E6%B0%97%E9%81%93"), - #{host := "example.com", path := "/", query := "name=合気道"} = + #{host := "example.com", path := "/", query := "name=%E5%90%88%E6%B0%97%E9%81%93"} = uri_string:parse("//example.com/?name=%E5%90%88%E6%B0%97%E9%81%93"). parse_fragment(_Config) -> @@ -635,9 +658,11 @@ parse_fragment(_Config) -> uri_string:parse("//example.com/#nose"). parse_pct_encoded_fragment(_Config) -> - #{scheme := "foo", host := "example.com", fragment := "合気道"} = + #{scheme := "foo", host := "example.com", + fragment := "%E5%90%88%E6%B0%97%E9%81%93"} = uri_string:parse("foo://example.com#%E5%90%88%E6%B0%97%E9%81%93"), - #{host := "example.com", path := "/", fragment := "合気道"} = + #{host := "example.com", path := "/", + fragment := "%E5%90%88%E6%B0%97%E9%81%93"} = uri_string:parse("//example.com/#%E5%90%88%E6%B0%97%E9%81%93"). parse_list(_Config) -> @@ -711,9 +736,7 @@ parse_negative(_Config) -> {error,invalid_uri,":"} = uri_string:parse("foo://usär@host"), {error,invalid_uri,"ö"} = uri_string:parse("//host/path?foö=bar"), {error,invalid_uri,"ö"} = uri_string:parse("//host/path#foö"), - {error,invalid_uri,"127.256.0.1"} = uri_string:parse("//127.256.0.1"), {error,invalid_uri,":::127.0.0.1"} = uri_string:parse("//[:::127.0.0.1]"), - {error,invalid_utf8,<<0,0,0,246>>} = uri_string:parse("//%00%00%00%F6"), {error,invalid_uri,"A"} = uri_string:parse("//localhost:A8"). @@ -913,7 +936,9 @@ normalize(_Config) -> <<"sftp://localhost">> = uri_string:normalize(<<"sftp://localhost:22">>), <<"tftp://localhost">> = - uri_string:normalize(<<"tftp://localhost:69">>). + uri_string:normalize(<<"tftp://localhost:69">>), + <<"/foo/%2F/bar">> = + uri_string:normalize(<<"/foo/%2f/%62ar">>). normalize_map(_Config) -> "/a/g" = uri_string:normalize(#{path => "/a/b/c/./../../g"}), @@ -942,7 +967,9 @@ normalize_map(_Config) -> host => <<"localhost">>}), <<"tftp://localhost">> = uri_string:normalize(#{scheme => <<"tftp">>,port => 69,path => <<>>, - host => <<"localhost">>}). + host => <<"localhost">>}), + "/foo/%2F/bar" = + uri_string:normalize(#{path => "/foo/%2f/%62ar"}). normalize_return_map(_Config) -> #{scheme := "http",path := "/a/g",host := "localhost-örebro"} = @@ -963,7 +990,82 @@ normalize_negative(_Config) -> {error,invalid_uri,":"} = uri_string:normalize("http://[192.168.0.1]", [return_map]), {error,invalid_uri,":"} = - uri_string:normalize(<<"http://[192.168.0.1]">>, [return_map]). + uri_string:normalize(<<"http://[192.168.0.1]">>, [return_map]), + {error,invalid_utf8,<<0,0,0,246>>} = uri_string:normalize("//%00%00%00%F6"). + +normalize_binary_pct_encoded_userinfo(_Config) -> + #{scheme := <<"user">>, path := <<"合@気道"/utf8>>} = + uri_string:normalize(<<"user:%E5%90%88@%E6%B0%97%E9%81%93">>, [return_map]), + #{path := <<"合気道@"/utf8>>} = + uri_string:normalize(<<"%E5%90%88%E6%B0%97%E9%81%93@">>, [return_map]), + #{path := <<"/合気道@"/utf8>>} = + uri_string:normalize(<<"/%E5%90%88%E6%B0%97%E9%81%93@">>, [return_map]), + #{path := <<"合@気道"/utf8>>} = + uri_string:normalize(<<"%E5%90%88@%E6%B0%97%E9%81%93">>, [return_map]), + #{userinfo := <<"合"/utf8>>, host := <<"気道"/utf8>>} = + uri_string:normalize(<<"//%E5%90%88@%E6%B0%97%E9%81%93">>, [return_map]), + #{userinfo := <<"合:気"/utf8>>, host := <<"道"/utf8>>} = + uri_string:normalize(<<"//%E5%90%88:%E6%B0%97@%E9%81%93">>, [return_map]), + #{scheme := <<"foo">>, path := <<"/合気道@"/utf8>>} = + uri_string:normalize(<<"foo:/%E5%90%88%E6%B0%97%E9%81%93@">>, [return_map]), + #{scheme := <<"foo">>, userinfo := <<"合"/utf8>>, host := <<"気道"/utf8>>} = + uri_string:normalize(<<"foo://%E5%90%88@%E6%B0%97%E9%81%93">>, [return_map]), + #{scheme := <<"foo">>, userinfo := <<"合:気"/utf8>>, host := <<"道"/utf8>>} = + uri_string:normalize(<<"foo://%E5%90%88:%E6%B0%97@%E9%81%93">>, [return_map]), + {error,invalid_uri,"@"} = + uri_string:normalize(<<"//%E5%90%88@%E6%B0%97%E9%81%93@">>, [return_map]), + {error,invalid_uri,":"} = + uri_string:normalize(<<"foo://%E5%90%88@%E6%B0%97%E9%81%93@">>, [return_map]). + +normalize_binary_pct_encoded_query(_Config) -> + #{scheme := <<"foo">>, host := <<"example.com">>, path := <<"/">>, + query := <<"name=合気道"/utf8>>} = + uri_string:normalize(<<"foo://example.com/?name=%E5%90%88%E6%B0%97%E9%81%93">>, [return_map]), + #{host := <<"example.com">>, path := <<"/">>, query := <<"name=合気道"/utf8>>} = + uri_string:normalize(<<"//example.com/?name=%E5%90%88%E6%B0%97%E9%81%93">>, [return_map]). + +normalize_binary_pct_encoded_fragment(_Config) -> + #{scheme := <<"foo">>, host := <<"example.com">>, fragment := <<"合気道"/utf8>>} = + uri_string:normalize(<<"foo://example.com#%E5%90%88%E6%B0%97%E9%81%93">>, [return_map]), + #{host := <<"example.com">>, path := <<"/">>, fragment := <<"合気道"/utf8>>} = + uri_string:normalize(<<"//example.com/#%E5%90%88%E6%B0%97%E9%81%93">>, [return_map]). + +normalize_pct_encoded_userinfo(_Config) -> + #{scheme := "user", path := "合@気道"} = + uri_string:normalize("user:%E5%90%88@%E6%B0%97%E9%81%93", [return_map]), + #{path := "合気道@"} = + uri_string:normalize("%E5%90%88%E6%B0%97%E9%81%93@", [return_map]), + #{path := "/合気道@"} = + uri_string:normalize("/%E5%90%88%E6%B0%97%E9%81%93@", [return_map]), + #{path := "合@気道"} = + uri_string:normalize("%E5%90%88@%E6%B0%97%E9%81%93", [return_map]), + #{userinfo := "合", host := "気道"} = + uri_string:normalize("//%E5%90%88@%E6%B0%97%E9%81%93", [return_map]), + #{userinfo := "合:気", host := "道"} = + uri_string:normalize("//%E5%90%88:%E6%B0%97@%E9%81%93", [return_map]), + #{scheme := "foo", path := "/合気道@"} = + uri_string:normalize("foo:/%E5%90%88%E6%B0%97%E9%81%93@", [return_map]), + #{scheme := "foo", userinfo := "合", host := "気道"} = + uri_string:normalize("foo://%E5%90%88@%E6%B0%97%E9%81%93", [return_map]), + #{scheme := "foo", userinfo := "合:気", host := "道"} = + uri_string:normalize("foo://%E5%90%88:%E6%B0%97@%E9%81%93", [return_map]), + {error,invalid_uri,"@"} = + uri_string:normalize("//%E5%90%88@%E6%B0%97%E9%81%93@", [return_map]), + {error,invalid_uri,":"} = + uri_string:normalize("foo://%E5%90%88@%E6%B0%97%E9%81%93@", [return_map]). + +normalize_pct_encoded_query(_Config) -> + #{scheme := "foo", host := "example.com", path := "/", + query := "name=合気道"} = + uri_string:normalize("foo://example.com/?name=%E5%90%88%E6%B0%97%E9%81%93", [return_map]), + #{host := "example.com", path := "/", query := "name=合気道"} = + uri_string:normalize("//example.com/?name=%E5%90%88%E6%B0%97%E9%81%93", [return_map]). + +normalize_pct_encoded_fragment(_Config) -> + #{scheme := "foo", host := "example.com", fragment := "合気道"} = + uri_string:normalize("foo://example.com#%E5%90%88%E6%B0%97%E9%81%93", [return_map]), + #{host := "example.com", path := "/", fragment := "合気道"} = + uri_string:normalize("//example.com/#%E5%90%88%E6%B0%97%E9%81%93", [return_map]). interop_query_utf8(_Config) -> Q = uri_string:compose_query([{"foo bar","1"}, {"合", "2"}]), @@ -977,3 +1079,86 @@ interop_query_latin1(_Config) -> Uri1 = uri_string:transcode(Uri, [{in_encoding, latin1}]), #{query := Q1} = uri_string:parse(Uri1), [{"foo bar","1"}, {"合", "2"}] = uri_string:dissect_query(Q1). + +regression_parse(_Config) -> + #{host := "Bar",path := [],scheme := "FOo"} = + uri_string:parse("FOo://Bar"), + #{host := "bar",path := [],scheme := "foo"} = + uri_string:parse("foo://bar"), + #{host := "A%2f",path := "/%62ar",scheme := "foo"} = + uri_string:parse("foo://A%2f/%62ar"), + #{host := "a%2F",path := "/bar",scheme := "foo"} = + uri_string:parse("foo://a%2F/bar"), + #{host := "%C3%B6",path := [],scheme := "FOo"} = + uri_string:parse("FOo://%C3%B6"). + +regression_recompose(_Config) -> + "FOo://Bar" = + uri_string:recompose(#{host => "Bar",path => [],scheme => "FOo"}), + "foo://bar" = + uri_string:recompose(#{host => "bar",path => [],scheme => "foo"}), + "foo://A%2f/%62ar" = + uri_string:recompose(#{host => "A%2f",path => "/%62ar",scheme => "foo"}), + "foo://a%2F/bar" = + uri_string:recompose(#{host => "a%2F",path => "/bar",scheme => "foo"}), + "FOo://%C3%B6" = + uri_string:recompose(#{host => "%C3%B6",path => [],scheme => "FOo"}), + "FOo://%C3%B6" = + uri_string:recompose(#{host => "ö",path => [],scheme => "FOo"}). + +regression_normalize(_Config) -> + "foo://bar" = + uri_string:normalize("FOo://Bar"), + #{host := "bar",path := [],scheme := "foo"} = + uri_string:normalize("FOo://Bar", [return_map]), + + "foo://bar" = + uri_string:normalize("foo://bar"), + #{host := "bar",path := [],scheme := "foo"} = + uri_string:normalize("foo://bar", [return_map]), + + "foo://a%2F/bar" = + uri_string:normalize("foo://A%2f/%62ar"), + #{host := "a%2F",path := "/bar",scheme := "foo"} = + uri_string:normalize("foo://A%2f/%62ar", [return_map]), + + "foo://a%2F/bar" = + uri_string:normalize("foo://a%2F/bar"), + #{host := "a%2F",path := "/bar",scheme := "foo"} = + uri_string:normalize("foo://a%2F/bar", [return_map]), + + "foo://%C3%B6" = + uri_string:normalize("FOo://%C3%B6"), + #{host := "ö",path := [],scheme := "foo"} = + uri_string:normalize("FOo://%C3%B6", [return_map]), + + + "foo://bar" = + uri_string:normalize(#{host => "Bar",path => [],scheme => "FOo"}), + #{host := "bar",path := [],scheme := "foo"} = + uri_string:normalize(#{host => "Bar",path => [],scheme => "FOo"}, [return_map]), + + "foo://bar" = + uri_string:normalize(#{host => "bar",path => [],scheme => "foo"}), + #{host := "bar",path := [],scheme := "foo"} = + uri_string:normalize(#{host => "bar",path => [],scheme => "foo"}, [return_map]), + + "foo://a%2F/bar" = + uri_string:normalize(#{host => "A%2f",path => "/%62ar",scheme => "foo"}), + #{host := "a%2F",path := "/bar",scheme := "foo"} = + uri_string:normalize(#{host => "A%2f",path => "/%62ar",scheme => "foo"}, [return_map]), + + "foo://a%2F/bar" = + uri_string:normalize(#{host => "a%2F",path => "/bar",scheme => "foo"}), + #{host := "a%2F",path := "/bar",scheme := "foo"} = + uri_string:normalize(#{host => "a%2F",path => "/bar",scheme => "foo"}, [return_map]), + + "foo://%C3%B6" = + uri_string:normalize(#{host => "%C3%B6",path => [],scheme => "FOo"}), + #{host := "ö",path := [],scheme := "foo"} = + uri_string:normalize(#{host => "%C3%B6",path => [],scheme => "FOo"}, [return_map]), + + "foo://%C3%B6" = + uri_string:normalize(#{host => "ö",path => [],scheme => "FOo"}), + #{host := "ö",path := [],scheme := "foo"} = + uri_string:normalize(#{host => "ö",path => [],scheme => "FOo"}, [return_map]). diff --git a/lib/stdlib/test/uri_string_property_test_SUITE.erl b/lib/stdlib/test/uri_string_property_test_SUITE.erl index ae2c61c7aa..b01dd9bf65 100644 --- a/lib/stdlib/test/uri_string_property_test_SUITE.erl +++ b/lib/stdlib/test/uri_string_property_test_SUITE.erl @@ -22,7 +22,7 @@ -include_lib("common_test/include/ct.hrl"). -compile(export_all). -all() -> [recompose]. +all() -> [recompose, normalize]. init_per_suite(Config) -> ct_property_test:init_per_suite(Config). @@ -37,3 +37,8 @@ recompose(Config) -> ct_property_test:quickcheck( uri_string_recompose:prop_recompose(), Config). + +normalize(Config) -> + ct_property_test:quickcheck( + uri_string_recompose:prop_normalize(), + Config). diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index 0525b2de0b..09a4d6fb50 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1 +1 @@ -STDLIB_VSN = 3.5 +STDLIB_VSN = 3.4.5 diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml index 4ff23aaaca..bd2bcde2c2 100644 --- a/lib/syntax_tools/doc/src/notes.xml +++ b/lib/syntax_tools/doc/src/notes.xml @@ -32,21 +32,6 @@ <p>This document describes the changes made to the Syntax_Tools application.</p> -<section><title>Syntax_Tools 2.1.5</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Update to use the new string api instead of the old.</p> - <p> - Own Id: OTP-15036</p> - </item> - </list> - </section> - -</section> - <section><title>Syntax_Tools 2.1.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl index b816c0699c..029f1e88ac 100644 --- a/lib/syntax_tools/src/erl_syntax.erl +++ b/lib/syntax_tools/src/erl_syntax.erl @@ -5328,7 +5328,7 @@ revert_map_type_assoc(Node) -> Pos = get_pos(Node), Name = map_type_assoc_name(Node), Value = map_type_assoc_value(Node), - {type, Pos, map_type_assoc, [Name, Value]}. + {type, Pos, map_field_assoc, [Name, Value]}. %% ===================================================================== @@ -5386,7 +5386,7 @@ revert_map_type_exact(Node) -> Pos = get_pos(Node), Name = map_type_exact_name(Node), Value = map_type_exact_value(Node), - {type, Pos, map_type_exact, [Name, Value]}. + {type, Pos, map_field_exact, [Name, Value]}. %% ===================================================================== diff --git a/lib/syntax_tools/test/syntax_tools_SUITE.erl b/lib/syntax_tools/test/syntax_tools_SUITE.erl index ae2c67c03e..c8e6448d37 100644 --- a/lib/syntax_tools/test/syntax_tools_SUITE.erl +++ b/lib/syntax_tools/test/syntax_tools_SUITE.erl @@ -24,13 +24,14 @@ %% Test cases -export([app_test/1,appup_test/1,smoke_test/1,revert/1,revert_map/1, + revert_map_type/1, t_abstract_type/1,t_erl_parse_type/1,t_epp_dodger/1, t_comment_scan/1,t_igor/1,t_erl_tidy/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [app_test,appup_test,smoke_test,revert,revert_map, + [app_test,appup_test,smoke_test,revert,revert_map,revert_map_type, t_abstract_type,t_erl_parse_type,t_epp_dodger, t_comment_scan,t_igor,t_erl_tidy]. @@ -121,7 +122,26 @@ revert_map(Config) when is_list(Config) -> {map_field_assoc,{atom,17,name},{var,18,'Value'}}}]), ?t:timetrap_cancel(Dog). - +%% Testing bug fix for reverting map_field_assoc in types +revert_map_type(Config) when is_list(Config) -> + Dog = ?t:timetrap(?t:minutes(1)), + Form1 = {attribute,4,record, + {state, + [{typed_record_field, + {record_field,5,{atom,5,x}}, + {type,5,map, + [{type,5,map_field_exact,[{atom,5,y},{atom,5,z}]}]}}]}}, + Mapped1 = erl_syntax_lib:map(fun(X) -> X end, Form1), + Form1 = erl_syntax:revert(Mapped1), + Form2 = {attribute,4,record, + {state, + [{typed_record_field, + {record_field,5,{atom,5,x}}, + {type,5,map, + [{type,5,map_field_assoc,[{atom,5,y},{atom,5,z}]}]}}]}}, + Mapped2 = erl_syntax_lib:map(fun(X) -> X end, Form2), + Form2 = erl_syntax:revert(Mapped2), + ?t:timetrap_cancel(Dog). %% api tests diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk index 4d13267f16..8d37c40742 100644 --- a/lib/syntax_tools/vsn.mk +++ b/lib/syntax_tools/vsn.mk @@ -1 +1 @@ -SYNTAX_TOOLS_VSN = 2.1.5 +SYNTAX_TOOLS_VSN = 2.1.4 diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml index 6452080572..45f276c09e 100644 --- a/lib/tools/doc/src/notes.xml +++ b/lib/tools/doc/src/notes.xml @@ -31,27 +31,6 @@ </header> <p>This document describes the changes made to the Tools application.</p> -<section><title>Tools 3.0</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>Added <c>instrument:allocations</c> and - <c>instrument:carriers</c> for retrieving information - about memory utilization and fragmentation.</p> - <p>The old <c>instrument</c> interface has been removed, - as have the related options <c>+Mim</c> and - <c>+Mis</c>.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14961</p> - </item> - </list> - </section> - -</section> - <section><title>Tools 2.11.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index bb3f4c66c0..f9723c0f9b 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -1 +1 @@ -TOOLS_VSN = 3.0 +TOOLS_VSN = 2.11.2 diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml index ffe05726c4..69ea906ec0 100644 --- a/lib/wx/doc/src/notes.xml +++ b/lib/wx/doc/src/notes.xml @@ -32,22 +32,6 @@ <p>This document describes the changes made to the wxErlang application.</p> -<section><title>Wx 1.8.4</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Changed implementation so wx can now be built towards - wxWidgets-3.1.1.</p> - <p> - Own Id: OTP-15027</p> - </item> - </list> - </section> - -</section> - <section><title>Wx 1.8.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk index 37a5477631..7da4529c98 100644 --- a/lib/wx/vsn.mk +++ b/lib/wx/vsn.mk @@ -1 +1 @@ -WX_VSN = 1.8.4 +WX_VSN = 1.8.3 diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml index 6959bb77c7..f62a8dc53d 100644 --- a/lib/xmerl/doc/src/notes.xml +++ b/lib/xmerl/doc/src/notes.xml @@ -32,21 +32,6 @@ <p>This document describes the changes made to the Xmerl application.</p> -<section><title>Xmerl 1.3.17</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Fix typos in documentation.</p> - <p> - Own Id: OTP-15039</p> - </item> - </list> - </section> - -</section> - <section><title>Xmerl 1.3.16</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk index be11935f2f..ddff0c8894 100644 --- a/lib/xmerl/vsn.mk +++ b/lib/xmerl/vsn.mk @@ -1 +1 @@ -XMERL_VSN = 1.3.17 +XMERL_VSN = 1.3.16 diff --git a/make/otp_release_targets.mk b/make/otp_release_targets.mk index 779aaa1a1e..d1fbf6c58f 100644 --- a/make/otp_release_targets.mk +++ b/make/otp_release_targets.mk @@ -36,9 +36,13 @@ endif # ------------------------------------------------------- # Take the XML files and add the github link info to them # ------------------------------------------------------- +ifneq ($(strip $(XMLDIR)),) _create_xml_dirs := $(shell mkdir -p $(XMLDIR)) +endif XML_GEN_FILES+=$(patsubst %.xml,$(XMLDIR)/%.xml,$(XML_FILES)) + +ifeq ($(strip $(NO_GITHUB_DOC_LINKS)),) $(XMLDIR)/%.xml: %.xml $(gen_verbose)escript $(DOCGEN)/priv/bin/github_link.escript $< \ "$(subst $(ERL_TOP)/,,$(CURDIR)/$^)" "NA" $@ @@ -46,6 +50,13 @@ $(XMLDIR)/%.xml: %.xml $(XMLDIR)/%.xmlsrc: %.xmlsrc $(gen_verbose)escript $(DOCGEN)/priv/bin/github_link.escript $< \ "$(subst $(ERL_TOP)/,,$(CURDIR)/$^)" "NA" $@ +else +## Just copy the files if the application does not want github edit links +$(XMLDIR)/%.xml: %.xml + $(gen_verbose)$(CP) $< $@ +$(XMLDIR)/%.xmlsrc: %.xmlsrc + $(gen_verbose)$(CP) $< $@ +endif ifeq ($(TOPDOC),) diff --git a/otp_versions.table b/otp_versions.table index dd84a8203d..22762f0691 100644 --- a/otp_versions.table +++ b/otp_versions.table @@ -1,4 +1,4 @@ -OTP-21.0 : asn1-5.0.6 common_test-1.16 compiler-7.2 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 erts-10.0 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 mnesia-4.15.4 observer-2.8 os_mon-2.4.5 parsetools-2.1.7 public_key-1.6 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 ssh-4.7 ssl-9.0 stdlib-3.5 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 # megaco-3.18.3 odbc-2.12.1 otp_mibs-1.1.2 snmp-5.2.10 : +OTP-20.3.7 : erl_docgen-0.7.3 erts-9.3.2 inets-6.5.2 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_interface-3.10.2 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.10 ssh-4.6.9 ssl-8.2.6 stdlib-3.4.5 syntax_tools-2.1.4 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : OTP-20.3.6 : crypto-4.2.2 ssh-4.6.9 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.2 erl_interface-3.10.2 erts-9.3.1 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4 inets-6.5.1 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.10 ssl-8.2.6 stdlib-3.4.5 syntax_tools-2.1.4 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : OTP-20.3.5 : erts-9.3.1 ssl-8.2.6 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.1 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.2 erl_interface-3.10.2 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4 inets-6.5.1 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.10 ssh-4.6.8 stdlib-3.4.5 syntax_tools-2.1.4 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : OTP-20.3.4 : erl_interface-3.10.2 ic-4.4.4 inets-6.5.1 ssh-4.6.8 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.1 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.2 erts-9.3 et-1.6.1 eunit-2.3.5 hipe-3.17.1 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.10 ssl-8.2.5 stdlib-3.4.5 syntax_tools-2.1.4 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : diff --git a/system/doc/efficiency_guide/advanced.xml b/system/doc/efficiency_guide/advanced.xml index 83b87a3641..fe77ce8ea4 100644 --- a/system/doc/efficiency_guide/advanced.xml +++ b/system/doc/efficiency_guide/advanced.xml @@ -188,11 +188,6 @@ limit can be raised or lowered using the <c>+t</c> option.</cell> </row> <row> - <cell>Ets tables</cell> - <cell>Default is 1400. It can be changed with the environment - variable <c>ERL_MAX_ETS_TABLES</c>.</cell> - </row> - <row> <cell>Elements in a tuple</cell> <cell>The maximum number of elements in a tuple is 16,777,215 (24-bit unsigned integer).</cell> diff --git a/system/doc/system_principles/error_logging.xml b/system/doc/system_principles/error_logging.xml index 9d95ce8f3b..9290a1de17 100644 --- a/system/doc/system_principles/error_logging.xml +++ b/system/doc/system_principles/error_logging.xml @@ -62,46 +62,48 @@ Error in process <0.27.0> with exit value: {{badmatch,[1,2,3]},[{m,f,1},{shell,e <p>The standard behaviours (<c>supervisor</c>, <c>gen_server</c>, and so on) send progress and error information to Logger. Progress reports are by default not logged, but can be - enabled by setting the Kernel configuration - parameter <c>logger_progress_reports</c> to <c>log</c>. Supervisor - reports, crash reports and other error and information reports - are by default logged through the log handler which is - set up when the Kernel application is started.</p> + enabled by setting the primary log level to <c>info</c>, for + example by using the Kernel configuration + parameter <c>logger_level</c>. Supervisor reports, crash reports + and other error and information reports are by default logged + through the log handler which is set up when the Kernel + application is started.</p> <p>Prior to Erlang/OTP 21.0, supervisor, crash, and progress reports were only logged when the SASL application was running. This behaviour can, for backwards compatibility, be enabled by setting the Kernel configuration - parameter <c>logger_sasl_compatible</c> to <c>true</c>. For more - information, see + parameter <seealso marker="kernel:kernel_app#logger_sasl_compatible"> + <c>logger_sasl_compatible</c></seealso> + to <c>true</c>. For more information, see <seealso marker="sasl:error_logging">SASL Error Logging</seealso> in the SASL User's Guide.</p> <pre> -% <input>erl -kernel logger_progress_reports log</input> -Erlang/OTP 21 [erts-10.0] [source-76388a1] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] +% <input>erl -kernel logger_level info</input> +Erlang/OTP 21 [erts-10.0] [source-13c50db] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] -=PROGRESS REPORT==== 18-May-2018::21:33:41.705292 === +=PROGRESS REPORT==== 8-Jun-2018::16:54:19.916404 === application: kernel started_at: nonode@nohost -=PROGRESS REPORT==== 18-May-2018::21:33:41.708900 === +=PROGRESS REPORT==== 8-Jun-2018::16:54:19.922908 === application: stdlib started_at: nonode@nohost -=PROGRESS REPORT==== 18-May-2018::21:33:41.726003 === +=PROGRESS REPORT==== 8-Jun-2018::16:54:19.925755 === supervisor: {local,kernel_safe_sup} - started: [{pid,<0.75.0>}, + started: [{pid,<0.74.0>}, {id,disk_log_sup}, {mfargs,{disk_log_sup,start_link,[]}}, {restart_type,permanent}, {shutdown,1000}, {child_type,supervisor}] -=PROGRESS REPORT==== 18-May-2018::21:33:41.726348 === +=PROGRESS REPORT==== 8-Jun-2018::16:54:19.926056 === supervisor: {local,kernel_safe_sup} - started: [{pid,<0.76.0>}, + started: [{pid,<0.75.0>}, {id,disk_log_server}, {mfargs,{disk_log_server,start_link,[]}}, {restart_type,permanent}, {shutdown,2000}, {child_type,worker}] -Eshell V9.3.1 (abort with ^G) +Eshell V10.0 (abort with ^G) 1> </pre> </section> </chapter> diff --git a/xcomp/erl-xcomp-armv8-rpi3-linux-gnueabihf.conf b/xcomp/erl-xcomp-armv8-rpi3-linux-gnueabihf.conf new file mode 100644 index 0000000000..dffc4a4b56 --- /dev/null +++ b/xcomp/erl-xcomp-armv8-rpi3-linux-gnueabihf.conf @@ -0,0 +1,276 @@ +## -*-shell-script-*- +## +## %CopyrightBegin% +## +## Copyright Ericsson AB 2009-2018. All Rights Reserved. +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## +## %CopyrightEnd% +## +## File: erl-xcomp-armv8-rpi3-linux-gnueabihf.conf +## Author: Péter Dimitrov +## Tested: macOS High Sierra 10.13.2 / +## Raspberry Pi 3 Model B Rev 1.2 +## +## ----------------------------------------------------------------------------- +## When cross compiling Erlang/OTP using `otp_build', copy this file and set +## the variables needed below. Then pass the path to the copy of this file as +## an argument to `otp_build' in the configure stage: +## `otp_build configure --xcomp-conf=<FILE>' +## ----------------------------------------------------------------------------- + +## Note that you cannot define arbitrary variables in a cross compilation +## configuration file. Only the ones listed below will be guaranteed to be +## visible throughout the whole execution of all `configure' scripts. Other +## variables needs to be defined as arguments to `configure' or exported in +## the environment. + +## -- Variables for `otp_build' Only ------------------------------------------- + +## Variables in this section are only used, when configuring Erlang/OTP for +## cross compilation using `$ERL_TOP/otp_build configure'. + +## *NOTE*! These variables currently have *no* effect if you configure using +## the `configure' script directly. + +# * `erl_xcomp_build' - The build system used. This value will be passed as +# `--build=$erl_xcomp_build' argument to the `configure' script. It does +# not have to be a full `CPU-VENDOR-OS' triplet, but can be. The full +# `CPU-VENDOR-OS' triplet will be created by +# `$ERL_TOP/erts/autoconf/config.sub $erl_xcomp_build'. If set to `guess', +# the build system will be guessed using +# `$ERL_TOP/erts/autoconf/config.guess'. +erl_xcomp_build=guess + +# * `erl_xcomp_host' - Cross host/target system to build for. This value will +# be passed as `--host=$erl_xcomp_host' argument to the `configure' script. +# It does not have to be a full `CPU-VENDOR-OS' triplet, but can be. The +# full `CPU-VENDOR-OS' triplet will be created by +# `$ERL_TOP/erts/autoconf/config.sub $erl_xcomp_host'. +erl_xcomp_host=armv8-rpi3-linux-gnueabihf + +# * `erl_xcomp_configure_flags' - Extra configure flags to pass to the +# `configure' script. +#erl_xcomp_configure_flags= + +## -- Cross Compiler and Other Tools ------------------------------------------- + +## If the cross compilation tools are prefixed by `<HOST>-' you probably do +## not need to set these variables (where `<HOST>' is what has been passed as +## `--host=<HOST>' argument to `configure'). + +## All variables in this section can also be used when native compiling. + +# * `CC' - C compiler. +CC=armv8-rpi3-linux-gnueabihf-gcc + +# * `CFLAGS' - C compiler flags. +#CFLAGS= + +# * `STATIC_CFLAGS' - Static C compiler flags. +#STATIC_CFLAGS= + +# * `CFLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library +# search path for the shared libraries. Note that this actually is a +# linker flag, but it needs to be passed via the compiler. +#CFLAG_RUNTIME_LIBRARY_PATH= + +# * `CPP' - C pre-processor. +CPP=armv8-rpi3-linux-gnueabihf-cpp + +# * `CPPFLAGS' - C pre-processor flags. +#CPPFLAGS= + +# * `CXX' - C++ compiler. +CXX=armv8-rpi3-linux-gnueabihf-g++ + +# * `CXXFLAGS' - C++ compiler flags. +#CXXFLAGS= + +# * `LD' - Linker. +LD=armv8-rpi3-linux-gnueabihf-ld + +# * `LDFLAGS' - Linker flags. +LDFLAGS="-L$RPI_SYSROOT/lib" + +# * `LIBS' - Libraries. +#LIBS= + +## -- *D*ynamic *E*rlang *D*river Linking -- + +## *NOTE*! Either set all or none of the `DED_LD*' variables. + +# * `DED_LD' - Linker for Dynamically loaded Erlang Drivers. +#DED_LD= + +# * `DED_LDFLAGS' - Linker flags to use with `DED_LD'. +#DED_LDFLAGS= + +# * `DED_LD_FLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library +# search path for shared libraries when linking with `DED_LD'. +#DED_LD_FLAG_RUNTIME_LIBRARY_PATH= + +## -- Large File Support -- + +## *NOTE*! Either set all or none of the `LFS_*' variables. + +# * `LFS_CFLAGS' - Large file support C compiler flags. +#LFS_CFLAGS= + +# * `LFS_LDFLAGS' - Large file support linker flags. +#LFS_LDFLAGS= + +# * `LFS_LIBS' - Large file support libraries. +#LFS_LIBS= + +## -- Other Tools -- + +# * `RANLIB' - `ranlib' archive index tool. +RANLIB=armv8-rpi3-linux-gnueabihf-ranlib + +# * `AR' - `ar' archiving tool. +AR=armv8-rpi3-linux-gnueabihf-ar + +# * `GETCONF' - `getconf' system configuration inspection tool. `getconf' is +# currently used for finding out large file support flags to use, and +# on Linux systems for finding out if we have an NPTL thread library or +# not. +#GETCONF= + +## -- Cross System Root Locations ---------------------------------------------- + +# * `erl_xcomp_sysroot' - The absolute path to the system root of the cross +# compilation environment. Currently, the `crypto', `odbc', `ssh' and +# `ssl' applications need the system root. These applications will be +# skipped if the system root has not been set. The system root might be +# needed for other things too. If this is the case and the system root +# has not been set, `configure' will fail and request you to set it. +erl_xcomp_sysroot="$RPI_SYSROOT" + +# * `erl_xcomp_isysroot' - The absolute path to the system root for includes +# of the cross compilation environment. If not set, this value defaults +# to `$erl_xcomp_sysroot', i.e., only set this value if the include system +# root path is not the same as the system root path. +#erl_xcomp_isysroot= + +## -- Optional Feature, and Bug Tests ------------------------------------------ + +## These tests cannot (always) be done automatically when cross compiling. You +## usually do not need to set these variables. Only set these if you really +## know what you are doing. + +## Note that some of these values will override results of tests performed +## by `configure', and some will not be used until `configure' is sure that +## it cannot figure the result out. + +## The `configure' script will issue a warning when a default value is used. +## When a variable has been set, no warning will be issued. + +# * `erl_xcomp_after_morecore_hook' - `yes|no'. Defaults to `no'. If `yes', +# the target system must have a working `__after_morecore_hook' that can be +# used for tracking used `malloc()' implementations core memory usage. +# This is currently only used by unsupported features. +#erl_xcomp_after_morecore_hook= + +# * `erl_xcomp_bigendian' - `yes|no'. No default. If `yes', the target system +# must be big endian. If `no', little endian. This can often be +# automatically detected, but not always. If not automatically detected, +# `configure' will fail unless this variable is set. Since no default +# value is used, `configure' will try to figure this out automatically. +#erl_xcomp_bigendian= + +# * `erl_xcomp_double_middle` - `yes|no`. No default. If `yes`, the +# target system must have doubles in "middle-endian" format. If +# `no`, it has "regular" endianness. This can often be automatically +# detected, but not always. If not automatically detected, +# `configure` will fail unless this variable is set. Since no +# default value is used, `configure` will try to figure this out +# automatically. +#erl_xcomp_double_middle_endian + +# * `erl_xcomp_clock_gettime_cpu_time' - `yes|no'. Defaults to `no'. If `yes', +# the target system must have a working `clock_gettime()' implementation +# that can be used for retrieving process CPU time. +#erl_xcomp_clock_gettime_cpu_time= + +# * `erl_xcomp_getaddrinfo' - `yes|no'. Defaults to `no'. If `yes', the target +# system must have a working `getaddrinfo()' implementation that can +# handle both IPv4 and IPv6. +#erl_xcomp_getaddrinfo= + +# * `erl_xcomp_gethrvtime_procfs_ioctl' - `yes|no'. Defaults to `no'. If `yes', +# the target system must have a working `gethrvtime()' implementation and +# is used with procfs `ioctl()'. +#erl_xcomp_gethrvtime_procfs_ioctl= + +# * `erl_xcomp_dlsym_brk_wrappers' - `yes|no'. Defaults to `no'. If `yes', the +# target system must have a working `dlsym(RTLD_NEXT, <S>)' implementation +# that can be used on `brk' and `sbrk' symbols used by the `malloc()' +# implementation in use, and by this track the `malloc()' implementations +# core memory usage. This is currently only used by unsupported features. +#erl_xcomp_dlsym_brk_wrappers= + +# * `erl_xcomp_kqueue' - `yes|no'. Defaults to `no'. If `yes', the target +# system must have a working `kqueue()' implementation that returns a file +# descriptor which can be used by `poll()' and/or `select()'. If `no' and +# the target system has not got `epoll()' or `/dev/poll', the kernel-poll +# feature will be disabled. +#erl_xcomp_kqueue= + +# * `erl_xcomp_linux_clock_gettime_correction' - `yes|no'. Defaults to `yes' on +# Linux; otherwise, `no'. If `yes', `clock_gettime(CLOCK_MONOTONIC, _)' on +# the target system must work. This variable is recommended to be set to +# `no' on Linux systems with kernel versions less than 2.6. +#erl_xcomp_linux_clock_gettime_correction= + +# * `erl_xcomp_linux_nptl' - `yes|no'. Defaults to `yes' on Linux; otherwise, +# `no'. If `yes', the target system must have NPTL (Native POSIX Thread +# Library). Older Linux systems have LinuxThreads instead of NPTL (Linux +# kernel versions typically less than 2.6). +#erl_xcomp_linux_nptl= + +# * `erl_xcomp_linux_usable_sigaltstack' - `yes|no'. Defaults to `yes' on Linux; +# otherwise, `no'. If `yes', `sigaltstack()' must be usable on the target +# system. `sigaltstack()' on Linux kernel versions less than 2.4 are +# broken. +#erl_xcomp_linux_usable_sigaltstack= + +# * `erl_xcomp_linux_usable_sigusrx' - `yes|no'. Defaults to `yes'. If `yes', +# the `SIGUSR1' and `SIGUSR2' signals must be usable by the ERTS. Old +# LinuxThreads thread libraries (Linux kernel versions typically less than +# 2.2) used these signals and made them unusable by the ERTS. +#erl_xcomp_linux_usable_sigusrx= + +# * `erl_xcomp_poll' - `yes|no'. Defaults to `no' on Darwin/MacOSX; otherwise, +# `yes'. If `yes', the target system must have a working `poll()' +# implementation that also can handle devices. If `no', `select()' will be +# used instead of `poll()'. +#erl_xcomp_poll= + +# * `erl_xcomp_putenv_copy' - `yes|no'. Defaults to `no'. If `yes', the target +# system must have a `putenv()' implementation that stores a copy of the +# key/value pair. +#erl_xcomp_putenv_copy= + +# * `erl_xcomp_reliable_fpe' - `yes|no'. Defaults to `no'. If `yes', the target +# system must have reliable floating point exceptions. +#erl_xcomp_reliable_fpe= + +# * `erl_xcomp_posix_memalign' - `yes|no'. Defaults to `yes' if `posix_memalign' +# system call exists; otherwise `no'. If `yes', the target system must have a +# `posix_memalign' implementation that accepts larger than page size +# alignment. +#erl_xcomp_posix_memalign= + +## ----------------------------------------------------------------------------- |