aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in38
-rw-r--r--erts/configure.in107
-rw-r--r--erts/doc/src/erl.xml20
-rw-r--r--erts/doc/src/erl_driver.xml8
-rw-r--r--erts/doc/src/erl_nif.xml4
-rw-r--r--erts/doc/src/erlang.xml240
-rw-r--r--erts/doc/src/erlc.xml10
-rw-r--r--erts/doc/src/notes.xml8
-rw-r--r--erts/emulator/Makefile.in18
-rw-r--r--erts/emulator/beam/atom.c12
-rw-r--r--erts/emulator/beam/atom.h21
-rw-r--r--erts/emulator/beam/atom.names12
-rw-r--r--erts/emulator/beam/beam_emu.c38
-rw-r--r--erts/emulator/beam/bif.c72
-rw-r--r--erts/emulator/beam/bif.tab15
-rw-r--r--erts/emulator/beam/erl_arith.c43
-rw-r--r--erts/emulator/beam/erl_bif_guard.c14
-rw-r--r--erts/emulator/beam/erl_bif_info.c91
-rw-r--r--erts/emulator/beam/erl_bif_re.c15
-rw-r--r--erts/emulator/beam/erl_db_tree.c14
-rw-r--r--erts/emulator/beam/erl_debug.c14
-rw-r--r--erts/emulator/beam/erl_gc.c252
-rw-r--r--erts/emulator/beam/erl_init.c154
-rw-r--r--erts/emulator/beam/erl_lock_check.c13
-rw-r--r--erts/emulator/beam/erl_message.c24
-rw-r--r--erts/emulator/beam/erl_message.h23
-rw-r--r--erts/emulator/beam/erl_port_task.c58
-rw-r--r--erts/emulator/beam/erl_process.c99
-rw-r--r--erts/emulator/beam/erl_process.h36
-rw-r--r--erts/emulator/beam/erl_time_sup.c14
-rw-r--r--erts/emulator/beam/erl_trace.c29
-rw-r--r--erts/emulator/beam/erl_vm.h80
-rw-r--r--erts/emulator/beam/external.c283
-rw-r--r--erts/emulator/beam/external.h26
-rw-r--r--erts/emulator/beam/global.h11
-rw-r--r--erts/emulator/beam/utils.c60
-rw-r--r--erts/emulator/hipe/hipe_bif0.c123
-rw-r--r--erts/emulator/test/binary_SUITE.erl46
-rw-r--r--erts/emulator/test/fun_SUITE.erl18
-rw-r--r--erts/emulator/test/process_SUITE.erl54
-rw-r--r--erts/emulator/test/scheduler_SUITE.erl110
-rw-r--r--erts/emulator/test/statistics_SUITE.erl75
-rw-r--r--erts/emulator/test/system_info_SUITE.erl27
-rw-r--r--erts/emulator/test/trace_SUITE.erl77
-rw-r--r--erts/epmd/src/epmd_int.h11
-rw-r--r--erts/epmd/src/epmd_srv.c28
-rw-r--r--erts/epmd/test/Makefile24
-rw-r--r--erts/epmd/test/epmd_SUITE.erl160
-rw-r--r--erts/etc/common/erlc.c13
-rw-r--r--erts/etc/common/erlexec.c36
-rw-r--r--erts/lib_src/Makefile.in12
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin48420 -> 50376 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin23284 -> 23284 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin44416 -> 44416 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1392 -> 1392 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin29480 -> 29480 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin57308 -> 57308 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin20756 -> 21756 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin10624 -> 10624 bytes
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl201
-rw-r--r--erts/preloaded/src/prim_zip.erl57
-rw-r--r--erts/test/erl_print_SUITE.erl12
-rw-r--r--erts/test/erlc_SUITE.erl19
-rw-r--r--erts/test/erlexec_SUITE.erl12
-rw-r--r--erts/test/ethread_SUITE.erl12
-rw-r--r--erts/test/ignore_cores.erl12
-rw-r--r--erts/test/nt_SUITE.erl13
-rw-r--r--erts/test/otp_SUITE.erl13
-rw-r--r--erts/test/run_erl_SUITE.erl12
-rw-r--r--erts/test/z_SUITE.erl12
-rw-r--r--lib/appmon/doc/src/Makefile13
-rw-r--r--lib/common_test/doc/src/Makefile20
-rw-r--r--lib/common_test/doc/src/example_chapter.xml12
-rw-r--r--lib/common_test/include/ct.hrl12
-rw-r--r--lib/compiler/doc/src/compile.xml12
-rw-r--r--lib/compiler/src/beam_validator.erl16
-rw-r--r--lib/compiler/src/compile.erl113
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl46
-rw-r--r--lib/compiler/test/error_SUITE.erl30
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/cosFileTransfer/doc/src/notes.xml18
-rw-r--r--lib/cosFileTransfer/vsn.mk3
-rw-r--r--lib/crypto/doc/src/Makefile3
-rw-r--r--lib/crypto/vsn.mk2
-rw-r--r--lib/debugger/src/dbg_ui_mon.erl13
-rw-r--r--lib/debugger/src/dbg_wx_filedialog_win.erl15
-rw-r--r--lib/debugger/src/dbg_wx_mon.erl15
-rw-r--r--lib/debugger/src/dbg_wx_mon_win.erl12
-rwxr-xr-xlib/debugger/src/dbg_wx_trace_win.erl12
-rw-r--r--lib/debugger/src/dbg_wx_win.erl23
-rw-r--r--lib/docbuilder/doc/src/inline_tags.xml8
-rw-r--r--lib/edoc/Makefile6
-rw-r--r--lib/edoc/doc/src/Makefile5
-rw-r--r--lib/edoc/src/Makefile2
-rw-r--r--lib/erl_docgen/priv/bin/Makefile13
-rwxr-xr-xlib/erl_docgen/priv/bin/codeline_preprocessing.escript17
-rwxr-xr-xlib/erl_docgen/priv/bin/xml_from_edoc.escript149
-rw-r--r--lib/erl_docgen/priv/xsl/db_eix.xsl68
-rw-r--r--lib/erl_docgen/priv/xsl/db_html.xsl253
-rw-r--r--lib/erl_docgen/priv/xsl/db_man.xsl242
-rw-r--r--lib/erl_docgen/priv/xsl/db_pdf.xsl99
-rw-r--r--lib/erl_docgen/priv/xsl/db_pdf_params.xsl26
-rw-r--r--lib/erl_interface/src/legacy/erl_eterm.c16
-rw-r--r--lib/erl_interface/vsn.mk2
-rw-r--r--lib/et/doc/src/Makefile24
-rw-r--r--lib/et/doc/src/book.gifbin1081 -> 0 bytes
-rw-r--r--lib/et/doc/src/coffee_order.pngbin0 -> 23692 bytes
-rw-r--r--lib/et/doc/src/et.xml67
-rw-r--r--lib/et/doc/src/et_architecture.xml554
-rw-r--r--lib/et/doc/src/et_collector.xml19
-rw-r--r--lib/et/doc/src/et_desc.xmlsrc683
-rw-r--r--lib/et/doc/src/et_examples.xml311
-rw-r--r--lib/et/doc/src/et_examples.xmlsrc383
-rw-r--r--lib/et/doc/src/et_intro.xml82
-rw-r--r--lib/et/doc/src/et_selector.xml108
-rw-r--r--lib/et/doc/src/et_tutorial.xmlsrc273
-rw-r--r--lib/et/doc/src/et_viewer.xml9
-rw-r--r--lib/et/doc/src/files.mk42
-rw-r--r--lib/et/doc/src/live_trans.gifbin8691 -> 0 bytes
-rw-r--r--lib/et/doc/src/live_trans.pngbin0 -> 19999 bytes
-rw-r--r--lib/et/doc/src/live_trans.ps1559
-rw-r--r--lib/et/doc/src/megaco_collector.gifbin68430 -> 0 bytes
-rw-r--r--lib/et/doc/src/megaco_collector.pngbin0 -> 37915 bytes
-rw-r--r--lib/et/doc/src/megaco_collector.ps3247
-rw-r--r--lib/et/doc/src/megaco_filter.gifbin8827 -> 0 bytes
-rw-r--r--lib/et/doc/src/megaco_filter.pngbin0 -> 19067 bytes
-rw-r--r--lib/et/doc/src/megaco_filter.ps1733
-rw-r--r--lib/et/doc/src/megaco_tracer.gifbin12400 -> 0 bytes
-rw-r--r--lib/et/doc/src/megaco_tracer.pngbin0 -> 46696 bytes
-rw-r--r--lib/et/doc/src/megaco_tracer.ps2508
-rw-r--r--lib/et/doc/src/note.gifbin1539 -> 0 bytes
-rw-r--r--lib/et/doc/src/notes.gifbin2005 -> 0 bytes
-rw-r--r--lib/et/doc/src/notes.xml60
-rw-r--r--lib/et/doc/src/part.xml9
-rw-r--r--lib/et/doc/src/ref_man.gifbin1530 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans.gifbin20208 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans.pngbin0 -> 19026 bytes
-rw-r--r--lib/et/doc/src/sim_trans.ps6595
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_collector.gifbin11607 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_collector.pngbin0 -> 13361 bytes
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_collector.ps1407
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.gifbin7531 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.pngbin0 -> 15235 bytes
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.ps1371
-rw-r--r--lib/et/doc/src/sim_trans_mgr_actors.gifbin9118 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans_mgr_actors.pngbin0 -> 18936 bytes
-rw-r--r--lib/et/doc/src/sim_trans_mgr_actors.ps1705
-rw-r--r--lib/et/doc/src/sim_trans_move_actor.gifbin8965 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans_move_actor.pngbin0 -> 19026 bytes
-rw-r--r--lib/et/doc/src/sim_trans_move_actor.ps6403
-rw-r--r--lib/et/doc/src/sim_trans_write_lock.gifbin10871 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans_write_lock.pngbin0 -> 13425 bytes
-rw-r--r--lib/et/doc/src/sim_trans_write_lock.ps1287
-rw-r--r--lib/et/doc/src/user_guide.gifbin1581 -> 0 bytes
-rw-r--r--lib/et/doc/src/warning.gifbin1498 -> 0 bytes
-rw-r--r--lib/et/examples/Makefile14
-rw-r--r--lib/et/examples/et_demo.erl103
-rw-r--r--lib/et/examples/et_display_demo.erl32
-rw-r--r--lib/et/examples/et_trace_demo.erl38
-rw-r--r--lib/et/src/Makefile17
-rw-r--r--lib/et/src/et.app.src17
-rw-r--r--lib/et/src/et.erl38
-rw-r--r--lib/et/src/et_collector.erl330
-rw-r--r--lib/et/src/et_gs_contents_viewer.erl (renamed from lib/et/src/et_contents_viewer.erl)86
-rw-r--r--lib/et/src/et_gs_viewer.erl1483
-rw-r--r--lib/et/src/et_internal.hrl13
-rw-r--r--lib/et/src/et_selector.erl76
-rw-r--r--lib/et/src/et_viewer.erl1492
-rw-r--r--lib/et/src/et_wx_contents_viewer.erl700
-rw-r--r--lib/et/src/et_wx_viewer.erl2124
-rw-r--r--lib/et/src/modules.mk17
-rw-r--r--lib/et/test/Makefile (renamed from lib/et/doc/src/make.dep)76
-rw-r--r--lib/et/test/README30
-rw-r--r--lib/et/test/et.spec2
-rw-r--r--lib/et/test/et_test_lib.erl329
-rw-r--r--lib/et/test/et_test_lib.hrl90
-rw-r--r--lib/et/test/et_wx_SUITE.erl100
-rwxr-xr-xlib/et/test/ett55
-rw-r--r--lib/et/test/ett.erl154
-rw-r--r--lib/et/vsn.mk15
-rw-r--r--lib/eunit/doc/src/Makefile5
-rw-r--r--lib/eunit/test/Makefile12
-rw-r--r--lib/hipe/Makefile18
-rw-r--r--lib/hipe/amd64/Makefile15
-rw-r--r--lib/hipe/arm/Makefile15
-rw-r--r--lib/hipe/cerl/Makefile15
-rw-r--r--lib/hipe/flow/Makefile15
-rw-r--r--lib/hipe/icode/Makefile15
-rw-r--r--lib/hipe/main/Makefile16
-rw-r--r--lib/hipe/misc/Makefile15
-rw-r--r--lib/hipe/opt/Makefile15
-rw-r--r--lib/hipe/ppc/Makefile15
-rw-r--r--lib/hipe/regalloc/Makefile16
-rw-r--r--lib/hipe/sparc/Makefile15
-rw-r--r--lib/hipe/tools/Makefile15
-rw-r--r--lib/hipe/util/Makefile15
-rw-r--r--lib/hipe/x86/Makefile15
-rw-r--r--lib/inets/Makefile20
-rw-r--r--lib/inets/doc/src/Makefile58
-rw-r--r--lib/inets/doc/src/ftp.xml16
-rw-r--r--lib/inets/doc/src/http_server.xml86
-rw-r--r--lib/inets/doc/src/httpc.xml (renamed from lib/inets/doc/src/http.xml)244
-rw-r--r--lib/inets/doc/src/httpd.xml46
-rw-r--r--lib/inets/doc/src/httpd_util.xml11
-rw-r--r--lib/inets/doc/src/inets.xml8
-rw-r--r--lib/inets/doc/src/make.dep22
-rw-r--r--lib/inets/doc/src/mod_esi.xml8
-rw-r--r--lib/inets/doc/src/notes.xml132
-rw-r--r--lib/inets/doc/src/notes_history.xml24
-rw-r--r--lib/inets/doc/src/ref_man.xml8
-rw-r--r--lib/inets/src/ftp/Makefile18
-rw-r--r--lib/inets/src/http_client/Makefile27
-rw-r--r--lib/inets/src/http_client/http.erl772
-rw-r--r--lib/inets/src/http_client/httpc.erl1079
-rw-r--r--lib/inets/src/http_client/httpc_cookie.erl (renamed from lib/inets/src/http_client/http_cookie.erl)368
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl954
-rw-r--r--lib/inets/src/http_client/httpc_handler_sup.erl31
-rw-r--r--lib/inets/src/http_client/httpc_internal.hrl78
-rw-r--r--lib/inets/src/http_client/httpc_manager.erl799
-rw-r--r--lib/inets/src/http_client/httpc_profile_sup.erl20
-rw-r--r--lib/inets/src/http_client/httpc_request.erl68
-rw-r--r--lib/inets/src/http_client/httpc_response.erl19
-rw-r--r--lib/inets/src/http_lib/Makefile22
-rw-r--r--lib/inets/src/http_lib/http_chunk.erl21
-rw-r--r--lib/inets/src/http_lib/http_transport.erl147
-rw-r--r--lib/inets/src/http_lib/http_util.erl35
-rw-r--r--lib/inets/src/http_server/Makefile15
-rw-r--r--lib/inets/src/http_server/httpd.erl14
-rw-r--r--lib/inets/src/http_server/httpd_conf.erl19
-rw-r--r--lib/inets/src/http_server/httpd_instance_sup.erl16
-rw-r--r--lib/inets/src/http_server/httpd_request.erl17
-rw-r--r--lib/inets/src/http_server/httpd_sup.erl12
-rw-r--r--lib/inets/src/http_server/mod_alias.erl111
-rw-r--r--lib/inets/src/http_server/mod_cgi.erl12
-rw-r--r--lib/inets/src/http_server/mod_esi.erl51
-rw-r--r--lib/inets/src/inets_app/Makefile24
-rw-r--r--lib/inets/src/inets_app/inets.app.src15
-rw-r--r--lib/inets/src/inets_app/inets.appup.src24
-rw-r--r--lib/inets/src/inets_app/inets.erl16
-rw-r--r--lib/inets/src/tftp/Makefile20
-rw-r--r--lib/inets/test/Makefile343
-rw-r--r--lib/inets/test/ftp_SUITE.erl143
-rw-r--r--lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel18
-rw-r--r--lib/inets/test/ftp_format_SUITE.erl341
-rw-r--r--lib/inets/test/ftp_freebsd_x86_test.erl153
l---------lib/inets/test/ftp_internal.hrl1
-rw-r--r--lib/inets/test/ftp_linux_ppc_test.erl151
-rw-r--r--lib/inets/test/ftp_linux_x86_test.erl160
-rw-r--r--lib/inets/test/ftp_macosx_ppc_test.erl152
-rw-r--r--lib/inets/test/ftp_macosx_x86_test.erl152
-rw-r--r--lib/inets/test/ftp_netbsd_x86_test.erl152
-rw-r--r--lib/inets/test/ftp_openbsd_x86_test.erl151
-rw-r--r--lib/inets/test/ftp_solaris10_sparc_test.erl154
-rw-r--r--lib/inets/test/ftp_solaris10_x86_test.erl155
-rw-r--r--lib/inets/test/ftp_solaris8_sparc_test.erl152
-rw-r--r--lib/inets/test/ftp_solaris9_sparc_test.erl151
-rw-r--r--lib/inets/test/ftp_suite_lib.erl1593
-rw-r--r--lib/inets/test/ftp_ticket_test.erl51
-rw-r--r--lib/inets/test/ftp_windows_2003_server_test.erl152
-rw-r--r--lib/inets/test/ftp_windows_xp_test.erl150
-rw-r--r--lib/inets/test/http_format_SUITE.erl585
l---------lib/inets/test/http_internal.hrl1
-rw-r--r--lib/inets/test/httpc_SUITE.erl2954
l---------lib/inets/test/httpc_SUITE_data/Makefile.src1
l---------lib/inets/test/httpc_SUITE_data/cgi_echo.c1
-rw-r--r--lib/inets/test/httpc_SUITE_data/dummy.html12
-rw-r--r--lib/inets/test/httpc_SUITE_data/empty.html (renamed from system/doc/images/.gitignore)0
-rw-r--r--lib/inets/test/httpc_SUITE_data/mime.types465
-rw-r--r--lib/inets/test/httpc_SUITE_data/redirect.html10
-rw-r--r--lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem22
-rw-r--r--lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem22
-rw-r--r--lib/inets/test/httpc_cookie_SUITE.erl451
l---------lib/inets/test/httpc_internal.hrl1
-rw-r--r--lib/inets/test/httpd_1_1.erl494
-rw-r--r--lib/inets/test/httpd_SUITE.erl2081
-rw-r--r--lib/inets/test/httpd_SUITE_data/Makefile.src14
-rw-r--r--lib/inets/test/httpd_SUITE_data/cgi_echo.c97
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/auth/group3
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/auth/passwd4
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.bat9
-rwxr-xr-xlib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.sh6
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf79
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf63
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf268
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types465
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf66
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/config.shtml70
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/echo.shtml35
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/exec.shtml30
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/flastmod.shtml29
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/fsize.shtml29
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/include.shtml33
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/index.html25
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/last_modified.html22
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/friedrich.html7
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/oech.html4
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/welcome.html1
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/open/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/README161
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/a.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/alert.black.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/alert.red.gifbin0 -> 247 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/apache_pb.gifbin0 -> 2326 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/back.gifbin0 -> 216 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/ball.gray.gifbin0 -> 233 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/ball.red.gifbin0 -> 205 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/binary.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/binhex.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/blank.gifbin0 -> 148 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/bomb.gifbin0 -> 308 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/box1.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/box2.gifbin0 -> 268 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/broken.gifbin0 -> 247 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/burst.gifbin0 -> 235 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button1.gifbin0 -> 755 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button10.gifbin0 -> 781 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button2.gifbin0 -> 785 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button3.gifbin0 -> 745 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button4.gifbin0 -> 786 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button5.gifbin0 -> 780 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button6.gifbin0 -> 791 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button7.gifbin0 -> 796 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button8.gifbin0 -> 784 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button9.gifbin0 -> 784 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/buttonl.gifbin0 -> 587 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/buttonr.gifbin0 -> 576 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/c.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/comp.blue.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/comp.gray.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/compressed.gifbin0 -> 1038 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/continued.gifbin0 -> 214 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/dir.gifbin0 -> 225 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/down.gifbin0 -> 163 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/dvi.gifbin0 -> 238 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/f.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/folder.gifbin0 -> 225 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/folder.open.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/folder.sec.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/forward.gifbin0 -> 219 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/generic.gifbin0 -> 221 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/generic.red.gifbin0 -> 220 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/generic.sec.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/hand.right.gifbin0 -> 217 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/hand.up.gifbin0 -> 223 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/htdig.gifbin0 -> 1822 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/icon.sheet.gifbin0 -> 11977 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/image1.gifbin0 -> 274 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/image2.gifbin0 -> 309 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/image3.gifbin0 -> 286 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/index.gifbin0 -> 268 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/layout.gifbin0 -> 276 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/left.gifbin0 -> 172 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/link.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/movie.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/p.gifbin0 -> 237 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/patch.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pdf.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie0.gifbin0 -> 188 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie1.gifbin0 -> 198 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie2.gifbin0 -> 198 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie3.gifbin0 -> 191 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie4.gifbin0 -> 193 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie5.gifbin0 -> 189 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie6.gifbin0 -> 186 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie7.gifbin0 -> 185 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie8.gifbin0 -> 173 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/portal.gifbin0 -> 254 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/poweredby.gifbin0 -> 2748 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/ps.gifbin0 -> 244 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/quill.gifbin0 -> 267 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/right.gifbin0 -> 172 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/screw1.gifbin0 -> 258 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/screw2.gifbin0 -> 263 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/script.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/sound1.gifbin0 -> 248 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/sound2.gifbin0 -> 221 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/sphere1.gifbin0 -> 285 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/sphere2.gifbin0 -> 264 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/star.gifbin0 -> 89 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/star_blank.gifbin0 -> 53 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/tar.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/tex.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/text.gifbin0 -> 229 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/transfer.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/unknown.gifbin0 -> 245 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/up.gifbin0 -> 164 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/uu.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/uuencoded.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/world1.gifbin0 -> 228 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/world2.gifbin0 -> 261 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip1
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem22
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem22
-rw-r--r--lib/inets/test/httpd_basic_SUITE.erl136
-rw-r--r--lib/inets/test/httpd_block.erl299
-rw-r--r--lib/inets/test/httpd_load.erl99
-rw-r--r--lib/inets/test/httpd_mod.erl947
-rw-r--r--lib/inets/test/httpd_poll.erl496
-rw-r--r--lib/inets/test/httpd_test_data/server_root/auth/group3
-rw-r--r--lib/inets/test/httpd_test_data/server_root/auth/passwd4
-rw-r--r--lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.bat9
-rwxr-xr-xlib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.sh6
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/8080.conf79
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/8888.conf63
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/httpd.conf268
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/mime.types465
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/ssl.conf66
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/config.shtml70
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/dets_open/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/echo.shtml35
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/exec.shtml30
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/flastmod.shtml29
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/fsize.shtml29
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/include.shtml33
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/index.html25
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/last_modified.html22
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/misc/friedrich.html7
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/misc/oech.html4
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/misc/welcome.html1
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_open/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/open/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/README161
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/a.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/alert.black.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/alert.red.gifbin0 -> 247 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/apache_pb.gifbin0 -> 2326 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/back.gifbin0 -> 216 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/ball.gray.gifbin0 -> 233 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/ball.red.gifbin0 -> 205 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/binary.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/binhex.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/blank.gifbin0 -> 148 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/bomb.gifbin0 -> 308 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/box1.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/box2.gifbin0 -> 268 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/broken.gifbin0 -> 247 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/burst.gifbin0 -> 235 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button1.gifbin0 -> 755 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button10.gifbin0 -> 781 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button2.gifbin0 -> 785 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button3.gifbin0 -> 745 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button4.gifbin0 -> 786 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button5.gifbin0 -> 780 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button6.gifbin0 -> 791 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button7.gifbin0 -> 796 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button8.gifbin0 -> 784 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button9.gifbin0 -> 784 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/buttonl.gifbin0 -> 587 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/buttonr.gifbin0 -> 576 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/c.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/comp.blue.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/comp.gray.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/compressed.gifbin0 -> 1038 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/continued.gifbin0 -> 214 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/dir.gifbin0 -> 225 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/down.gifbin0 -> 163 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/dvi.gifbin0 -> 238 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/f.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/folder.gifbin0 -> 225 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/folder.open.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/folder.sec.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/forward.gifbin0 -> 219 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/generic.gifbin0 -> 221 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/generic.red.gifbin0 -> 220 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/generic.sec.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/hand.right.gifbin0 -> 217 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/hand.up.gifbin0 -> 223 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/htdig.gifbin0 -> 1822 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/icon.sheet.gifbin0 -> 11977 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/image1.gifbin0 -> 274 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/image2.gifbin0 -> 309 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/image3.gifbin0 -> 286 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/index.gifbin0 -> 268 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/layout.gifbin0 -> 276 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/left.gifbin0 -> 172 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/link.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/movie.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/p.gifbin0 -> 237 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/patch.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pdf.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie0.gifbin0 -> 188 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie1.gifbin0 -> 198 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie2.gifbin0 -> 198 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie3.gifbin0 -> 191 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie4.gifbin0 -> 193 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie5.gifbin0 -> 189 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie6.gifbin0 -> 186 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie7.gifbin0 -> 185 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie8.gifbin0 -> 173 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/portal.gifbin0 -> 254 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/poweredby.gifbin0 -> 2748 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/ps.gifbin0 -> 244 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/quill.gifbin0 -> 267 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/right.gifbin0 -> 172 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/screw1.gifbin0 -> 258 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/screw2.gifbin0 -> 263 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/script.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/sound1.gifbin0 -> 248 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/sound2.gifbin0 -> 221 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/sphere1.gifbin0 -> 285 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/sphere2.gifbin0 -> 264 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/star.gifbin0 -> 89 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/star_blank.gifbin0 -> 53 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/tar.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/tex.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/text.gifbin0 -> 229 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/transfer.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/unknown.gifbin0 -> 245 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/up.gifbin0 -> 164 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/uu.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/uuencoded.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/world1.gifbin0 -> 228 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/world2.gifbin0 -> 261 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/logs/Dummy_File_Needed_By_WinZip1
-rw-r--r--lib/inets/test/httpd_test_data/server_root/ssl/ssl_client.pem22
-rw-r--r--lib/inets/test/httpd_test_data/server_root/ssl/ssl_server.pem22
-rw-r--r--lib/inets/test/httpd_test_lib.erl332
-rw-r--r--lib/inets/test/httpd_time_test.erl500
-rw-r--r--lib/inets/test/inets.config1
-rw-r--r--lib/inets/test/inets.spec2
-rw-r--r--lib/inets/test/inets.spec.vxworks5
-rw-r--r--lib/inets/test/inets_SUITE.erl583
-rw-r--r--lib/inets/test/inets_SUITE_data/.gitignore0
-rw-r--r--lib/inets/test/inets_app_test.erl296
-rw-r--r--lib/inets/test/inets_appup_test.erl336
l---------lib/inets/test/inets_internal.hrl1
-rw-r--r--lib/inets/test/inets_sup_SUITE.erl414
-rw-r--r--lib/inets/test/inets_sup_SUITE_data/mime.types3
-rw-r--r--lib/inets/test/inets_sup_SUITE_data/simple.conf6
-rw-r--r--lib/inets/test/inets_test_lib.erl302
-rw-r--r--lib/inets/test/inets_test_lib.hrl104
-rw-r--r--lib/inets/test/rules.mk59
-rw-r--r--lib/inets/test/tftp_SUITE.erl903
-rw-r--r--lib/inets/test/tftp_test_lib.erl307
-rw-r--r--lib/inets/test/tftp_test_lib.hrl43
-rw-r--r--lib/inets/vsn.mk33
-rw-r--r--lib/jinterface/doc/src/Makefile13
-rw-r--r--lib/kernel/src/Makefile12
-rw-r--r--lib/kernel/src/code.erl24
-rw-r--r--lib/kernel/src/code_server.erl14
-rw-r--r--lib/kernel/src/hipe_unified_loader.erl32
-rw-r--r--lib/kernel/test/Makefile12
-rw-r--r--lib/kernel/test/bif_SUITE.erl44
-rw-r--r--lib/kernel/test/cleanup.erl12
-rw-r--r--lib/kernel/test/erl_distribution_SUITE.erl46
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE.erl74
-rw-r--r--lib/kernel/test/error_logger_SUITE.erl32
-rw-r--r--lib/kernel/test/file_SUITE.erl12
-rw-r--r--lib/kernel/test/global_group_SUITE.erl30
-rw-r--r--lib/kernel/test/heart_SUITE.erl16
-rw-r--r--lib/kernel/test/init_SUITE.erl14
-rw-r--r--lib/kernel/test/kernel_SUITE.erl12
-rw-r--r--lib/kernel/test/kernel_config_SUITE.erl12
-rw-r--r--lib/kernel/test/loose_node.erl27
-rw-r--r--lib/kernel/test/os_SUITE.erl24
-rw-r--r--lib/kernel/test/pdict_SUITE.erl14
-rw-r--r--lib/kernel/test/rpc_SUITE.erl14
-rw-r--r--lib/kernel/test/seq_trace_SUITE.erl16
-rw-r--r--lib/kernel/test/wrap_log_reader_SUITE.erl30
-rw-r--r--lib/megaco/doc/src/Makefile19
-rw-r--r--lib/megaco/doc/src/megaco_codec_transform.xml27
-rw-r--r--lib/megaco/doc/src/megaco_debug.xml28
-rw-r--r--lib/megaco/doc/src/megaco_performance.xml18
-rw-r--r--lib/megaco/doc/src/notes.xml42
-rw-r--r--lib/megaco/doc/standard/H.248.1-Corr1-200403.docbin296448 -> 0 bytes
-rw-r--r--lib/megaco/doc/standard/rfc2327.txt2355
-rw-r--r--lib/megaco/doc/standard/rfc3266.txt283
-rw-r--r--lib/megaco/examples/meas/meas.sh.skel12
-rw-r--r--lib/megaco/include/megaco.hrl19
-rw-r--r--lib/megaco/src/engine/megaco_config.erl12
-rw-r--r--lib/megaco/test/Makefile129
-rw-r--r--lib/megaco/vsn.mk21
-rw-r--r--lib/mnesia/doc/src/mnesia.xml6
-rw-r--r--lib/mnesia/src/mnesia.erl10
-rw-r--r--lib/mnesia/src/mnesia_loader.erl10
-rw-r--r--lib/mnesia/src/mnesia_monitor.erl10
-rw-r--r--lib/odbc/doc/src/Makefile13
-rw-r--r--lib/orber/doc/src/notes.xml18
-rw-r--r--lib/orber/vsn.mk3
-rw-r--r--lib/parsetools/test/Makefile78
-rw-r--r--lib/parsetools/test/leex_SUITE.erl909
-rw-r--r--lib/parsetools/test/parsetools.spec1
-rw-r--r--lib/parsetools/test/yecc_SUITE.erl1795
-rw-r--r--lib/percept/doc/src/Makefile14
-rw-r--r--lib/public_key/doc/src/Makefile13
-rw-r--r--lib/public_key/src/pubkey_cert_records.erl12
-rw-r--r--lib/public_key/src/public_key.erl26
-rw-r--r--lib/public_key/test/Makefile12
-rw-r--r--lib/public_key/test/public_key_SUITE.erl15
-rw-r--r--lib/reltool/test/Makefile82
-rw-r--r--lib/reltool/test/README30
-rw-r--r--lib/reltool/test/reltool.spec2
-rw-r--r--lib/reltool/test/reltool_server_SUITE.erl494
-rw-r--r--lib/reltool/test/reltool_test_lib.erl329
-rw-r--r--lib/reltool/test/reltool_test_lib.hrl91
-rw-r--r--lib/reltool/test/reltool_wx_SUITE.erl62
-rwxr-xr-xlib/reltool/test/rtt55
-rw-r--r--lib/reltool/test/rtt.erl154
-rw-r--r--lib/ssh/doc/src/Makefile13
-rw-r--r--lib/ssh/doc/src/notes.xml17
-rw-r--r--lib/ssh/src/ssh.appup.src12
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl14
-rw-r--r--lib/ssh/vsn.mk3
-rw-r--r--lib/ssl/doc/src/Makefile13
-rw-r--r--lib/ssl/src/ssl_connection.erl23
-rw-r--r--lib/ssl/src/ssl_handshake.erl38
-rw-r--r--lib/ssl/test/Makefile137
-rw-r--r--lib/ssl/test/make_certs.erl288
-rw-r--r--lib/ssl/test/old_ssl_active_SUITE.erl387
-rw-r--r--lib/ssl/test/old_ssl_active_once_SUITE.erl409
-rw-r--r--lib/ssl/test/old_ssl_dist_SUITE.erl595
-rw-r--r--lib/ssl/test/old_ssl_misc_SUITE.erl105
-rw-r--r--lib/ssl/test/old_ssl_passive_SUITE.erl374
-rw-r--r--lib/ssl/test/old_ssl_peer_cert_SUITE.erl180
-rw-r--r--lib/ssl/test/old_ssl_protocol_SUITE.erl169
-rw-r--r--lib/ssl/test/old_ssl_verify_SUITE.erl141
-rw-r--r--lib/ssl/test/old_transport_accept_SUITE.erl238
-rw-r--r--lib/ssl/test/ssl.cover7
-rw-r--r--lib/ssl/test/ssl.spec1
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl2075
-rw-r--r--lib/ssl/test/ssl_basic_SUITE_data/RANDbin0 -> 512 bytes
-rw-r--r--lib/ssl/test/ssl_packet_SUITE.erl1486
-rw-r--r--lib/ssl/test/ssl_payload_SUITE.erl726
-rw-r--r--lib/ssl/test/ssl_test_MACHINE.erl935
-rw-r--r--lib/ssl/test/ssl_test_MACHINE.hrl39
-rw-r--r--lib/ssl/test/ssl_test_lib.erl408
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl772
-rw-r--r--lib/ssl/vsn.mk15
-rw-r--r--lib/stdlib/doc/src/beam_lib.xml152
-rw-r--r--lib/stdlib/doc/src/io.xml9
-rw-r--r--lib/stdlib/doc/src/unicode.xml4
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml6
-rw-r--r--lib/stdlib/src/Makefile14
-rw-r--r--lib/stdlib/src/edlin.erl36
-rw-r--r--lib/stdlib/src/edlin_expand.erl49
-rw-r--r--lib/stdlib/src/epp.erl265
-rw-r--r--lib/stdlib/src/escript.erl13
-rw-r--r--lib/stdlib/src/filelib.erl22
-rw-r--r--lib/stdlib/src/re.erl71
-rw-r--r--lib/stdlib/test/ExpandTestCaps.erl32
-rw-r--r--lib/stdlib/test/ExpandTestCaps1.erl44
-rw-r--r--lib/stdlib/test/Makefile7
-rw-r--r--lib/stdlib/test/calendar_SUITE.erl26
-rw-r--r--lib/stdlib/test/edlin_expand_SUITE.erl156
-rw-r--r--lib/stdlib/test/epp_SUITE.erl143
-rw-r--r--lib/stdlib/test/ets_SUITE.erl18
-rw-r--r--lib/stdlib/test/ets_tough_SUITE.erl18
-rw-r--r--lib/stdlib/test/expand_test.erl32
-rw-r--r--lib/stdlib/test/expand_test1.erl44
-rw-r--r--lib/stdlib/test/filelib_SUITE.erl30
-rw-r--r--lib/stdlib/test/fixtable_SUITE.erl26
-rw-r--r--lib/stdlib/test/format_SUITE.erl12
-rw-r--r--lib/stdlib/test/gen_event_SUITE.erl30
-rw-r--r--lib/stdlib/test/io_proto_SUITE.erl40
-rw-r--r--lib/stdlib/test/ms_transform_SUITE.erl36
-rw-r--r--lib/stdlib/test/queue_SUITE.erl22
-rw-r--r--lib/stdlib/test/re_SUITE.erl30
-rw-r--r--lib/stdlib/test/re_SUITE_data/mod_testoutput8877
-rw-r--r--lib/stdlib/test/re_testoutput1_replacement_test.erl11
-rw-r--r--lib/stdlib/test/re_testoutput1_split_test.erl11
-rw-r--r--lib/stdlib/test/run_pcre_tests.erl52
-rw-r--r--lib/stdlib/test/select_SUITE.erl16
-rw-r--r--lib/stdlib/test/slave_SUITE.erl18
-rw-r--r--lib/stdlib/test/sofs_SUITE.erl132
-rw-r--r--lib/stdlib/test/supervisor_SUITE.erl68
-rw-r--r--lib/stdlib/test/tar_SUITE.erl18
-rw-r--r--lib/stdlib/test/timer_SUITE.erl12
-rw-r--r--lib/stdlib/test/unicode_SUITE.erl82
-rw-r--r--lib/stdlib/test/win32reg_SUITE.erl14
-rw-r--r--lib/stdlib/test/zip_SUITE.erl20
-rw-r--r--lib/syntax_tools/Makefile6
-rw-r--r--lib/syntax_tools/doc/src/Makefile14
-rw-r--r--lib/syntax_tools/src/Makefile12
-rw-r--r--lib/test_server/doc/src/Makefile13
-rw-r--r--lib/test_server/src/Makefile12
-rw-r--r--lib/tools/test/Makefile90
-rw-r--r--lib/tools/test/cover_SUITE.erl1198
-rw-r--r--lib/tools/test/cover_SUITE_data/a.erl55
-rw-r--r--lib/tools/test/cover_SUITE_data/b.erl14
-rw-r--r--lib/tools/test/cover_SUITE_data/cc.erl88
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/crypt.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/d/y.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/v.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/w.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/x.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/d.erl156
-rw-r--r--lib/tools/test/cover_SUITE_data/d1/e.erl127
-rw-r--r--lib/tools/test/cover_SUITE_data/f.erl10
-rw-r--r--lib/tools/test/cover_SUITE_data/included_functions/cover_inc.erl8
-rw-r--r--lib/tools/test/cover_SUITE_data/included_functions/cover_inc.hrl7
-rw-r--r--lib/tools/test/cover_SUITE_data/otp_6115/f1.erl12
-rw-r--r--lib/tools/test/cover_SUITE_data/otp_6115/f2.erl13
-rw-r--r--lib/tools/test/cprof_SUITE.erl309
-rw-r--r--lib/tools/test/cprof_SUITE_data/cprof_SUITE_test.erl25
-rw-r--r--lib/tools/test/emem_SUITE.erl713
-rw-r--r--lib/tools/test/eprof_SUITE.erl97
-rw-r--r--lib/tools/test/eprof_SUITE_data/ed.script8
-rw-r--r--lib/tools/test/eprof_SUITE_data/eed.erl815
-rw-r--r--lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl74
-rw-r--r--lib/tools/test/fprof_SUITE.erl1191
-rw-r--r--lib/tools/test/fprof_SUITE_data/foo.erl41
l---------lib/tools/test/ignore_cores.erl1
-rw-r--r--lib/tools/test/instrument_SUITE.erl129
-rw-r--r--lib/tools/test/make_SUITE.erl295
-rw-r--r--lib/tools/test/make_SUITE_data/Emakefile20
-rw-r--r--lib/tools/test/make_SUITE_data/test1.erl10
-rw-r--r--lib/tools/test/make_SUITE_data/test2.erl10
-rw-r--r--lib/tools/test/make_SUITE_data/test3.erl10
-rw-r--r--lib/tools/test/make_SUITE_data/test4.erl10
-rw-r--r--lib/tools/test/make_SUITE_data/test5.erl10
-rw-r--r--lib/tools/test/tools.spec1
-rw-r--r--lib/tools/test/tools.spec.win2
-rw-r--r--lib/tools/test/tools_SUITE.erl56
-rw-r--r--lib/tools/test/xref_SUITE.erl2743
-rw-r--r--lib/tools/test/xref_SUITE_data/depr_r9c.beambin0 -> 1664 bytes
-rw-r--r--lib/tools/test/xref_SUITE_data/dir/dir/dummy2
-rw-r--r--lib/tools/test/xref_SUITE_data/dir/jam/x.jam0
-rw-r--r--lib/tools/test/xref_SUITE_data/lib_test/cp.erl6
-rw-r--r--lib/tools/test/xref_SUITE_data/lib_test/lib1.erl6
-rw-r--r--lib/tools/test/xref_SUITE_data/lib_test/lib2.erl14
-rw-r--r--lib/tools/test/xref_SUITE_data/lib_test/lib3.erl11
-rw-r--r--lib/tools/test/xref_SUITE_data/lib_test/t.erl14
-rw-r--r--lib/tools/test/xref_SUITE_data/md/x__x.erl7
-rw-r--r--lib/tools/test/xref_SUITE_data/md/y__y.erl12
-rw-r--r--lib/tools/test/xref_SUITE_data/read/read.beam.v1bin0 -> 7160 bytes
-rw-r--r--lib/tools/test/xref_SUITE_data/read/read.erl175
-rw-r--r--lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.0/ebin/dummy2
-rw-r--r--lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.1/ebin/dummy2
-rw-r--r--lib/tools/test/xref_SUITE_data/rel2/lib/app2-1.1/ebin/dummy2
-rw-r--r--lib/tools/test/xref_SUITE_data/rel2/x.erl16
-rw-r--r--lib/tools/test/xref_SUITE_data/rel2/y.erl6
-rw-r--r--lib/tools/test/xref_SUITE_data/update/x.erl.16
-rw-r--r--lib/tools/test/xref_SUITE_data/update/x.erl.26
-rw-r--r--lib/wx/api_gen/wx_gen.erl19
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl30
-rw-r--r--lib/wx/api_gen/wx_gen_erl.erl19
-rw-r--r--lib/wx/api_gen/wxapi.conf21
-rw-r--r--lib/wx/c_src/gen/gl_fdefs.h10
-rw-r--r--lib/wx/c_src/gen/gl_finit.h10
-rw-r--r--lib/wx/c_src/gen/gl_funcs.cpp10
-rw-r--r--lib/wx/c_src/gen/glu_finit.h10
-rw-r--r--lib/wx/c_src/gen/wxe_derived_dest.h10
-rw-r--r--lib/wx/c_src/gen/wxe_events.cpp14
-rw-r--r--lib/wx/c_src/gen/wxe_funcs.cpp237
-rw-r--r--lib/wx/c_src/gen/wxe_init.cpp10
-rw-r--r--lib/wx/c_src/gen/wxe_macros.h2875
-rw-r--r--lib/wx/c_src/wxe_impl.cpp57
-rw-r--r--lib/wx/c_src/wxe_return.cpp12
-rw-r--r--lib/wx/doc/src/Makefile18
-rw-r--r--lib/wx/include/gl.hrl10
-rw-r--r--lib/wx/include/glu.hrl10
-rw-r--r--lib/wx/include/wx.hrl12
-rw-r--r--lib/wx/src/gen/gl.erl10
-rw-r--r--lib/wx/src/gen/gl_debug.hrl10
-rw-r--r--lib/wx/src/gen/glu.erl10
-rw-r--r--lib/wx/src/gen/wxAcceleratorEntry.erl10
-rw-r--r--lib/wx/src/gen/wxAcceleratorTable.erl10
-rw-r--r--lib/wx/src/gen/wxArtProvider.erl10
-rw-r--r--lib/wx/src/gen/wxAuiDockArt.erl10
-rw-r--r--lib/wx/src/gen/wxAuiManager.erl10
-rw-r--r--lib/wx/src/gen/wxAuiManagerEvent.erl10
-rw-r--r--lib/wx/src/gen/wxAuiNotebook.erl10
-rw-r--r--lib/wx/src/gen/wxAuiNotebookEvent.erl10
-rw-r--r--lib/wx/src/gen/wxAuiPaneInfo.erl10
-rw-r--r--lib/wx/src/gen/wxAuiTabArt.erl10
-rw-r--r--lib/wx/src/gen/wxBitmap.erl10
-rw-r--r--lib/wx/src/gen/wxBitmapButton.erl10
-rw-r--r--lib/wx/src/gen/wxBitmapDataObject.erl10
-rw-r--r--lib/wx/src/gen/wxBoxSizer.erl10
-rw-r--r--lib/wx/src/gen/wxBrush.erl10
-rw-r--r--lib/wx/src/gen/wxBufferedDC.erl10
-rw-r--r--lib/wx/src/gen/wxBufferedPaintDC.erl10
-rw-r--r--lib/wx/src/gen/wxButton.erl10
-rw-r--r--lib/wx/src/gen/wxCalendarCtrl.erl10
-rw-r--r--lib/wx/src/gen/wxCalendarDateAttr.erl10
-rw-r--r--lib/wx/src/gen/wxCalendarEvent.erl10
-rw-r--r--lib/wx/src/gen/wxCaret.erl10
-rw-r--r--lib/wx/src/gen/wxCheckBox.erl10
-rw-r--r--lib/wx/src/gen/wxCheckListBox.erl10
-rw-r--r--lib/wx/src/gen/wxChildFocusEvent.erl10
-rw-r--r--lib/wx/src/gen/wxChoice.erl10
-rw-r--r--lib/wx/src/gen/wxChoicebook.erl10
-rw-r--r--lib/wx/src/gen/wxClientDC.erl10
-rw-r--r--lib/wx/src/gen/wxClipboard.erl10
-rw-r--r--lib/wx/src/gen/wxCloseEvent.erl10
-rw-r--r--lib/wx/src/gen/wxColourData.erl10
-rw-r--r--lib/wx/src/gen/wxColourDialog.erl10
-rw-r--r--lib/wx/src/gen/wxColourPickerCtrl.erl10
-rw-r--r--lib/wx/src/gen/wxColourPickerEvent.erl10
-rw-r--r--lib/wx/src/gen/wxComboBox.erl10
-rw-r--r--lib/wx/src/gen/wxCommandEvent.erl10
-rw-r--r--lib/wx/src/gen/wxContextMenuEvent.erl10
-rw-r--r--lib/wx/src/gen/wxControl.erl10
-rw-r--r--lib/wx/src/gen/wxControlWithItems.erl10
-rw-r--r--lib/wx/src/gen/wxCursor.erl10
-rw-r--r--lib/wx/src/gen/wxDC.erl10
-rw-r--r--lib/wx/src/gen/wxDataObject.erl10
-rw-r--r--lib/wx/src/gen/wxDateEvent.erl10
-rw-r--r--lib/wx/src/gen/wxDatePickerCtrl.erl10
-rw-r--r--lib/wx/src/gen/wxDialog.erl10
-rw-r--r--lib/wx/src/gen/wxDirDialog.erl10
-rw-r--r--lib/wx/src/gen/wxDirPickerCtrl.erl10
-rw-r--r--lib/wx/src/gen/wxDisplayChangedEvent.erl10
-rw-r--r--lib/wx/src/gen/wxEraseEvent.erl10
-rw-r--r--lib/wx/src/gen/wxEvent.erl10
-rw-r--r--lib/wx/src/gen/wxEvtHandler.erl10
-rw-r--r--lib/wx/src/gen/wxFileDataObject.erl10
-rw-r--r--lib/wx/src/gen/wxFileDialog.erl10
-rw-r--r--lib/wx/src/gen/wxFileDirPickerEvent.erl10
-rw-r--r--lib/wx/src/gen/wxFilePickerCtrl.erl10
-rw-r--r--lib/wx/src/gen/wxFindReplaceData.erl10
-rw-r--r--lib/wx/src/gen/wxFindReplaceDialog.erl10
-rw-r--r--lib/wx/src/gen/wxFlexGridSizer.erl10
-rw-r--r--lib/wx/src/gen/wxFocusEvent.erl10
-rw-r--r--lib/wx/src/gen/wxFont.erl10
-rw-r--r--lib/wx/src/gen/wxFontData.erl10
-rw-r--r--lib/wx/src/gen/wxFontDialog.erl10
-rw-r--r--lib/wx/src/gen/wxFontPickerCtrl.erl10
-rw-r--r--lib/wx/src/gen/wxFontPickerEvent.erl10
-rw-r--r--lib/wx/src/gen/wxFrame.erl10
-rw-r--r--lib/wx/src/gen/wxGBSizerItem.erl10
-rw-r--r--lib/wx/src/gen/wxGLCanvas.erl10
-rw-r--r--lib/wx/src/gen/wxGauge.erl10
-rw-r--r--lib/wx/src/gen/wxGenericDirCtrl.erl12
-rw-r--r--lib/wx/src/gen/wxGraphicsBrush.erl10
-rw-r--r--lib/wx/src/gen/wxGraphicsContext.erl10
-rw-r--r--lib/wx/src/gen/wxGraphicsFont.erl10
-rw-r--r--lib/wx/src/gen/wxGraphicsMatrix.erl10
-rw-r--r--lib/wx/src/gen/wxGraphicsObject.erl10
-rw-r--r--lib/wx/src/gen/wxGraphicsPath.erl10
-rw-r--r--lib/wx/src/gen/wxGraphicsPen.erl10
-rw-r--r--lib/wx/src/gen/wxGraphicsRenderer.erl10
-rw-r--r--lib/wx/src/gen/wxGrid.erl10
-rw-r--r--lib/wx/src/gen/wxGridBagSizer.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellAttr.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellBoolEditor.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellBoolRenderer.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellChoiceEditor.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellEditor.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellFloatEditor.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellFloatRenderer.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellNumberEditor.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellNumberRenderer.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellRenderer.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellStringRenderer.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellTextEditor.erl10
-rw-r--r--lib/wx/src/gen/wxGridEvent.erl10
-rw-r--r--lib/wx/src/gen/wxGridSizer.erl10
-rw-r--r--lib/wx/src/gen/wxHelpEvent.erl10
-rw-r--r--lib/wx/src/gen/wxHtmlEasyPrinting.erl10
-rw-r--r--lib/wx/src/gen/wxHtmlLinkEvent.erl10
-rw-r--r--lib/wx/src/gen/wxHtmlWindow.erl10
-rw-r--r--lib/wx/src/gen/wxIcon.erl10
-rw-r--r--lib/wx/src/gen/wxIconBundle.erl10
-rw-r--r--lib/wx/src/gen/wxIconizeEvent.erl10
-rw-r--r--lib/wx/src/gen/wxIdleEvent.erl10
-rw-r--r--lib/wx/src/gen/wxImage.erl10
-rw-r--r--lib/wx/src/gen/wxImageList.erl10
-rw-r--r--lib/wx/src/gen/wxJoystickEvent.erl10
-rw-r--r--lib/wx/src/gen/wxKeyEvent.erl10
-rw-r--r--lib/wx/src/gen/wxLayoutAlgorithm.erl10
-rw-r--r--lib/wx/src/gen/wxListBox.erl10
-rw-r--r--lib/wx/src/gen/wxListCtrl.erl10
-rw-r--r--lib/wx/src/gen/wxListEvent.erl10
-rw-r--r--lib/wx/src/gen/wxListItem.erl10
-rw-r--r--lib/wx/src/gen/wxListView.erl10
-rw-r--r--lib/wx/src/gen/wxListbook.erl10
-rw-r--r--lib/wx/src/gen/wxLogNull.erl10
-rw-r--r--lib/wx/src/gen/wxMDIChildFrame.erl10
-rw-r--r--lib/wx/src/gen/wxMDIClientWindow.erl10
-rw-r--r--lib/wx/src/gen/wxMDIParentFrame.erl10
-rw-r--r--lib/wx/src/gen/wxMask.erl10
-rw-r--r--lib/wx/src/gen/wxMaximizeEvent.erl10
-rw-r--r--lib/wx/src/gen/wxMemoryDC.erl10
-rw-r--r--lib/wx/src/gen/wxMenu.erl10
-rw-r--r--lib/wx/src/gen/wxMenuBar.erl10
-rw-r--r--lib/wx/src/gen/wxMenuEvent.erl10
-rw-r--r--lib/wx/src/gen/wxMenuItem.erl10
-rw-r--r--lib/wx/src/gen/wxMessageDialog.erl10
-rw-r--r--lib/wx/src/gen/wxMiniFrame.erl10
-rw-r--r--lib/wx/src/gen/wxMirrorDC.erl10
-rw-r--r--lib/wx/src/gen/wxMouseCaptureChangedEvent.erl10
-rw-r--r--lib/wx/src/gen/wxMouseEvent.erl10
-rw-r--r--lib/wx/src/gen/wxMoveEvent.erl10
-rw-r--r--lib/wx/src/gen/wxMultiChoiceDialog.erl10
-rw-r--r--lib/wx/src/gen/wxNavigationKeyEvent.erl10
-rw-r--r--lib/wx/src/gen/wxNcPaintEvent.erl10
-rw-r--r--lib/wx/src/gen/wxNotebook.erl10
-rw-r--r--lib/wx/src/gen/wxNotebookEvent.erl10
-rw-r--r--lib/wx/src/gen/wxNotifyEvent.erl10
-rw-r--r--lib/wx/src/gen/wxPageSetupDialog.erl10
-rw-r--r--lib/wx/src/gen/wxPageSetupDialogData.erl10
-rw-r--r--lib/wx/src/gen/wxPaintDC.erl10
-rw-r--r--lib/wx/src/gen/wxPaintEvent.erl10
-rw-r--r--lib/wx/src/gen/wxPalette.erl10
-rw-r--r--lib/wx/src/gen/wxPaletteChangedEvent.erl10
-rw-r--r--lib/wx/src/gen/wxPanel.erl10
-rw-r--r--lib/wx/src/gen/wxPasswordEntryDialog.erl10
-rw-r--r--lib/wx/src/gen/wxPen.erl10
-rw-r--r--lib/wx/src/gen/wxPickerBase.erl10
-rw-r--r--lib/wx/src/gen/wxPostScriptDC.erl10
-rw-r--r--lib/wx/src/gen/wxPreviewCanvas.erl10
-rw-r--r--lib/wx/src/gen/wxPreviewControlBar.erl10
-rw-r--r--lib/wx/src/gen/wxPreviewFrame.erl10
-rw-r--r--lib/wx/src/gen/wxPrintData.erl10
-rw-r--r--lib/wx/src/gen/wxPrintDialog.erl10
-rw-r--r--lib/wx/src/gen/wxPrintDialogData.erl10
-rw-r--r--lib/wx/src/gen/wxPrintPreview.erl10
-rw-r--r--lib/wx/src/gen/wxPrinter.erl10
-rw-r--r--lib/wx/src/gen/wxPrintout.erl10
-rw-r--r--lib/wx/src/gen/wxProgressDialog.erl10
-rw-r--r--lib/wx/src/gen/wxQueryNewPaletteEvent.erl10
-rw-r--r--lib/wx/src/gen/wxRadioBox.erl10
-rw-r--r--lib/wx/src/gen/wxRadioButton.erl10
-rw-r--r--lib/wx/src/gen/wxRegion.erl10
-rw-r--r--lib/wx/src/gen/wxSashEvent.erl10
-rw-r--r--lib/wx/src/gen/wxSashLayoutWindow.erl10
-rw-r--r--lib/wx/src/gen/wxSashWindow.erl10
-rw-r--r--lib/wx/src/gen/wxScreenDC.erl10
-rw-r--r--lib/wx/src/gen/wxScrollBar.erl10
-rw-r--r--lib/wx/src/gen/wxScrollEvent.erl10
-rw-r--r--lib/wx/src/gen/wxScrollWinEvent.erl10
-rw-r--r--lib/wx/src/gen/wxScrolledWindow.erl10
-rw-r--r--lib/wx/src/gen/wxSetCursorEvent.erl10
-rw-r--r--lib/wx/src/gen/wxShowEvent.erl10
-rw-r--r--lib/wx/src/gen/wxSingleChoiceDialog.erl10
-rw-r--r--lib/wx/src/gen/wxSizeEvent.erl10
-rw-r--r--lib/wx/src/gen/wxSizer.erl10
-rw-r--r--lib/wx/src/gen/wxSizerFlags.erl10
-rw-r--r--lib/wx/src/gen/wxSizerItem.erl10
-rw-r--r--lib/wx/src/gen/wxSlider.erl10
-rw-r--r--lib/wx/src/gen/wxSpinButton.erl10
-rw-r--r--lib/wx/src/gen/wxSpinCtrl.erl10
-rw-r--r--lib/wx/src/gen/wxSpinEvent.erl10
-rw-r--r--lib/wx/src/gen/wxSplashScreen.erl10
-rw-r--r--lib/wx/src/gen/wxSplitterEvent.erl10
-rw-r--r--lib/wx/src/gen/wxSplitterWindow.erl10
-rw-r--r--lib/wx/src/gen/wxStaticBitmap.erl10
-rw-r--r--lib/wx/src/gen/wxStaticBox.erl10
-rw-r--r--lib/wx/src/gen/wxStaticBoxSizer.erl10
-rw-r--r--lib/wx/src/gen/wxStaticLine.erl10
-rw-r--r--lib/wx/src/gen/wxStaticText.erl10
-rw-r--r--lib/wx/src/gen/wxStatusBar.erl10
-rw-r--r--lib/wx/src/gen/wxStdDialogButtonSizer.erl10
-rw-r--r--lib/wx/src/gen/wxStyledTextCtrl.erl10
-rw-r--r--lib/wx/src/gen/wxStyledTextEvent.erl10
-rw-r--r--lib/wx/src/gen/wxSysColourChangedEvent.erl10
-rw-r--r--lib/wx/src/gen/wxTextAttr.erl10
-rw-r--r--lib/wx/src/gen/wxTextCtrl.erl10
-rw-r--r--lib/wx/src/gen/wxTextDataObject.erl10
-rw-r--r--lib/wx/src/gen/wxTextEntryDialog.erl10
-rw-r--r--lib/wx/src/gen/wxToggleButton.erl10
-rw-r--r--lib/wx/src/gen/wxToolBar.erl10
-rw-r--r--lib/wx/src/gen/wxToolTip.erl10
-rw-r--r--lib/wx/src/gen/wxToolbook.erl10
-rw-r--r--lib/wx/src/gen/wxTopLevelWindow.erl10
-rw-r--r--lib/wx/src/gen/wxTreeCtrl.erl458
-rw-r--r--lib/wx/src/gen/wxTreeEvent.erl14
-rw-r--r--lib/wx/src/gen/wxTreebook.erl10
-rw-r--r--lib/wx/src/gen/wxUpdateUIEvent.erl10
-rw-r--r--lib/wx/src/gen/wxWindow.erl10
-rw-r--r--lib/wx/src/gen/wxWindowCreateEvent.erl10
-rw-r--r--lib/wx/src/gen/wxWindowDC.erl10
-rw-r--r--lib/wx/src/gen/wxWindowDestroyEvent.erl10
-rw-r--r--lib/wx/src/gen/wxXmlResource.erl10
-rw-r--r--lib/wx/src/gen/wx_misc.erl10
-rw-r--r--lib/wx/src/gen/wxe_debug.hrl2875
-rw-r--r--lib/wx/src/gen/wxe_funcs.hrl2875
-rw-r--r--lib/wx/test/wx_class_SUITE.erl26
-rw-r--r--lib/wx/test/wx_xtra_SUITE.erl72
-rw-r--r--lib/wx/test/wxt.erl18
-rw-r--r--lib/xmerl/doc/src/Makefile12
-rw-r--r--make/otp.mk.in36
-rwxr-xr-xotp_build126
-rw-r--r--system/AD.html307
-rw-r--r--system/AD.sgml367
-rw-r--r--system/ADbeam.html261
-rw-r--r--system/ADbeam.sgml246
-rw-r--r--system/doc/book.xml52
-rw-r--r--system/doc/extensions/Makefile142
-rw-r--r--system/doc/extensions/bit_syntax.xml403
-rw-r--r--system/doc/extensions/book.xml45
-rw-r--r--system/doc/extensions/fun_test.erl17
-rw-r--r--system/doc/extensions/funparse.erl74
-rw-r--r--system/doc/extensions/funs.xml486
-rw-r--r--system/doc/extensions/funs1.erl125
-rw-r--r--system/doc/extensions/include.xml81
-rw-r--r--system/doc/extensions/list_comprehensions.erl118
-rw-r--r--system/doc/extensions/list_comprehensions.xml205
-rw-r--r--system/doc/extensions/list_comrehensions.erl75
-rw-r--r--system/doc/extensions/macros.xml177
-rw-r--r--system/doc/extensions/make.dep21
-rw-r--r--system/doc/extensions/mexpand.erl16
-rw-r--r--system/doc/extensions/misc.xml310
-rw-r--r--system/doc/extensions/part.xml57
-rw-r--r--system/doc/extensions/records.xml284
-rw-r--r--system/doc/extensions/warning.gifbin1498 -> 0 bytes
-rw-r--r--system/doc/pics/Makefile58
-rw-r--r--system/doc/pics/app.gifbin285 -> 0 bytes
-rw-r--r--system/doc/pics/ede.gifbin13644 -> 0 bytes
-rw-r--r--system/doc/pics/ede_logo.gifbin757 -> 0 bytes
-rw-r--r--system/doc/pics/min_head.gifbin2652 -> 0 bytes
-rw-r--r--system/doc/pics/notes.gifbin2005 -> 0 bytes
-rw-r--r--system/doc/pics/otp.gifbin13737 -> 0 bytes
-rw-r--r--system/doc/pics/otp_logo.gifbin1660 -> 0 bytes
-rw-r--r--system/doc/pics/ps.gifbin618 -> 0 bytes
-rw-r--r--system/doc/pics/ref_man.gifbin1530 -> 0 bytes
-rw-r--r--system/doc/pics/user_guide.gifbin1581 -> 0 bytes
-rw-r--r--system/doc/reference_manual/macros.xml38
-rw-r--r--system/doc/reference_manual/modules.xml30
-rw-r--r--system/doc/reference_manual/part.xml7
-rwxr-xr-xsystem/doc/reference_manual/typespec.xml464
-rwxr-xr-x[l---------]system/doc/top/bin/otp_man_index107
-rw-r--r--[l---------]system/doc/top/src/erl_html_tools.erl728
-rw-r--r--[l---------]system/doc/top/src/erlresolvelinks.erl145
l---------system/doc/top/src/permuted_index.erl1
-rw-r--r--system/doc/top/templates/erlang.gifbin2162 -> 0 bytes
-rw-r--r--system/doc/top/templates/first.html.src104
-rwxr-xr-xsystem/doc/top/templates/flip_closed.gifbin82 -> 0 bytes
-rwxr-xr-xsystem/doc/top/templates/flip_google.gifbin257 -> 0 bytes
-rwxr-xr-xsystem/doc/top/templates/flip_open.gifbin86 -> 0 bytes
-rwxr-xr-xsystem/doc/top/templates/flip_static.gifbin109 -> 0 bytes
-rwxr-xr-xsystem/doc/top/templates/flipmenu.js342
-rw-r--r--system/doc/top/templates/index.html.src4
-rw-r--r--system/doc/top/templates/otp_top.css53
-rw-r--r--system/doc/top/templates/system.html.src281
-rw-r--r--system/doc/top/templates/toc_.html.src105
1041 files changed, 67719 insertions, 48512 deletions
diff --git a/Makefile.in b/Makefile.in
index 107bf80bb5..8e97edfd84 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1998-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1998-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
# Toplevel makefile for building the Erlang system
@@ -214,14 +214,15 @@ endif
# ---------------------------------------------------------------
# Target only used when building commercial ERTS patches
# ---------------------------------------------------------------
-release_docs:
+release_docs docs:
ifeq ($(OTP_SMALL_BUILD),true)
- cd $(ERL_TOP)/lib && $(MAKE) TESTROOT=$(RELEASE_ROOT) release_docs
+ cd $(ERL_TOP)/lib && $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
else
- cd $(ERL_TOP)/lib && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release_docs
- cd $(ERL_TOP)/lib/dialyzer && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release_docs
+ cd $(ERL_TOP)/lib && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
+ cd $(ERL_TOP)/lib/dialyzer && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
endif
- cd $(ERL_TOP)/erts && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release_docs
+ cd $(ERL_TOP)/erts && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
+ cd $(ERL_TOP)/system/doc && $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
# ----------------------------------------------------------------------
@@ -441,6 +442,8 @@ fourth_bootstrap_copy:
if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/wx ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/wx ; fi
if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/ebin ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/ebin ; fi
if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/include ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/include ; fi
+ if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server ; fi
+ if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server/include ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server/include ; fi
for x in lib/ic/ebin/*.beam; do \
BN=`basename $$x`; \
TF=$(BOOTSTRAP_ROOT)/bootstrap/lib/ic/ebin/$$BN; \
@@ -506,6 +509,16 @@ fourth_bootstrap_copy:
cp $$x $$TF; \
true; \
done
+ for x in lib/test_server/include/*.hrl; do \
+ BN=`basename $$x`; \
+ TF=$(BOOTSTRAP_ROOT)/bootstrap/lib/test_server/include/$$BN; \
+ test -f $$TF && \
+ test '!' -z "`find $$x -newer $$TF -print`" && \
+ cp $$x $$TF; \
+ test '!' -f $$TF && \
+ cp $$x $$TF; \
+ true; \
+ done
# cp lib/syntax_tools/ebin/*.beam $(BOOTSTRAP_ROOT)/bootstrap/lib/syntax_tools/ebin
@@ -718,6 +731,11 @@ bootstrap_nc_for_ne_no_debug_sym:
#
install: install.dirs install.emulator install.libs install.Install install.bin
+install-docs:
+ ERL_TOP=$(ERL_TOP) INSTALLROOT=$(ERLANG_LIBDIR) PATH=$(BOOT_PREFIX)$${PATH} \
+ $(MAKE) RELEASE_ROOT=$(ERLANG_LIBDIR) release_docs
+
+
install.emulator:
cd erts && \
ERL_TOP=$(ERL_TOP) PATH=$(BOOT_PREFIX)$${PATH} \
diff --git a/erts/configure.in b/erts/configure.in
index faccf5f102..48d236351b 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1,20 +1,20 @@
dnl Process this file with autoconf to produce a configure script. -*-m4-*-
dnl %CopyrightBegin%
-dnl
-dnl Copyright Ericsson AB 1997-2009. All Rights Reserved.
-dnl
+dnl
+dnl Copyright Ericsson AB 1997-2010. All Rights Reserved.
+dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
dnl compliance with the License. You should have received a copy of the
dnl Erlang Public License along with this software. If not, it can be
dnl retrieved online at http://www.erlang.org/.
-dnl
+dnl
dnl Software distributed under the License is distributed on an "AS IS"
dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
dnl the License for the specific language governing rights and limitations
dnl under the License.
-dnl
+dnl
dnl %CopyrightEnd%
dnl The string "FIXME convbreak" means that there is a break of
@@ -325,6 +325,7 @@ dnl Checks for programs.
dnl ----------------------------------------------------------------------
AC_PROG_CC
+AC_SUBST(GCC)
dnl ---------------------------------------------------------------------
dnl Special stuff regarding CFLAGS and details in the environment...
@@ -344,6 +345,9 @@ case $host_os in
AC_MSG_WARN([Reverting to 32-bit time_t])
CPPFLAGS="$CPPFLAGS -D_USE_32BIT_TIME_T"
;;
+ darwin*)
+ CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE"
+ ;;
*)
;;
esac
@@ -2098,6 +2102,44 @@ if test X${enable_hipe} != Xno; then
esac
fi
fi
+
+case $ARCH-$OPSYS in
+ amd64-darwin*|x86-darwin*)
+ AC_MSG_CHECKING([For modern (leopard) style mcontext_t])
+ AC_TRY_COMPILE([
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <mach/mach.h>
+ #include <pthread.h>
+ #include <machine/signal.h>
+ #include <ucontext.h>
+ ],[
+ #if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
+ #define __DARWIN__ 1
+ #endif
+
+ #ifndef __DARWIN__
+ #error inpossible
+ #else
+
+ mcontext_t mc = NULL;
+ int x = mc->__fs.__fpu_mxcsr;
+
+ #endif
+ ],darwin_mcontext_leopard=yes,
+ darwin_mcontext_leopard=no)
+ if test X"$darwin_mcontext_leopard" = X"yes"; then
+ AC_DEFINE(DARWIN_MODERN_MCONTEXT,[],[Modern style mcontext_t in MacOSX])
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ;;
+ *)
+ darwin_mcontext_leopard=no
+ ;;
+esac
if test X${enable_fp_exceptions} = Xauto ; then
if test X${enable_hipe} = Xyes; then
enable_fp_exceptions=yes
@@ -2487,6 +2529,7 @@ static void fpe_sig_action(int sig, siginfo_t *si, void *puc)
regs[PT_FPSCR] = 0x80|0x40|0x10; /* VE, OE, ZE; not UE or XE */
#endif
#elif defined(__DARWIN__)
+#if defined(DARWIN_MODERN_MCONTEXT)
#if defined(__x86_64__)
mcontext_t mc = uc->uc_mcontext;
struct __darwin_x86_float_state64 *fpstate = &mc->__fs;
@@ -2502,6 +2545,23 @@ static void fpe_sig_action(int sig, siginfo_t *si, void *puc)
mc->ss.srr0 += 4;
mc->fs.fpscr = 0x80|0x40|0x10;
#endif
+#else
+#if defined(__x86_64__)
+ mcontext_t mc = uc->uc_mcontext;
+ struct x86_float_state64_t *fpstate = &mc->fs;
+ fpstate->fpu_mxcsr = 0x1F80;
+ *(unsigned short *)&fpstate->fpu_fsw &= ~0xFF;
+#elif defined(__i386__)
+ mcontext_t mc = uc->uc_mcontext;
+ x86_float_state32_t *fpstate = &mc->fs;
+ fpstate->fpu_mxcsr = 0x1F80;
+ *(unsigned short *)&fpstate->fpu_fsw &= ~0xFF;
+#elif defined(__ppc__)
+ mcontext_t mc = uc->uc_mcontext;
+ mc->ss.srr0 += 4;
+ mc->fs.fpscr = 0x80|0x40|0x10;
+#endif
+#endif
#elif defined(__FreeBSD__) && defined(__x86_64__)
mcontext_t *mc = &uc->uc_mcontext;
struct savefpu *savefpu = (struct savefpu*)&mc->mc_fpstate;
@@ -2615,43 +2675,6 @@ fi)
fi
fi
-case $ARCH-$OPSYS in
- amd64-darwin*|x86-darwin*)
- AC_MSG_CHECKING([For modern (leopard) style mcontext_t])
- AC_TRY_COMPILE([
- #include <stdlib.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <mach/mach.h>
- #include <pthread.h>
- #include <machine/signal.h>
- #include <ucontext.h>
- ],[
- #if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
- #define __DARWIN__ 1
- #endif
-
- #ifndef __DARWIN__
- #error inpossible
- #else
-
- mcontext_t mc = NULL;
- int x = mc->__fs.__fpu_mxcsr;
-
- #endif
- ],darwin_mcontext_leopard=yes,
- darwin_mcontext_leopard=no)
- if test X"$darwin_mcontext_leopard" = X"yes"; then
- AC_DEFINE(DARWIN_MODERN_MCONTEXT,[],[Modern style mcontext_t in MacOSX])
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
- ;;
- *)
- darwin_mcontext_leopard=no
- ;;
-esac
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index 90a3c53a37..73d15c33d7 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>erl</title>
@@ -410,7 +410,7 @@
<tag><c><![CDATA[-setcookie Cookie]]></c></tag>
<item>
<p>Sets the magic cookie of the node to <c><![CDATA[Cookie]]></c>, see
- <seealso marker="erlang#erlang:set_cookie/2">erlang:set_cookie/2</seealso>.</p>
+ <seealso marker="erlang#set_cookie/2">erlang:set_cookie/2</seealso>.</p>
</item>
<tag><c><![CDATA[-shutdown_time Time]]></c></tag>
<item>
@@ -527,11 +527,16 @@
<p>Calling <c>erlang:halt/1</c> with a string argument will still
produce a crash dump.</p>
</item>
- <tag><c><![CDATA[+h Size]]></c></tag>
+ <tag><c><![CDATA[+hms Size]]></c></tag>
<item>
<p>Sets the default heap size of processes to the size
<c><![CDATA[Size]]></c>.</p>
</item>
+ <tag><c><![CDATA[+hmbs Size]]></c></tag>
+ <item>
+ <p>Sets the default binary virtual heap size of processes to the size
+ <c><![CDATA[Size]]></c>.</p>
+ </item>
<tag><c><![CDATA[+K true | false]]></c></tag>
<item>
<p>Enables or disables the kernel poll functionality if
@@ -793,6 +798,11 @@
Valid range is 4-8192 kilowords. The default stack size
is OS dependent.</p>
</item>
+ <tag><c><![CDATA[+t size]]></c></tag>
+ <item>
+ <marker id="+t"></marker>
+ <p>Set the maximum number of atoms the VM can handle. Default is 1048576.</p>
+ </item>
<tag><c><![CDATA[+T Level]]></c></tag>
<item>
<marker id="+T"></marker>
diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml
index 0b11f4bbcb..5d7a11b70a 100644
--- a/erts/doc/src/erl_driver.xml
+++ b/erts/doc/src/erl_driver.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>erl_driver</title>
@@ -1292,7 +1292,7 @@ typedef struct ErlIOVec {
has been set in the
<seealso marker="driver_entry">driver_entry</seealso>,
data can be forced into the driver via
- <seealso marker="erlang#erlang:port_command/3">port_command(Port, Data, [force])</seealso>
+ <seealso marker="erlang#port_command/3">port_command(Port, Data, [force])</seealso>
even though the driver has signaled that it is busy.
</p>
</desc>
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 2033ba8a66..2902d70976 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -148,7 +148,7 @@ ok
that the library needs in able to keep a state between NIF
calls. <c>enif_get_data()</c> will return this pointer.</p>
<p><c>load_info</c> is the second argument to <seealso
- marker="erlang#erlang:load_nif-2">erlang:load_nif/2</seealso>.</p>
+ marker="erlang#load_nif-2">erlang:load_nif/2</seealso>.</p>
<p>The library will fail to load if <c>load</c> returns
anything other than 0. <c>load</c> can be NULL in case no
initialization is needed.</p>
@@ -397,7 +397,7 @@ typedef struct {
</funcs>
<section>
<title>SEE ALSO</title>
- <p><seealso marker="erlang#erlang:load_nif-2">load_nif(3)</seealso></p>
+ <p><seealso marker="erlang#load_nif-2">load_nif(3)</seealso></p>
</section>
</cref>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 871fc0fd63..207aabca35 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>erlang</title>
@@ -342,8 +342,50 @@ iolist() = [char() | binary() | iolist()]
<desc>
<p>Returns an Erlang term which is the result of decoding
the binary object <c>Binary</c>, which must be encoded
- according to the Erlang external term format. See also
- <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>.</p>
+ according to the Erlang external term format.</p>
+ <warning>
+ <p>When decoding binaries from untrusted sources, consider using
+ <c>binary_to_term/2</c> to prevent denial of service attacks.</p>
+ </warning>
+ <p>See also
+ <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>
+ and
+ <seealso marker="#binary_to_term/2">binary_to_term/2</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:binary_to_term(Binary, Opts) -> term()</name>
+ <fsummary>Decode an Erlang external term format binary</fsummary>
+ <type>
+ <v>Opts = [safe]</v>
+ <v>Binary = ext_binary()</v>
+ </type>
+ <desc>
+ <p>As <c>binary_to_term/1</c>, but takes options that affect decoding
+ of the binary.</p>
+ <taglist>
+ <tag><c>safe</c></tag>
+ <item>
+ <p>Use this option when receiving binaries from an untrusted
+ source.</p>
+ <p>When enabled, it prevents decoding data that may be used to
+ attack the Erlang system. In the event of receiving unsafe
+ data, decoding fails with a badarg error.</p>
+ <p>Currently, this prevents creation of new atoms directly,
+ creation of new atoms indirectly (as they are embedded in
+ certain structures like pids, refs, funs, etc.), and creation of
+ new external function references. None of those resources are
+ currently garbage collected, so unchecked creation of them can
+ exhaust available memory.</p>
+ </item>
+ </taglist>
+ <p>Failure: <c>badarg</c> if <c>safe</c> is specified and unsafe data
+ is decoded.</p>
+ <p>See also
+ <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>,
+ <seealso marker="#binary_to_term/1">binary_to_term/1</seealso>,
+ and <seealso marker="#list_to_existing_atom/1">
+ list_to_existing_atom/1</seealso>.</p>
</desc>
</func>
<func>
@@ -410,19 +452,19 @@ iolist() = [char() | binary() | iolist()]
<desc>
<p>Cancels a timer, where <c>TimerRef</c> was returned by
either
- <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>
+ <seealso marker="#send_after/3">erlang:send_after/3</seealso>
or
- <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>.
+ <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>.
If the timer is there to be removed, the function returns
the time in milliseconds left until the timer would have expired,
otherwise <c>false</c> (which means that <c>TimerRef</c> was
never a timer, that it has already been cancelled, or that it
has already delivered its message).</p>
<p>See also
- <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>,
- <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>,
+ <seealso marker="#send_after/3">erlang:send_after/3</seealso>,
+ <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>,
and
- <seealso marker="#erlang:read_timer/1">erlang:read_timer/1</seealso>.</p>
+ <seealso marker="#read_timer/1">erlang:read_timer/1</seealso>.</p>
<p>Note: Cancelling a timer does not guarantee that the message
has not already been delivered to the message queue.</p>
</desc>
@@ -673,7 +715,7 @@ false</pre>
<desc>
<p>If <c>MonitorRef</c> is a reference which the calling process
obtained by calling
- <seealso marker="#erlang:monitor/2">erlang:monitor/2</seealso>,
+ <seealso marker="#monitor/2">erlang:monitor/2</seealso>,
this monitoring is turned off. If the monitoring is already
turned off, nothing happens.</p>
<p>Once <c>erlang:demonitor(MonitorRef)</c> has returned it is
@@ -684,7 +726,7 @@ false</pre>
the call, though. Therefore, in most cases, it is advisable
to remove such a <c>'DOWN'</c> message from the message queue
after monitoring has been stopped.
- <seealso marker="#erlang:demonitor/2">erlang:demonitor(MonitorRef, [flush])</seealso> can be used instead of
+ <seealso marker="#demonitor/2">erlang:demonitor(MonitorRef, [flush])</seealso> can be used instead of
<c>erlang:demonitor(MonitorRef)</c> if this cleanup is wanted.</p>
<note>
<p>Prior to OTP release R11B (erts version 5.5) <c>erlang:demonitor/1</c>
@@ -718,7 +760,7 @@ false</pre>
of <c>OptionList</c>.
</p>
<p><c>erlang:demonitor(MonitorRef, [])</c> is equivalent to
- <seealso marker="#erlang:demonitor/1">erlang:demonitor(MonitorRef)</seealso>.</p>
+ <seealso marker="#demonitor/1">erlang:demonitor(MonitorRef)</seealso>.</p>
<p>Currently the following <c>Option</c>s are valid:</p>
<taglist>
<tag><c>flush</c></tag>
@@ -768,7 +810,7 @@ false</pre>
</note>
<p>Failure: <c>badarg</c> if <c>OptionList</c> is not a list, or
if <c>Option</c> is not a valid option, or the same failure as for
- <seealso marker="#erlang:demonitor/1">erlang:demonitor/1</seealso></p>
+ <seealso marker="#demonitor/1">erlang:demonitor/1</seealso></p>
</desc>
</func>
<func>
@@ -1087,7 +1129,7 @@ b</pre>
<c>uniq</c>, and <c>pid</c>. For an external fun, the value
of any of these items is always the atom <c>undefined</c>.</p>
<p>See
- <seealso marker="#erlang:fun_info/1">erlang:fun_info/1</seealso>.</p>
+ <seealso marker="#fun_info/1">erlang:fun_info/1</seealso>.</p>
</desc>
</func>
<func>
@@ -1233,8 +1275,8 @@ b</pre>
returns, for example:</p>
<p><c>{'EXIT',{badarg,Stacktrace}} = catch abs(x)</c></p>
<p>See also
- <seealso marker="#erlang:error/1">erlang:error/1</seealso> and
- <seealso marker="#erlang:error/2">erlang:error/2</seealso>.</p>
+ <seealso marker="#error/1">erlang:error/1</seealso> and
+ <seealso marker="#error/2">erlang:error/2</seealso>.</p>
</desc>
</func>
<func>
@@ -2345,7 +2387,7 @@ os_prompt%</pre>
<item>
If <c>Type</c> is not one of the memory types listed in the
documentation of
- <seealso marker="#erlang:memory/0">erlang:memory/0</seealso>.
+ <seealso marker="#memory/0">erlang:memory/0</seealso>.
</item>
<tag><c>badarg</c></tag>
<item>
@@ -2359,7 +2401,7 @@ os_prompt%</pre>
</item>
</taglist>
<p>See also
- <seealso marker="#erlang:memory/0">erlang:memory/0</seealso>.</p>
+ <seealso marker="#memory/0">erlang:memory/0</seealso>.</p>
</desc>
</func>
<func>
@@ -2468,7 +2510,7 @@ os_prompt%</pre>
</note>
<p>The monitoring is turned off either when the <c>'DOWN'</c>
message is sent, or when
- <seealso marker="#erlang:demonitor/1">erlang:demonitor/1</seealso>
+ <seealso marker="#demonitor/1">erlang:demonitor/1</seealso>
is called.</p>
<p>If an attempt is made to monitor a process on an older node
(where remote process monitoring is not implemented or one
@@ -3337,7 +3379,7 @@ os_prompt%</pre>
registered name, [] is returned.</p>
<p>For valid values of <c>Item</c>, and corresponding
values of <c>Info</c>, see
- <seealso marker="#erlang:port_info/1">erlang:port_info/1</seealso>.</p>
+ <seealso marker="#port_info/1">erlang:port_info/1</seealso>.</p>
<p>Failure: <c>badarg</c> if <c>Port</c> is not a local port.</p>
</desc>
</func>
@@ -3427,6 +3469,11 @@ os_prompt%</pre>
<p>This changes the minimum heap size for the calling
process.</p>
</item>
+ <tag><c>process_flag(min_bin_vheap_size, MinBinVHeapSize)</c></tag>
+ <item>
+ <p>This changes the minimum binary virtual heap size for the calling
+ process.</p>
+ </item>
<tag><c>process_flag(priority, Level)</c></tag>
<item>
<marker id="process_flag_priority"></marker>
@@ -3758,6 +3805,14 @@ os_prompt%</pre>
<p><c>MessageQueue</c> is a list of the messages to
the process, which have not yet been processed.</p>
</item>
+ <tag><c>{min_heap_size, MinHeapSize}</c></tag>
+ <item>
+ <p><c>MinHeapSize</c> is the minimum heap size for the process.</p>
+ </item>
+ <tag><c>{min_bin_vheap_size, MinBinVHeapSize}</c></tag>
+ <item>
+ <p><c>MinBinVHeapSize</c> is the minimum binary virtual heap size for the process.</p>
+ </item>
<tag><c>{monitored_by, Pids}</c></tag>
<item>
<p>A list of pids that are monitoring the process (with
@@ -3813,9 +3868,9 @@ os_prompt%</pre>
ActiveSuspendCount, OutstandingSuspendCount}</c> tuples.
<c>Suspendee</c> is the pid of a process that have been or is to
be suspended by the process identified by <c>Pid</c> via the
- <seealso marker="#erlang:suspend_process/2">erlang:suspend_process/2</seealso>
+ <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>
BIF, or the
- <seealso marker="#erlang:suspend_process/1">erlang:suspend_process/1</seealso>
+ <seealso marker="#suspend_process/1">erlang:suspend_process/1</seealso>
BIF. <c>ActiveSuspendCount</c> is the number of times the
<c>Suspendee</c> has been suspended by <c>Pid</c>.
<c>OutstandingSuspendCount</c> is the number of not yet
@@ -3966,19 +4021,19 @@ os_prompt%</pre>
</type>
<desc>
<p><c>TimerRef</c> is a timer reference returned by
- <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>
+ <seealso marker="#send_after/3">erlang:send_after/3</seealso>
or
- <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>.
+ <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>.
If the timer is active, the function returns the time in
milliseconds left until the timer will expire, otherwise
<c>false</c> (which means that <c>TimerRef</c> was never a
timer, that it has been cancelled, or that it has already
delivered its message).</p>
<p>See also
- <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>,
- <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>,
+ <seealso marker="#send_after/3">erlang:send_after/3</seealso>,
+ <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>,
and
- <seealso marker="#erlang:cancel_timer/1">erlang:cancel_timer/1</seealso>.</p>
+ <seealso marker="#cancel_timer/1">erlang:cancel_timer/1</seealso>.</p>
</desc>
</func>
<func>
@@ -4043,9 +4098,9 @@ true</pre>
<p>Decreases the suspend count on the process identified by
<c>Suspendee</c>. <c>Suspendee</c> should previously have been
suspended via
- <seealso marker="#erlang:suspend_process/2">erlang:suspend_process/2</seealso>,
+ <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>,
or
- <seealso marker="#erlang:suspend_process/1">erlang:suspend_process/1</seealso>
+ <seealso marker="#suspend_process/1">erlang:suspend_process/1</seealso>
by the process calling <c>erlang:resume_process(Suspendee)</c>. When
the suspend count on <c>Suspendee</c> reach zero, <c>Suspendee</c>
will be resumed, i.e., the state of the <c>Suspendee</c> is changed
@@ -4131,9 +4186,9 @@ true</pre>
<p>Sends a message and returns <c>ok</c>, or does not send
the message but returns something else (see below). Otherwise
the same as
- <seealso marker="#erlang:send/2">erlang:send/2</seealso>. See
+ <seealso marker="#send/2">erlang:send/2</seealso>. See
also
- <seealso marker="#erlang:send_nosuspend/2">erlang:send_nosuspend/2,3</seealso>.
+ <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2,3</seealso>.
for more detailed explanation and warnings.</p>
<p>The possible options are:</p>
<taglist>
@@ -4179,10 +4234,10 @@ true</pre>
erts version 5.4.11. Note that timers will not be
automatically canceled when <c>Dest</c> is an atom.</p>
<p>See also
- <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>,
- <seealso marker="#erlang:cancel_timer/1">erlang:cancel_timer/1</seealso>,
+ <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>,
+ <seealso marker="#cancel_timer/1">erlang:cancel_timer/1</seealso>,
and
- <seealso marker="#erlang:read_timer/1">erlang:read_timer/1</seealso>.</p>
+ <seealso marker="#read_timer/1">erlang:read_timer/1</seealso>.</p>
<p>Failure: <c>badarg</c> if the arguments does not satisfy
the requirements specified above.</p>
</desc>
@@ -4198,7 +4253,7 @@ true</pre>
</type>
<desc>
<p>The same as
- <seealso marker="#erlang:send/3">erlang:send(Dest, Msg, [nosuspend])</seealso>, but returns <c>true</c> if
+ <seealso marker="#send/3">erlang:send(Dest, Msg, [nosuspend])</seealso>, but returns <c>true</c> if
the message was sent and <c>false</c> if the message was not
sent because the sender would have had to be suspended.</p>
<p>This function is intended for send operations towards an
@@ -4250,10 +4305,10 @@ true</pre>
</type>
<desc>
<p>The same as
- <seealso marker="#erlang:send/3">erlang:send(Dest, Msg, [nosuspend | Options])</seealso>,
+ <seealso marker="#send/3">erlang:send(Dest, Msg, [nosuspend | Options])</seealso>,
but with boolean return value.</p>
<p>This function behaves like
- <seealso marker="#erlang:send_nosuspend/2">erlang:send_nosuspend/2)</seealso>,
+ <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2)</seealso>,
but takes a third parameter, a list of options. The only
currently implemented option is <c>noconnect</c>. The option
<c>noconnect</c> makes the function return <c>false</c> if
@@ -4491,10 +4546,11 @@ true</pre>
<fsummary>Create a new process with a fun as entry point</fsummary>
<type>
<v>Fun = fun()</v>
- <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
<v>&nbsp;Level = low | normal | high</v>
<v>&nbsp;Number = int()</v>
<v>&nbsp;Size = int()</v>
+ <v>&nbsp;VSize = int()</v>
</type>
<desc>
<p>Returns the pid of a new process started by the application
@@ -4512,10 +4568,11 @@ true</pre>
<type>
<v>Node = node()</v>
<v>Fun = fun()</v>
- <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
<v>&nbsp;Level = low | normal | high</v>
<v>&nbsp;Number = int()</v>
<v>&nbsp;Size = int()</v>
+ <v>&nbsp;VSize = int()</v>
</type>
<desc>
<p>Returns the pid of a new process started by the application
@@ -4531,10 +4588,11 @@ true</pre>
<type>
<v>Module = Function = atom()</v>
<v>Args = [term()]</v>
- <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
<v>&nbsp;Level = low | normal | high</v>
<v>&nbsp;Number = int()</v>
<v>&nbsp;Size = int()</v>
+ <v>&nbsp;VSize = int()</v>
</type>
<desc>
<p>Works exactly like
@@ -4552,7 +4610,7 @@ true</pre>
<tag><c>monitor</c></tag>
<item>
<p>Monitor the new process (just like
- <seealso marker="#erlang:monitor/2">erlang:monitor/2</seealso> does).</p>
+ <seealso marker="#monitor/2">erlang:monitor/2</seealso> does).</p>
</item>
<tag><c>{priority, Level}</c></tag>
<item>
@@ -4595,7 +4653,7 @@ true</pre>
and no virtual memory, one might want to preserve memory
by setting <c>Number</c> to zero. (The value may be set
globally, see
- <seealso marker="#erlang:system_flag/2">erlang:system_flag/2</seealso>.)</p>
+ <seealso marker="#system_flag/2">erlang:system_flag/2</seealso>.)</p>
</item>
<tag><c>{min_heap_size, Size}</c></tag>
<item>
@@ -4614,6 +4672,23 @@ true</pre>
fine-tuning an application and to measure the execution
time with various <c>Size</c> values.</p>
</item>
+ <tag><c>{min_bin_vheap_size, VSize}</c></tag>
+ <item>
+ <p>This option is only useful for performance tuning.
+ In general, you should not use this option unless you
+ know that there is problem with execution times and/or
+ memory consumption, and you should measure to make sure
+ that the option improved matters.
+ </p>
+ <p>Gives a minimum binary virtual heap size in words. Setting this value
+ higher than the system default might speed up some
+ processes because less garbage collection is done.
+ Setting too high value, however, might waste memory.
+ Therefore, it is recommended to use this option only for
+ fine-tuning an application and to measure the execution
+ time with various <c>VSize</c> values.</p>
+ </item>
+
</taglist>
</desc>
</func>
@@ -4624,10 +4699,11 @@ true</pre>
<v>Node = node()</v>
<v>Module = Function = atom()</v>
<v>Args = [term()]</v>
- <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
<v>&nbsp;Level = low | normal | high</v>
<v>&nbsp;Number = int()</v>
<v>&nbsp;Size = int()</v>
+ <v>&nbsp;VSize = int()</v>
</type>
<desc>
<p>Returns the pid of a new process started by the application
@@ -4688,10 +4764,10 @@ true</pre>
erts version 5.4.11. Note that timers will not be
automatically canceled when <c>Dest</c> is an atom.</p>
<p>See also
- <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>,
- <seealso marker="#erlang:cancel_timer/1">erlang:cancel_timer/1</seealso>,
+ <seealso marker="#send_after/3">erlang:send_after/3</seealso>,
+ <seealso marker="#cancel_timer/1">erlang:cancel_timer/1</seealso>,
and
- <seealso marker="#erlang:read_timer/1">erlang:read_timer/1</seealso>.</p>
+ <seealso marker="#read_timer/1">erlang:read_timer/1</seealso>.</p>
<p>Failure: <c>badarg</c> if the arguments does not satisfy
the requirements specified above.</p>
</desc>
@@ -4796,7 +4872,7 @@ true</pre>
process will not leave the suspended state until its suspend
count reach zero. The suspend count of <c>Suspendee</c> is
decreased when
- <seealso marker="#erlang:resume_process/1">erlang:resume_process(Suspendee)</seealso>
+ <seealso marker="#resume_process/1">erlang:resume_process(Suspendee)</seealso>
is called by the same process that called
<c>erlang:suspend_process(Suspendee)</c>. All increased suspend
counts on other processes acquired by a process will automatically be
@@ -4885,7 +4961,7 @@ true</pre>
<desc>
<p>Suspends the process identified by <c>Suspendee</c>. The
same as calling
- <seealso marker="#erlang:suspend_process/2">erlang:suspend_process(Suspendee, [])</seealso>. For more information see the documentation of <seealso marker="#erlang:suspend_process/2">erlang:suspend_process/2</seealso>.
+ <seealso marker="#suspend_process/2">erlang:suspend_process(Suspendee, [])</seealso>. For more information see the documentation of <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>.
</p>
<warning>
<p>This BIF is intended for debugging only.</p>
@@ -4960,6 +5036,17 @@ true</pre>
<seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or
<seealso marker="#process_flag/2">process_flag/2</seealso>. </p>
</item>
+ <tag><c>erlang:system_flag(min_bin_vheap_size, MinBinVHeapSize)</c></tag>
+ <item>
+ <p>Sets the default minimum binary virtual heap size for processes. The
+ size is given in words. The new <c>min_bin_vhheap_size</c> only
+ effects processes spawned after the change of
+ <c>min_bin_vhheap_size</c> has been made.
+ The <c>min_bin_vheap_size</c> can be set for individual
+ processes by use of
+ <seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or
+ <seealso marker="#process_flag/2">process_flag/2</seealso>. </p>
+ </item>
<tag><c>erlang:system_flag(multi_scheduling, BlockState)</c></tag>
<item>
<marker id="system_flag_multi_scheduling"></marker>
@@ -5185,7 +5272,7 @@ true</pre>
Some values are part of other values, and some memory
areas are not part of the result. If you are interested
in the total amount of memory allocated by the emulator
- see <seealso marker="#erlang:memory/0">erlang:memory/0,1</seealso>.</p>
+ see <seealso marker="#memory/0">erlang:memory/0,1</seealso>.</p>
</item>
<tag><c>allocator</c></tag>
<item>
@@ -5500,7 +5587,7 @@ true</pre>
<c>spawn</c> or <c>spawn_link</c> will use these
garbage collection settings. The default settings can be
changed by use of
- <seealso marker="#erlang:system_flag/2">system_flag/2</seealso>.
+ <seealso marker="#system_flag/2">system_flag/2</seealso>.
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>
can spawn a process that does not use the default
settings.</p>
@@ -5571,6 +5658,16 @@ true</pre>
<item>
<p>Returns a string containing the Erlang machine name.</p>
</item>
+ <tag><c>min_heap_size</c></tag>
+ <item>
+ <p>Returns <c>{min_heap_size, MinHeapSize}</c> where <c>MinHeapSize</c> is the current system wide
+ minimum heap size for spawned processes.</p>
+ </item>
+ <tag><c>min_bin_vheap_size</c></tag>
+ <item>
+ <p>Returns <c>{min_bin_vheap_size, MinBinVHeapSize}</c> where <c>MinBinVHeapSize</c> is the current system wide
+ minimum binary virtual heap size for spawned processes.</p>
+ </item>
<tag><c>modified_timing_level</c></tag>
<item>
<p>Returns the modified timing level (an integer) if
@@ -5803,7 +5900,7 @@ true</pre>
</type>
<desc>
<p>Returns the current system monitoring settings set by
- <seealso marker="#erlang:system_monitor/2">erlang:system_monitor/2</seealso>
+ <seealso marker="#system_monitor/2">erlang:system_monitor/2</seealso>
as <c>{MonitorPid, Options}</c>, or <c>undefined</c> if there
are no settings. The order of the options may be different
from the one that was set.</p>
@@ -5821,9 +5918,9 @@ true</pre>
system performance monitoring settings are cleared.</p>
<p>Calling the function with <c>{MonitorPid, Options}</c> as
argument, is the same as calling
- <seealso marker="#erlang:system_monitor/2">erlang:system_monitor(MonitorPid, Options)</seealso>.</p>
+ <seealso marker="#system_monitor/2">erlang:system_monitor(MonitorPid, Options)</seealso>.</p>
<p>Returns the previous system monitor settings just like
- <seealso marker="#erlang:system_monitor/0">erlang:system_monitor/0</seealso>.</p>
+ <seealso marker="#system_monitor/0">erlang:system_monitor/0</seealso>.</p>
</desc>
</func>
@@ -5859,7 +5956,7 @@ true</pre>
explained in the documentation of the
<seealso marker="#gc_start">gc_start</seealso>
trace message (see
- <seealso marker="#erlang:trace/3">erlang:trace/3</seealso>).
+ <seealso marker="#trace/3">erlang:trace/3</seealso>).
New tuples may be added, and the order of the tuples in
the <c>Info</c> list may be changed at any time without prior
notice.
@@ -5901,7 +5998,7 @@ true</pre>
</item>
</taglist>
<p>Returns the previous system monitor settings just like
- <seealso marker="#erlang:system_monitor/0">erlang:system_monitor/0</seealso>.</p>
+ <seealso marker="#system_monitor/0">erlang:system_monitor/0</seealso>.</p>
<note>
<p>If a monitoring process gets so large that it itself
starts to cause system monitor messages when garbage
@@ -5925,7 +6022,7 @@ true</pre>
</type>
<desc>
<p>Returns the current system profiling settings set by
- <seealso marker="#erlang:system_profile/2">erlang:system_profile/2</seealso>
+ <seealso marker="#system_profile/2">erlang:system_profile/2</seealso>
as <c>{ProfilerPid, Options}</c>, or <c>undefined</c> if there
are no settings. The order of the options may be different
from the one that was set.</p>
@@ -6153,7 +6250,7 @@ true</pre>
<item>
<p>Trace certain function calls. Specify which function
calls to trace by calling
- <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
+ <seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
<p>Message tags: <c>call</c>, <c>return_from</c>.</p>
</item>
<tag><c>silent</c></tag>
@@ -6182,7 +6279,7 @@ true</pre>
Trace the actual return from a traced function back to
its caller. Only works for functions traced with
the <c>local</c> option to
- <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
+ <seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
<p>The semantics is that a trace message is sent when a
call traced function actually returns, that is, when a
chain of tail recursive calls is ended. There will be
@@ -6407,6 +6504,19 @@ true</pre>
<tag><c>mbuf_size</c></tag>
<item>The combined size of message buffers associated with
the process.</item>
+
+ <tag><c>bin_vheap_size</c></tag>
+ <item>The total size of unique off-heap binaries referenced from the process heap.</item>
+ <tag><c>bin_vheap_block_size</c></tag>
+ <item>The total size of binaries, in words, allowed in the virtual
+ heap in the process before doing a garbage collection. </item>
+ <tag><c>bin_old_vheap_size</c></tag>
+ <item>The total size of unique off-heap binaries referenced from the process old heap.</item>
+ <tag><c>bin_vheap_block_size</c></tag>
+ <item>The total size of binaries, in words, allowed in the virtual
+ old heap in the process before doing a garbage collection. </item>
+
+
</taglist>
<p>All sizes are in words.</p>
</item>
@@ -6557,7 +6667,7 @@ true</pre>
<c>true</c> for the pseudo function <c>on_load</c> if call
count tracing is active. Return <c>false</c> otherwise.
See also
- <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
+ <seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
</item>
<tag><c>all</c></tag>
<item>
@@ -6580,7 +6690,7 @@ true</pre>
<fsummary>Set trace patterns for global call tracing</fsummary>
<desc>
<p>The same as
- <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern(MFA, MatchSpec, [])</seealso>,
+ <seealso marker="#trace_pattern/3">erlang:trace_pattern(MFA, MatchSpec, [])</seealso>,
retained for backward compatibility.</p>
</desc>
</func>
@@ -6593,7 +6703,7 @@ true</pre>
<desc>
<p>This BIF is used to enable or disable call tracing for
exported functions. It must be combined with
- <seealso marker="#erlang:trace/3">erlang:trace/3</seealso>
+ <seealso marker="#trace/3">erlang:trace/3</seealso>
to set the <c>call</c> trace flag for one or more processes.</p>
<p>Conceptually, call tracing works like this: Inside
the Erlang virtual machine there is a set of processes to be
@@ -6603,7 +6713,7 @@ true</pre>
in the traced function set, the trace action will be taken.
Otherwise, nothing will happen.</p>
<p>Use
- <seealso marker="#erlang:trace/3">erlang:trace/3</seealso> to
+ <seealso marker="#trace/3">erlang:trace/3</seealso> to
add or remove one or more processes to the set of traced
processes. Use <c>erlang:trace_pattern/2</c> to add or remove
exported functions to the set of traced functions.</p>
@@ -6720,7 +6830,7 @@ true</pre>
counters can be restarted from zero with
<c>MatchSpec == restart</c>.</p>
<p>The counter value can be read with
- <seealso marker="#erlang:trace_info/2">erlang:trace_info/2</seealso>.</p>
+ <seealso marker="#trace_info/2">erlang:trace_info/2</seealso>.</p>
</item>
</taglist>
<p>The <c>global</c> and <c>local</c> options are mutually
@@ -6740,7 +6850,7 @@ true</pre>
specification list. If a function has a match specification,
you can replace it with a completely new one. If you need to
change an existing match specification, use the
- <seealso marker="#erlang:trace_info/2">erlang:trace_info/2</seealso>
+ <seealso marker="#trace_info/2">erlang:trace_info/2</seealso>
BIF to retrieve the existing match specification.</p>
<p>Returns the number of exported functions that matched
the <c>MFA</c> argument. This will be zero if none matched at
diff --git a/erts/doc/src/erlc.xml b/erts/doc/src/erlc.xml
index 3859ac8365..1e8960c22c 100644
--- a/erts/doc/src/erlc.xml
+++ b/erts/doc/src/erlc.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>erlc</title>
@@ -104,6 +104,10 @@
must be quoted. Terms which contain spaces
must be quoted on all platforms.</p>
</item>
+ <tag>-W<em>error</em></tag>
+ <item>
+ <p>Makes all warnings into errors.</p>
+ </item>
<tag>-W<em>number</em></tag>
<item>
<p>Sets warning level to <em>number</em>. Default is <c><![CDATA[1]]></c>.
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 2252358e0d..5fe414841e 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>ERTS Release Notes</title>
@@ -242,7 +242,7 @@
<item>
<p>
The <seealso
- marker="erlang#erlang:port_command/3">erlang:port_command/3</seealso>
+ marker="erlang#port_command/3">erlang:port_command/3</seealso>
BIF has been added. <c>erlang:port_command/3</c> is
currently not auto imported, but it is planned to be auto
imported in OTP R14. For more information see the
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index 903e1e96ba..bc846d1e3d 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -1,24 +1,25 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
include ../vsn.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
ENABLE_ALLOC_TYPE_VARS = @ENABLE_ALLOC_TYPE_VARS@
HIPE_ENABLED=@HIPE_ENABLED@
@@ -213,7 +214,7 @@ else
OPT_LEVEL = -O3
endif
-ifeq ($(CC), gcc)
+ifeq ($(GCC),yes)
ifeq ($(NO_INLINE_FUNCTIONS),true)
GEN_OPT_FLGS = $(OPT_LEVEL) -fno-inline-functions
else
@@ -252,7 +253,7 @@ CS_TYPE_FLAGS = $(subst QUANTIFY,FAKE_QUANTIFY, \
$(subst PURIFY,FAKE_PURIFY, $(TYPE_FLAGS)))
endif
CS_CFLAGS_ = $(CS_TYPE_FLAGS) @DEFS@ $(WFLAGS)
-ifeq ($(CC), gcc)
+ifeq ($(GCC),yes)
CS_CFLAGS = $(subst -O2, $(GEN_OPT_FLGS) $(UNROLL_FLG), $(CS_CFLAGS_))
else
CS_CFLAGS = $(CS_CFLAGS_)
@@ -351,7 +352,6 @@ endif
CS_EXECUTABLE = child_setup$(TYPEMARKER)
# ----------------------------------------------------------------------
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
ifeq ($(ERLANG_OSTYPE), unix)
UNIX_ONLY_BUILDS = $(BINDIR)/$(CS_EXECUTABLE)
@@ -692,7 +692,7 @@ $(OBJDIR)/%.kp.o: sys/common/%.c
$(OBJDIR)/%.nkp.o: sys/common/%.c
$(CC) -DERTS_NO_KERNEL_POLL_VERSION $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@
-ifeq ($(CC), gcc)
+ifeq ($(GCC),yes)
$(OBJDIR)/erl_obsolete.o: beam/erl_obsolete.c
$(CC) $(subst -Wstrict-prototypes, , $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS))) $(INCLUDES) -c $< -o $@
diff --git a/erts/emulator/beam/atom.c b/erts/emulator/beam/atom.c
index dfc3cde6a7..e2a79d6e4f 100644
--- a/erts/emulator/beam/atom.c
+++ b/erts/emulator/beam/atom.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -322,7 +322,7 @@ init_atom_table(void)
text_list = NULL;
erts_index_init(ERTS_ALC_T_ATOM_TABLE, &erts_atom_table,
- "atom_tab", ATOM_SIZE, ATOM_LIMIT, f);
+ "atom_tab", ATOM_SIZE, erts_atom_table_size, f);
more_atom_space();
/* Ordinary atoms */
diff --git a/erts/emulator/beam/atom.h b/erts/emulator/beam/atom.h
index e7e0dc440d..cb245a87b1 100644
--- a/erts/emulator/beam/atom.h
+++ b/erts/emulator/beam/atom.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -28,6 +28,17 @@
#define MAX_ATOM_LENGTH 255
#define ATOM_LIMIT (1024*1024)
+#define MIN_ATOM_TABLE_SIZE 8192
+
+#ifndef ARCH_32
+/* Internal atom cache needs MAX_ATOM_TABLE_SIZE to be less than an
+ unsigned 32 bit integer. See external.c(erts_encode_ext_dist_header_setup)
+ for more details. */
+#define MAX_ATOM_TABLE_SIZE ((MAX_ATOM_INDEX + 1 < (1UL << 32)) ? MAX_ATOM_INDEX + 1 : (1UL << 32))
+#else
+#define MAX_ATOM_TABLE_SIZE (MAX_ATOM_INDEX + 1)
+#endif
+
/*
* Atom entry.
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 04eac2d807..57c8b08223 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -303,6 +303,7 @@ atom messages
atom meta
atom meta_match_spec
atom min_heap_size
+atom min_bin_vheap_size
atom minor_version
atom Minus='-'
atom module
@@ -446,6 +447,7 @@ atom running
atom running_ports
atom running_procs
atom runtime
+atom safe
atom save_calls
atom scheduler
atom scheduler_id
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 4ebb8853be..13757b7d1c 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -286,6 +286,15 @@ extern int count_instructions;
#endif
+#ifdef FORCE_HEAP_FRAGS
+# define HEAP_SPACE_VERIFIED(Words) do { \
+ c_p->space_verified = (Words); \
+ c_p->space_verified_from = HTOP; \
+ }while(0)
+#else
+# define HEAP_SPACE_VERIFIED(Words) ((void)0)
+#endif
+
#define PRE_BIF_SWAPOUT(P) \
HEAP_TOP((P)) = HTOP; \
(P)->stop = E; \
@@ -411,6 +420,7 @@ extern int count_instructions;
r(0) = reg[0]; \
SWAPIN; \
} \
+ HEAP_SPACE_VERIFIED(need); \
} while (0)
@@ -432,6 +442,7 @@ extern int count_instructions;
r(0) = reg[0]; \
SWAPIN; \
} \
+ HEAP_SPACE_VERIFIED(need); \
} while (0)
/*
@@ -456,6 +467,7 @@ extern int count_instructions;
Extra = reg[Live]; \
SWAPIN; \
} \
+ HEAP_SPACE_VERIFIED(need); \
} while (0)
#ifdef HYBRID
@@ -832,6 +844,7 @@ extern int count_instructions;
LIGHT_SWAPOUT; \
_result = erts_bs_get_float_2(c_p, _size, (Flags), _mb); \
LIGHT_SWAPIN; \
+ HEAP_SPACE_VERIFIED(0); \
if (is_non_value(_result)) { Fail; } \
else { Store(_result, Dst); } \
} while (0)
@@ -845,6 +858,7 @@ extern int count_instructions;
LIGHT_SWAPOUT; \
_result = erts_bs_get_binary_2(c_p, (Sz), (Flags), _mb); \
LIGHT_SWAPIN; \
+ HEAP_SPACE_VERIFIED(0); \
if (is_non_value(_result)) { Fail; } \
else { Store(_result, Dst); } \
} while (0)
@@ -859,6 +873,7 @@ extern int count_instructions;
LIGHT_SWAPOUT; \
_result = erts_bs_get_binary_2(c_p, _size, (Flags), _mb); \
LIGHT_SWAPIN; \
+ HEAP_SPACE_VERIFIED(0); \
if (is_non_value(_result)) { Fail; } \
else { Store(_result, Dst); } \
} while (0)
@@ -873,9 +888,12 @@ extern int count_instructions;
LIGHT_SWAPOUT; \
_result = erts_bs_get_binary_all_2(c_p, _mb); \
LIGHT_SWAPIN; \
+ HEAP_SPACE_VERIFIED(0); \
ASSERT(is_value(_result)); \
Store(_result, Dst); \
- } else { Fail; } \
+ } else { \
+ HEAP_SPACE_VERIFIED(0); \
+ Fail; } \
} while (0)
#define BsSkipBits2(Ms, Bits, Unit, Fail) \
@@ -1360,6 +1378,7 @@ void process_main(void)
*/
c_p->cp = 0;
CHECK_TERM(r(0));
+ HEAP_SPACE_VERIFIED(0);
Goto(*I);
}
@@ -2379,6 +2398,7 @@ void process_main(void)
if (is_big(tmp_arg1)) {
HTOP += bignum_header_arity(*HTOP) + 1;
}
+ HEAP_SPACE_VERIFIED(0);
if (is_nil(tmp_arg1)) {
/*
* This result must have been only slight larger
@@ -3225,6 +3245,7 @@ apply_bif_or_nif_epilogue:
sb->orig = new_binary;
new_binary = make_binary(sb);
}
+ HEAP_SPACE_VERIFIED(0);
StoreBifResult(2, new_binary);
} else {
Binary* bptr;
@@ -3712,6 +3733,7 @@ apply_bif_or_nif_epilogue:
*dst = *ms;
*HTOP = HEADER_BIN_MATCHSTATE(slots);
HTOP += wordsneeded;
+ HEAP_SPACE_VERIFIED(0);
StoreResult(make_matchstate(dst), Arg(3));
}
} else if (is_binary_header(header)) {
@@ -3725,6 +3747,7 @@ apply_bif_or_nif_epilogue:
#endif
result = erts_bs_start_match_2(c_p, tmp_arg1, slots);
HTOP = HEAP_TOP(c_p);
+ HEAP_SPACE_VERIFIED(0);
if (is_non_value(result)) {
ClauseFail();
} else {
@@ -3917,6 +3940,7 @@ apply_bif_or_nif_epilogue:
TestHeap(BIG_UINT_HEAP_SIZE, Arg(1));
_result = uint_to_big((Uint) _integer, HTOP);
HTOP += BIG_UINT_HEAP_SIZE;
+ HEAP_SPACE_VERIFIED(0);
}
#endif
StoreBifResult(2, _result);
@@ -3982,6 +4006,7 @@ apply_bif_or_nif_epilogue:
LIGHT_SWAPOUT;
result = erts_bs_get_integer_2(c_p, tmp_arg2, Arg(1), mb);
LIGHT_SWAPIN;
+ HEAP_SPACE_VERIFIED(0);
if (is_non_value(result)) {
ClauseFail();
}
@@ -4009,6 +4034,7 @@ apply_bif_or_nif_epilogue:
LIGHT_SWAPOUT;
result = erts_bs_get_integer_2(c_p, size, flags, mb);
LIGHT_SWAPIN;
+ HEAP_SPACE_VERIFIED(0);
if (is_non_value(result)) {
ClauseFail();
}
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 74b231d56d..9c8c0df9f0 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -807,11 +807,12 @@ BIF_RETTYPE spawn_opt_1(BIF_ALIST_1)
/*
* Store default values for options.
*/
- so.flags = SPO_USE_ARGS;
- so.min_heap_size = H_MIN_SIZE;
- so.priority = PRIORITY_NORMAL;
- so.max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs);
- so.scheduler = 0;
+ so.flags = SPO_USE_ARGS;
+ so.min_heap_size = H_MIN_SIZE;
+ so.min_vheap_size = BIN_VH_MIN_SIZE;
+ so.priority = PRIORITY_NORMAL;
+ so.max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs);
+ so.scheduler = 0;
/*
* Walk through the option list.
@@ -850,6 +851,15 @@ BIF_RETTYPE spawn_opt_1(BIF_ALIST_1)
} else {
so.min_heap_size = erts_next_heap_size(min_heap_size, 0);
}
+ } else if (arg == am_min_bin_vheap_size && is_small(val)) {
+ Sint min_vheap_size = signed_val(val);
+ if (min_vheap_size < 0) {
+ goto error;
+ } else if (min_vheap_size < BIN_VH_MIN_SIZE) {
+ so.min_vheap_size = BIN_VH_MIN_SIZE;
+ } else {
+ so.min_vheap_size = erts_next_heap_size(min_vheap_size, 0);
+ }
} else if (arg == am_fullsweep_after && is_small(val)) {
Sint max_gen_gcs = signed_val(val);
if (max_gen_gcs < 0) {
@@ -1485,6 +1495,23 @@ BIF_RETTYPE process_flag_2(BIF_ALIST_2)
}
BIF_RET(old_value);
}
+ else if (BIF_ARG_1 == am_min_bin_vheap_size) {
+ Sint i;
+ if (!is_small(BIF_ARG_2)) {
+ goto error;
+ }
+ i = signed_val(BIF_ARG_2);
+ if (i < 0) {
+ goto error;
+ }
+ old_value = make_small(BIF_P->min_vheap_size);
+ if (i < BIN_VH_MIN_SIZE) {
+ BIF_P->min_vheap_size = BIN_VH_MIN_SIZE;
+ } else {
+ BIF_P->min_vheap_size = erts_next_heap_size(i, 0);
+ }
+ BIF_RET(old_value);
+ }
else if (BIF_ARG_1 == am_sensitive) {
Uint is_sensitive;
if (BIF_ARG_2 == am_true) {
@@ -3736,10 +3763,35 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
BIF_RET(make_small(oval));
} else if (BIF_ARG_1 == am_min_heap_size) {
int oval = H_MIN_SIZE;
+
if (!is_small(BIF_ARG_2) || (n = signed_val(BIF_ARG_2)) < 0) {
goto error;
}
+
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_smp_block_system(0);
+
H_MIN_SIZE = erts_next_heap_size(n, 0);
+
+ erts_smp_release_system();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+
+ BIF_RET(make_small(oval));
+ } else if (BIF_ARG_1 == am_min_bin_vheap_size) {
+ int oval = BIN_VH_MIN_SIZE;
+
+ if (!is_small(BIF_ARG_2) || (n = signed_val(BIF_ARG_2)) < 0) {
+ goto error;
+ }
+
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_smp_block_system(0);
+
+ BIN_VH_MIN_SIZE = erts_next_heap_size(n, 0);
+
+ erts_smp_release_system();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+
BIF_RET(make_small(oval));
} else if (BIF_ARG_1 == am_display_items) {
int oval = display_items;
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 85a729208f..b6fa06354a 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -755,6 +755,11 @@ bif erlang:call_on_load_function/1
bif erlang:finish_after_on_load/2
#
+# New Bifs in R13B4
+#
+bif erlang:binary_to_term/2
+
+#
# Obsolete
#
diff --git a/erts/emulator/beam/erl_arith.c b/erts/emulator/beam/erl_arith.c
index b692832677..126ec7cc73 100644
--- a/erts/emulator/beam/erl_arith.c
+++ b/erts/emulator/beam/erl_arith.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -50,18 +50,16 @@ static ERTS_INLINE void maybe_shrink(Process* p, Eterm* hp, Eterm res, Uint allo
if (is_immed(res)) {
if (p->heap <= hp && hp < p->htop) {
p->htop = hp;
-#if defined(CHECK_FOR_HOLES)
- } else {
- erts_arith_shrink(p, hp);
-#endif
+ }
+ else {
+ erts_heap_frag_shrink(p, hp);
}
} else if ((actual = bignum_header_arity(*hp)+1) < alloc) {
if (p->heap <= hp && hp < p->htop) {
p->htop = hp+actual;
-#if defined(CHECK_FOR_HOLES)
- } else {
- erts_arith_shrink(p, hp+actual);
-#endif
+ }
+ else {
+ erts_heap_frag_shrink(p, hp+actual);
}
}
}
@@ -397,12 +395,11 @@ erts_mixed_plus(Process* p, Eterm arg1, Eterm arg2)
need_heap = BIG_NEED_SIZE(sz);
hp = HAlloc(p, need_heap);
res = big_plus(arg1, arg2, hp);
+ maybe_shrink(p, hp, res, need_heap);
if (is_nil(res)) {
- erts_arith_shrink(p, hp);
p->freason = SYSTEM_LIMIT;
return THE_NON_VALUE;
}
- maybe_shrink(p, hp, res, need_heap);
return res;
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
if (big_to_double(arg1, &f1.fd) < 0) {
@@ -533,12 +530,11 @@ erts_mixed_minus(Process* p, Eterm arg1, Eterm arg2)
need_heap = BIG_NEED_SIZE(sz);
hp = HAlloc(p, need_heap);
res = big_minus(arg1, arg2, hp);
+ maybe_shrink(p, hp, res, need_heap);
if (is_nil(res)) {
- erts_arith_shrink(p, hp);
p->freason = SYSTEM_LIMIT;
return THE_NON_VALUE;
}
- maybe_shrink(p, hp, res, need_heap);
return res;
default:
goto badarith;
@@ -731,12 +727,11 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2)
* the absolute value of the other is > 1.
*/
+ maybe_shrink(p, hp, res, need_heap);
if (is_nil(res)) {
- erts_arith_shrink(p, hp);
p->freason = SYSTEM_LIMIT;
return THE_NON_VALUE;
- }
- maybe_shrink(p, hp, res, need_heap);
+ }
return res;
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
if (big_to_double(arg1, &f1.fd) < 0) {
@@ -956,12 +951,11 @@ erts_int_div(Process* p, Eterm arg1, Eterm arg2)
need = BIG_NEED_SIZE(i-ires+1) + BIG_NEED_SIZE(i);
hp = HAlloc(p, need);
arg1 = big_div(arg1, arg2, hp);
+ maybe_shrink(p, hp, arg1, need);
if (is_nil(arg1)) {
- erts_arith_shrink(p, hp);
p->freason = SYSTEM_LIMIT;
return THE_NON_VALUE;
}
- maybe_shrink(p, hp, arg1, need);
}
return arg1;
default:
@@ -1004,12 +998,11 @@ erts_int_rem(Process* p, Eterm arg1, Eterm arg2)
Eterm* hp = HAlloc(p, need);
arg1 = big_rem(arg1, arg2, hp);
+ maybe_shrink(p, hp, arg1, need);
if (is_nil(arg1)) {
- erts_arith_shrink(p, hp);
p->freason = SYSTEM_LIMIT;
return THE_NON_VALUE;
}
- maybe_shrink(p, hp, arg1, need);
}
return arg1;
default:
@@ -1147,7 +1140,7 @@ trim_heap(Process* p, Eterm* hp, Eterm res)
* a garbage collection if there is insufficient heap space.
*/
-#define erts_arith_shrink horrible error
+#define erts_heap_frag_shrink horrible error
#define maybe_shrink horrible error
Eterm
diff --git a/erts/emulator/beam/erl_bif_guard.c b/erts/emulator/beam/erl_bif_guard.c
index 8b47db10dd..440b0b4f14 100644
--- a/erts/emulator/beam/erl_bif_guard.c
+++ b/erts/emulator/beam/erl_bif_guard.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2006-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2006-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -318,6 +318,10 @@ double_to_integer(Process* p, double x)
* The following code is used when a guard that may build on the
* heap is called directly. They must not use HAlloc(), but must
* do a garbage collection if there is insufficient heap space.
+ *
+ * Important note: All error checking MUST be done before doing
+ * a garbage collection. The compiler assumes that all registers
+ * are still valid if a guard BIF generates an exception.
*/
#define ERTS_NEED_GC(p, need) ((HEAP_LIMIT((p)) - HEAP_TOP((p))) <= (need))
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 60216aa8e4..5ff1f794df 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -543,6 +543,8 @@ static Eterm pi_args[] = {
am_last_calls,
am_total_heap_size,
am_suspending,
+ am_min_heap_size,
+ am_min_bin_vheap_size,
#ifdef HYBRID
am_message_binary
#endif
@@ -589,8 +591,10 @@ pi_arg2ix(Eterm arg)
case am_last_calls: return 24;
case am_total_heap_size: return 25;
case am_suspending: return 26;
+ case am_min_heap_size: return 27;
+ case am_min_bin_vheap_size: return 28;
#ifdef HYBRID
- case am_message_binary: return 27;
+ case am_message_binary: return 29;
#endif
default: return -1;
}
@@ -1355,6 +1359,30 @@ process_info_aux(Process *BIF_P,
break;
}
+ case am_fullsweep_after: {
+ Uint hsz = 3;
+ (void) erts_bld_uint(NULL, &hsz, MAX_GEN_GCS(rp));
+ hp = HAlloc(BIF_P, hsz);
+ res = erts_bld_uint(&hp, NULL, MAX_GEN_GCS(rp));
+ break;
+ }
+
+ case am_min_heap_size: {
+ Uint hsz = 3;
+ (void) erts_bld_uint(NULL, &hsz, MIN_HEAP_SIZE(rp));
+ hp = HAlloc(BIF_P, hsz);
+ res = erts_bld_uint(&hp, NULL, MIN_HEAP_SIZE(rp));
+ break;
+ }
+
+ case am_min_bin_vheap_size: {
+ Uint hsz = 3;
+ (void) erts_bld_uint(NULL, &hsz, MIN_VHEAP_SIZE(rp));
+ hp = HAlloc(BIF_P, hsz);
+ res = erts_bld_uint(&hp, NULL, MIN_VHEAP_SIZE(rp));
+ break;
+ }
+
case am_total_heap_size: {
ErlMessage *mp;
Uint total_heap_size;
@@ -1433,15 +1461,17 @@ process_info_aux(Process *BIF_P,
DECL_AM(minor_gcs);
Eterm t;
- hp = HAlloc(BIF_P, 3+2+3+2+3);
- t = TUPLE2(hp, AM_minor_gcs, make_small(GEN_GCS(rp)));
- hp += 3;
- res = CONS(hp, t, NIL);
- hp += 2;
- t = TUPLE2(hp, am_fullsweep_after, make_small(MAX_GEN_GCS(rp)));
- hp += 3;
- res = CONS(hp, t, res);
- hp += 2;
+ hp = HAlloc(BIF_P, 3+2 + 3+2 + 3+2 + 3+2 + 3); /* last "3" is for outside tuple */
+
+ t = TUPLE2(hp, AM_minor_gcs, make_small(GEN_GCS(rp))); hp += 3;
+ res = CONS(hp, t, NIL); hp += 2;
+ t = TUPLE2(hp, am_fullsweep_after, make_small(MAX_GEN_GCS(rp))); hp += 3;
+ res = CONS(hp, t, res); hp += 2;
+
+ t = TUPLE2(hp, am_min_heap_size, make_small(MIN_HEAP_SIZE(rp))); hp += 3;
+ res = CONS(hp, t, res); hp += 2;
+ t = TUPLE2(hp, am_min_bin_vheap_size, make_small(MIN_VHEAP_SIZE(rp))); hp += 3;
+ res = CONS(hp, t, res); hp += 2;
break;
}
@@ -1897,16 +1927,32 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
BIF_RET(res);
} else if (BIF_ARG_1 == am_garbage_collection){
Uint val = (Uint) erts_smp_atomic_read(&erts_max_gen_gcs);
- hp = HAlloc(BIF_P, 3+2);
- res = TUPLE2(hp, am_fullsweep_after, make_small(val));
- hp += 3;
- res = CONS(hp, res, NIL);
+ Eterm tup;
+ hp = HAlloc(BIF_P, 3+2 + 3+2 + 3+2);
+
+ tup = TUPLE2(hp, am_fullsweep_after, make_small(val)); hp += 3;
+ res = CONS(hp, tup, NIL); hp += 2;
+
+ tup = TUPLE2(hp, am_min_heap_size, make_small(H_MIN_SIZE)); hp += 3;
+ res = CONS(hp, tup, res); hp += 2;
+
+ tup = TUPLE2(hp, am_min_bin_vheap_size, make_small(BIN_VH_MIN_SIZE)); hp += 3;
+ res = CONS(hp, tup, res); hp += 2;
+
BIF_RET(res);
} else if (BIF_ARG_1 == am_fullsweep_after){
Uint val = (Uint) erts_smp_atomic_read(&erts_max_gen_gcs);
hp = HAlloc(BIF_P, 3);
res = TUPLE2(hp, am_fullsweep_after, make_small(val));
BIF_RET(res);
+ } else if (BIF_ARG_1 == am_min_heap_size) {
+ hp = HAlloc(BIF_P, 3);
+ res = TUPLE2(hp, am_min_heap_size,make_small(H_MIN_SIZE));
+ BIF_RET(res);
+ } else if (BIF_ARG_1 == am_min_bin_vheap_size) {
+ hp = HAlloc(BIF_P, 3);
+ res = TUPLE2(hp, am_min_bin_vheap_size,make_small(BIN_VH_MIN_SIZE));
+ BIF_RET(res);
} else if (BIF_ARG_1 == am_process_count) {
BIF_RET(make_small(erts_process_count()));
} else if (BIF_ARG_1 == am_process_limit) {
@@ -3131,6 +3177,13 @@ BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1)
else if (ERTS_IS_ATOM_STR("available_internal_state", BIF_ARG_1)) {
BIF_RET(am_true);
}
+ else if (ERTS_IS_ATOM_STR("force_heap_frags", BIF_ARG_1)) {
+#ifdef FORCE_HEAP_FRAGS
+ BIF_RET(am_true);
+#else
+ BIF_RET(am_false);
+#endif
+ }
}
else if (is_tuple(BIF_ARG_1)) {
Eterm* tp = tuple_val(BIF_ARG_1);
diff --git a/erts/emulator/beam/erl_bif_re.c b/erts/emulator/beam/erl_bif_re.c
index 16abab65b0..c027cd5984 100644
--- a/erts/emulator/beam/erl_bif_re.c
+++ b/erts/emulator/beam/erl_bif_re.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -884,7 +884,7 @@ re_run_3(BIF_ALIST_3)
int capture_count;
if (pflags & PARSE_FLAG_UNICODE &&
- (!is_binary(BIF_ARG_1) ||
+ (!is_binary(BIF_ARG_2) || !is_binary(BIF_ARG_1) ||
(is_list_cap && !(pflags & PARSE_FLAG_GLOBAL)))) {
BIF_TRAP3(urun_trap_exportp, BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3);
}
@@ -1020,6 +1020,9 @@ re_run_3(BIF_ALIST_3)
goto handle_iolist;
}
pb = (ProcBin *) bptr;
+ if (pb->flags) {
+ erts_emasculate_writable_binary(pb);
+ }
restart.subject = (char *) (pb->bytes+offset);
restart.flags |= RESTART_FLAG_SUBJECT_IN_BINARY;
} else {
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index d3a916d2d9..b421da591b 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -2529,7 +2529,9 @@ static TreeDbTerm *find_node(DbTableTree *tb, Eterm key)
this = this->right;
}
}
- release_stack(tb,stack);
+ if (stack) {
+ release_stack(tb,stack);
+ }
return this;
}
diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c
index 34ce87bc5d..e5c3c76fdd 100644
--- a/erts/emulator/beam/erl_debug.c
+++ b/erts/emulator/beam/erl_debug.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -344,7 +344,7 @@ void erts_check_for_holes(Process* p)
if (hf == p->last_mbuf) {
break;
}
- check_memory(hf->mem, hf->mem+hf->size);
+ check_memory(hf->mem, hf->mem+hf->used_size);
}
p->last_mbuf = MBUF(p);
}
@@ -386,7 +386,7 @@ void erts_check_heap(Process *p)
}
while (bp) {
- erts_check_memory(p,bp->mem,bp->mem + bp->size);
+ erts_check_memory(p,bp->mem,bp->mem + bp->used_size);
bp = bp->next;
}
}
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 6945317e65..e9bf37a173 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
#ifdef HAVE_CONFIG_H
@@ -961,12 +961,13 @@ do_minor(Process *p, int new_sz, Eterm* objv, int nobj)
n_htop = sweep_one_area(n_heap, n_htop, heap, heap_size);
} else {
Eterm* n_hp = n_heap;
+ Eterm* ptr;
+ Eterm val;
+ Eterm gval;
while (n_hp != n_htop) {
- Eterm* ptr;
- Eterm val;
- Eterm gval = *n_hp;
-
+ ASSERT(n_hp < n_htop);
+ gval = *n_hp;
switch (primary_tag(gval)) {
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
@@ -1402,68 +1403,6 @@ remove_message_buffers(Process* p)
}
}
-/*
- * Go through one root set array, move everything that it is one of the
- * heap fragments to our new heap.
- */
-static Eterm*
-collect_root_array(Process* p, Eterm* n_htop, Eterm* objv, int nobj)
-{
- ErlHeapFragment* qb;
- Eterm gval;
- Eterm* ptr;
- Eterm val;
-
- ASSERT(p->htop != NULL);
- while (nobj--) {
- gval = *objv;
-
- switch (primary_tag(gval)) {
-
- case TAG_PRIMARY_BOXED: {
- ptr = boxed_val(gval);
- val = *ptr;
- if (IS_MOVED(val)) {
- ASSERT(is_boxed(val));
- *objv++ = val;
- } else {
- for (qb = MBUF(p); qb != NULL; qb = qb->next) {
- if (in_area(ptr, qb->mem, qb->size*sizeof(Eterm))) {
- MOVE_BOXED(ptr,val,n_htop,objv);
- break;
- }
- }
- objv++;
- }
- break;
- }
-
- case TAG_PRIMARY_LIST: {
- ptr = list_val(gval);
- val = *ptr;
- if (is_non_value(val)) {
- *objv++ = ptr[1];
- } else {
- for (qb = MBUF(p); qb != NULL; qb = qb->next) {
- if (in_area(ptr, qb->mem, qb->size*sizeof(Eterm))) {
- MOVE_CONS(ptr,val,n_htop,objv);
- break;
- }
- }
- objv++;
- }
- break;
- }
-
- default: {
- objv++;
- break;
- }
- }
- }
- return n_htop;
-}
-
#ifdef HARDDEBUG
/*
@@ -1707,11 +1646,13 @@ sweep_rootset(Rootset* rootset, Eterm* htop, char* src, Uint src_size)
static Eterm*
sweep_one_area(Eterm* n_hp, Eterm* n_htop, char* src, Uint src_size)
{
- while (n_hp != n_htop) {
- Eterm* ptr;
- Eterm val;
- Eterm gval = *n_hp;
+ Eterm* ptr;
+ Eterm val;
+ Eterm gval;
+ while (n_hp != n_htop) {
+ ASSERT(n_hp < n_htop);
+ gval = *n_hp;
switch (primary_tag(gval)) {
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
@@ -1820,6 +1761,35 @@ sweep_one_heap(Eterm* heap_ptr, Eterm* heap_end, Eterm* htop, char* src, Uint sr
}
/*
+ * Move an area (heap fragment) by sweeping over it and set move markers.
+ */
+static Eterm*
+move_one_area(Eterm* n_htop, char* src, Uint src_size)
+{
+ Eterm* ptr = (Eterm*) src;
+ Eterm* end = ptr + src_size/sizeof(Eterm);
+ Eterm dummy_ref;
+
+ while (ptr != end) {
+ Eterm val;
+ ASSERT(ptr < end);
+ val = *ptr;
+ ASSERT(val != ERTS_HOLE_MARKER);
+ if (is_header(val)) {
+ ASSERT(ptr + header_arity(val) < end);
+ MOVE_BOXED(ptr, val, n_htop, &dummy_ref);
+ }
+ else { /* must be a cons cell */
+ ASSERT(ptr+1 < end);
+ MOVE_CONS(ptr, val, n_htop, &dummy_ref);
+ ptr += 2;
+ }
+ }
+
+ return n_htop;
+}
+
+/*
* Collect heap fragments and check that they point in the correct direction.
*/
@@ -1830,7 +1800,6 @@ collect_heap_frags(Process* p, Eterm* n_hstart, Eterm* n_htop,
ErlHeapFragment* qb;
char* frag_begin;
Uint frag_size;
- ErlMessage* mp;
/*
* We don't allow references to a heap fragments from the stack, heap,
@@ -1845,65 +1814,44 @@ collect_heap_frags(Process* p, Eterm* n_hstart, Eterm* n_htop,
#endif
/*
- * Go through the subset of the root set that is allowed to
- * reference data in heap fragments and move data from heap fragments
- * to our new heap.
- */
-
- if (nobj != 0) {
- n_htop = collect_root_array(p, n_htop, objv, nobj);
- }
- if (is_not_immed(p->fvalue)) {
- n_htop = collect_root_array(p, n_htop, &p->fvalue, 1);
- }
- if (is_not_immed(p->ftrace)) {
- n_htop = collect_root_array(p, n_htop, &p->ftrace, 1);
- }
- if (is_not_immed(p->seq_trace_token)) {
- n_htop = collect_root_array(p, n_htop, &p->seq_trace_token, 1);
- }
- if (is_not_immed(p->group_leader)) {
- n_htop = collect_root_array(p, n_htop, &p->group_leader, 1);
- }
-
- /*
- * Go through the message queue, move everything that is in one of the
- * heap fragments to our new heap.
- */
-
- for (mp = p->msg.first; mp != NULL; mp = mp->next) {
- /*
- * In most cases, mp->data.attached points to a heap fragment which is
- * self-contained and we will copy it to the heap at the
- * end of the GC to avoid scanning it.
- *
- * In a few cases, however, such as in process_info(Pid, messages)
- * and trace_delivered/1, a new message points to a term that has
- * been allocated by HAlloc() and mp->data.attached is NULL. Therefore
- * we need this loop.
- */
- if (mp->data.attached == NULL) {
- n_htop = collect_root_array(p, n_htop, mp->m, 2);
- }
- }
-
- /*
- * Now all references in the root set point to the new heap. However,
- * many references on the new heap point to heap fragments.
- */
-
+ * Move the heap fragments to the new heap. Note that no GC is done on
+ * the heap fragments. Any garbage will thus be moved as well and survive
+ * until next GC.
+ */
qb = MBUF(p);
- while (qb != NULL) {
- frag_begin = (char *) qb->mem;
- frag_size = qb->size * sizeof(Eterm);
+ while (qb != NULL) {
+ frag_size = qb->used_size * sizeof(Eterm);
if (frag_size != 0) {
- n_htop = sweep_one_area(n_hstart, n_htop, frag_begin, frag_size);
+ frag_begin = (char *) qb->mem;
+ n_htop = move_one_area(n_htop, frag_begin, frag_size);
}
qb = qb->next;
}
return n_htop;
}
+#ifdef DEBUG
+static Eterm follow_moved(Eterm term)
+{
+ Eterm* ptr;
+ switch (primary_tag(term)) {
+ case TAG_PRIMARY_IMMED1:
+ break;
+ case TAG_PRIMARY_BOXED:
+ ptr = boxed_val(term);
+ if (IS_MOVED(*ptr)) term = *ptr;
+ break;
+ case TAG_PRIMARY_LIST:
+ ptr = list_val(term);
+ if (is_non_value(ptr[0])) term = ptr[1];
+ break;
+ default:
+ abort();
+ }
+ return term;
+}
+#endif
+
static Uint
setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset)
{
@@ -1932,7 +1880,7 @@ setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset)
}
ASSERT((is_nil(p->seq_trace_token) ||
- is_tuple(p->seq_trace_token) ||
+ is_tuple(follow_moved(p->seq_trace_token)) ||
is_atom(p->seq_trace_token)));
if (is_not_immed(p->seq_trace_token)) {
roots[n].v = &p->seq_trace_token;
@@ -1944,7 +1892,7 @@ setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset)
is_internal_pid(p->tracer_proc) ||
is_internal_port(p->tracer_proc));
- ASSERT(is_pid(p->group_leader));
+ ASSERT(is_pid(follow_moved(p->group_leader)));
if (is_not_immed(p->group_leader)) {
roots[n].v = &p->group_leader;
roots[n].sz = 1;
@@ -2083,23 +2031,45 @@ shrink_new_heap(Process *p, Uint new_sz, Eterm *objv, int nobj)
}
static Uint
-next_vheap_size(Uint vheap, Uint vheap_sz) {
- if (vheap < H_MIN_SIZE) {
- return H_MIN_SIZE;
- }
+do_next_vheap_size(Uint vheap, Uint vheap_sz) {
+
+ /* grow
+ *
+ * vheap_sz ======================
+ *
+ * vheap 75% + grow
+ * ----------------------
+ *
+ * vheap 25 - 75% same
+ * ----------------------
+ *
+ * vheap ~ - 25% shrink
+ *
+ * ----------------------
+ */
+
+ if (vheap > (Uint) (vheap_sz*3/4)) {
+
+ while(vheap > (Uint) (vheap_sz*3/4)) {
+ vheap_sz = vheap_sz*2;
+ }
- /* grow */
- if (vheap > vheap_sz) {
- return erts_next_heap_size(2*vheap, 0);
+ return erts_next_heap_size(vheap_sz, 0);
}
- /* shrink */
- if ( vheap < vheap_sz/2) {
- return (Uint)vheap_sz*3/4;
+
+ if (vheap < (Uint) (vheap_sz/4)) {
+ return erts_next_heap_size((Uint) (vheap_sz / 2), 0);
}
return vheap_sz;
+
}
+static Uint
+next_vheap_size(Process* p, Uint vheap, Uint vheap_sz) {
+ vheap_sz = do_next_vheap_size(vheap, vheap_sz);
+ return vheap_sz < p->min_vheap_size ? p->min_vheap_size : vheap_sz;
+}
static void
sweep_proc_externals(Process *p, int fullsweep)
@@ -2302,8 +2272,8 @@ sweep_proc_bins(Process *p, int fullsweep)
FLAGS(p) |= F_NEED_FULLSWEEP;
}
- BIN_VHEAP_SZ(p) = next_vheap_size(bin_vheap, BIN_VHEAP_SZ(p));
- BIN_OLD_VHEAP_SZ(p) = next_vheap_size(BIN_OLD_VHEAP(p), BIN_OLD_VHEAP_SZ(p));
+ BIN_VHEAP_SZ(p) = next_vheap_size(p, bin_vheap, BIN_VHEAP_SZ(p));
+ BIN_OLD_VHEAP_SZ(p) = next_vheap_size(p, BIN_OLD_VHEAP(p), BIN_OLD_VHEAP_SZ(p));
MSO(p).overhead = bin_vheap;
/*
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 8afd349b85..17cf3b9597 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1997-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -84,9 +84,10 @@ int erts_use_sender_punish;
* Configurable parameters.
*/
-Uint display_items; /* no of items to display in traces etc */
+Uint display_items; /* no of items to display in traces etc */
Uint display_loads; /* print info about loaded modules */
int H_MIN_SIZE; /* The minimum heap grain */
+int BIN_VH_MIN_SIZE; /* The minimum binary virtual*/
Uint32 erts_debug_flags; /* Debug flags. */
#ifdef ERTS_OPCODE_COUNTER_SUPPORT
@@ -118,6 +119,8 @@ int erts_disable_tolerant_timeofday; /* Time correction can be disabled it is
* not and/or it is too slow.
*/
+int erts_atom_table_size = ATOM_LIMIT; /* Maximum number of atoms */
+
int erts_modified_timing_level;
int erts_no_crash_dump = 0; /* Use -d to suppress crash dump. */
@@ -252,7 +255,8 @@ erl_init(void)
no_schedulers,
no_schedulers_online);
- H_MIN_SIZE = erts_next_heap_size(H_MIN_SIZE, 0);
+ H_MIN_SIZE = erts_next_heap_size(H_MIN_SIZE, 0);
+ BIN_VH_MIN_SIZE = erts_next_heap_size(BIN_VH_MIN_SIZE, 0);
erts_init_trace();
erts_init_binary();
@@ -513,67 +517,73 @@ void erts_usage(void)
/* erts_fprintf(stderr, "-# number set the number of items to be used in traces etc\n"); */
- erts_fprintf(stderr, "-a size suggested stack size in kilo words for threads\n");
- erts_fprintf(stderr, " in the async-thread pool, valid range is [%d-%d]\n",
+ erts_fprintf(stderr, "-a size suggested stack size in kilo words for threads\n");
+ erts_fprintf(stderr, " in the async-thread pool, valid range is [%d-%d]\n",
ERTS_ASYNC_THREAD_MIN_STACK_SIZE,
ERTS_ASYNC_THREAD_MAX_STACK_SIZE);
- erts_fprintf(stderr, "-A number set number of threads in async thread pool,\n");
- erts_fprintf(stderr, " valid range is [0-%d]\n",
+ erts_fprintf(stderr, "-A number set number of threads in async thread pool,\n");
+ erts_fprintf(stderr, " valid range is [0-%d]\n",
ERTS_MAX_NO_OF_ASYNC_THREADS);
- erts_fprintf(stderr, "-B[c|d|i] c to have Ctrl-c interrupt the Erlang shell,\n");
- erts_fprintf(stderr, " d (or no extra option) to disable the break\n");
- erts_fprintf(stderr, " handler, i to ignore break signals\n");
+ erts_fprintf(stderr, "-B[c|d|i] c to have Ctrl-c interrupt the Erlang shell,\n");
+ erts_fprintf(stderr, " d (or no extra option) to disable the break\n");
+ erts_fprintf(stderr, " handler, i to ignore break signals\n");
/* erts_fprintf(stderr, "-b func set the boot function (default boot)\n"); */
- erts_fprintf(stderr, "-c disable continuous date/time correction with\n");
- erts_fprintf(stderr, " respect to uptime\n");
+ erts_fprintf(stderr, "-c disable continuous date/time correction with\n");
+ erts_fprintf(stderr, " respect to uptime\n");
- erts_fprintf(stderr, "-d don't write a crash dump for internally detected errors\n");
- erts_fprintf(stderr, " (halt(String) will still produce a crash dump)\n");
+ erts_fprintf(stderr, "-d don't write a crash dump for internally detected errors\n");
+ erts_fprintf(stderr, " (halt(String) will still produce a crash dump)\n");
- erts_fprintf(stderr, "-h number set minimum heap size in words (default %d)\n",
+ erts_fprintf(stderr, "-hms size set minimum heap size in words (default %d)\n",
H_DEFAULT_SIZE);
+ erts_fprintf(stderr, "-hmbs size set minimum binary virtual heap size in words (default %d)\n",
+ VH_DEFAULT_SIZE);
/* erts_fprintf(stderr, "-i module set the boot module (default init)\n"); */
- erts_fprintf(stderr, "-K boolean enable or disable kernel poll\n");
+ erts_fprintf(stderr, "-K boolean enable or disable kernel poll\n");
- erts_fprintf(stderr, "-l turn on auto load tracing\n");
+ erts_fprintf(stderr, "-l turn on auto load tracing\n");
- erts_fprintf(stderr, "-M<X> <Y> memory allocator switches,\n");
- erts_fprintf(stderr, " see the erts_alloc(3) documentation for more info.\n");
+ erts_fprintf(stderr, "-M<X> <Y> memory allocator switches,\n");
+ erts_fprintf(stderr, " see the erts_alloc(3) documentation for more info.\n");
- erts_fprintf(stderr, "-P number set maximum number of processes on this node,\n");
- erts_fprintf(stderr, " valid range is [%d-%d]\n",
+ erts_fprintf(stderr, "-P number set maximum number of processes on this node,\n");
+ erts_fprintf(stderr, " valid range is [%d-%d]\n",
ERTS_MIN_PROCESSES, ERTS_MAX_PROCESSES);
- erts_fprintf(stderr, "-R number set compatibility release number,\n");
- erts_fprintf(stderr, " valid range [%d-%d]\n",
+ erts_fprintf(stderr, "-R number set compatibility release number,\n");
+ erts_fprintf(stderr, " valid range [%d-%d]\n",
ERTS_MIN_COMPAT_REL, this_rel_num());
- erts_fprintf(stderr, "-r force ets memory block to be moved on realloc\n");
- erts_fprintf(stderr, "-sbt type set scheduler bind type, valid types are:\n");
- erts_fprintf(stderr, " u|ns|ts|ps|s|nnts|nnps|tnnps|db\n");
- erts_fprintf(stderr, "-sct cput set cpu topology,\n");
- erts_fprintf(stderr, " see the erl(1) documentation for more info.\n");
- erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n");
- erts_fprintf(stderr, " valid range is [%d-%d]\n",
+ erts_fprintf(stderr, "-r force ets memory block to be moved on realloc\n");
+ erts_fprintf(stderr, "-sbt type set scheduler bind type, valid types are:\n");
+ erts_fprintf(stderr, " u|ns|ts|ps|s|nnts|nnps|tnnps|db\n");
+ erts_fprintf(stderr, "-sct cput set cpu topology,\n");
+ erts_fprintf(stderr, " see the erl(1) documentation for more info.\n");
+ erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n");
+ erts_fprintf(stderr, " valid range is [%d-%d]\n",
ERTS_SCHED_THREAD_MIN_STACK_SIZE,
ERTS_SCHED_THREAD_MAX_STACK_SIZE);
- erts_fprintf(stderr, "-S n1:n2 set number of schedulers (n1), and number of\n");
- erts_fprintf(stderr, " schedulers online (n2), valid range for both\n");
- erts_fprintf(stderr, " numbers are [1-%d]\n",
+ erts_fprintf(stderr, "-S n1:n2 set number of schedulers (n1), and number of\n");
+ erts_fprintf(stderr, " schedulers online (n2), valid range for both\n");
+ erts_fprintf(stderr, " numbers are [1-%d]\n",
ERTS_MAX_NO_OF_SCHEDULERS);
- erts_fprintf(stderr, "-T number set modified timing level,\n");
- erts_fprintf(stderr, " valid range is [0-%d]\n",
+ erts_fprintf(stderr, "-t size set the maximum number of atoms the "
+ "emulator can handle\n");
+ erts_fprintf(stderr, " valid range is [%d-%d]\n",
+ MIN_ATOM_TABLE_SIZE, MAX_ATOM_TABLE_SIZE);
+ erts_fprintf(stderr, "-T number set modified timing level,\n");
+ erts_fprintf(stderr, " valid range is [0-%d]\n",
ERTS_MODIFIED_TIMING_LEVELS-1);
- erts_fprintf(stderr, "-V print Erlang version\n");
+ erts_fprintf(stderr, "-V print Erlang version\n");
- erts_fprintf(stderr, "-v turn on chatty mode (GCs will be reported etc)\n");
+ erts_fprintf(stderr, "-v turn on chatty mode (GCs will be reported etc)\n");
- erts_fprintf(stderr, "-W<i|w> set error logger warnings mapping,\n");
- erts_fprintf(stderr, " see error_logger documentation for details\n");
+ erts_fprintf(stderr, "-W<i|w> set error logger warnings mapping,\n");
+ erts_fprintf(stderr, " see error_logger documentation for details\n");
erts_fprintf(stderr, "\n");
erts_fprintf(stderr, "Note that if the emulator is started with erlexec (typically\n");
@@ -604,6 +614,7 @@ early_init(int *argc, char **argv) /*
erts_async_max_threads = 0;
erts_async_thread_suggested_stack_size = ERTS_ASYNC_THREAD_MIN_STACK_SIZE;
H_MIN_SIZE = H_DEFAULT_SIZE;
+ BIN_VH_MIN_SIZE = VH_DEFAULT_SIZE;
erts_initialized = 0;
@@ -922,17 +933,40 @@ erl_start(int argc, char **argv)
fprintf(stderr, "The undocumented +H option has been removed (R10B-6).\n\n");
break;
- case 'h':
- /* set default heap size */
- arg = get_arg(argv[i]+2, argv[i+1], &i);
- if ((H_MIN_SIZE = atoi(arg)) <= 0) {
- erts_fprintf(stderr, "bad heap size %s\n", arg);
- erts_usage();
+ case 'h': {
+ char *sub_param = argv[i]+2;
+ /* set default heap size
+ *
+ * h|ms - min_heap_size
+ * h|mbs - min_bin_vheap_size
+ *
+ */
+ if (has_prefix("mbs", sub_param)) {
+ arg = get_arg(sub_param+3, argv[i+1], &i);
+ if ((BIN_VH_MIN_SIZE = atoi(arg)) <= 0) {
+ erts_fprintf(stderr, "bad heap size %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM, ("using minimum binary virtual heap size %d\n", BIN_VH_MIN_SIZE));
+
+ } else if (has_prefix("ms", sub_param)) {
+ arg = get_arg(sub_param+2, argv[i+1], &i);
+ if ((H_MIN_SIZE = atoi(arg)) <= 0) {
+ erts_fprintf(stderr, "bad heap size %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM, ("using minimum heap size %d\n", H_MIN_SIZE));
+ } else {
+ /* backward compatibility */
+ arg = get_arg(argv[i]+2, argv[i+1], &i);
+ if ((H_MIN_SIZE = atoi(arg)) <= 0) {
+ erts_fprintf(stderr, "bad heap size %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM, ("using minimum heap size %d\n", H_MIN_SIZE));
}
- VERBOSE(DEBUG_SYSTEM,
- ("using minimum heap size %d\n",H_MIN_SIZE));
break;
-
+ }
case 'd':
/*
* Never produce crash dumps for internally detected
@@ -1112,6 +1146,22 @@ erl_start(int argc, char **argv)
}
break;
}
+ case 't':
+ /* set atom table size */
+ arg = get_arg(argv[i]+2, argv[i+1], &i);
+ errno = 0;
+ erts_atom_table_size = strtol(arg, NULL, 10);
+ if (errno != 0 ||
+ erts_atom_table_size < MIN_ATOM_TABLE_SIZE ||
+ erts_atom_table_size > MAX_ATOM_TABLE_SIZE) {
+ erts_fprintf(stderr, "bad atom table size %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM,
+ ("setting maximum number of atoms to %d\n",
+ erts_atom_table_size));
+ break;
+
case 'T' :
arg = get_arg(argv[i]+2, argv[i+1], &i);
errno = 0;
diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c
index 25f1d420d1..074b08ea57 100644
--- a/erts/emulator/beam/erl_lock_check.c
+++ b/erts/emulator/beam/erl_lock_check.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2005-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2005-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -84,6 +84,9 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "reg_tab", NULL },
{ "migration_info_update", NULL },
{ "proc_main", "pid" },
+#ifdef HIPE
+ { "hipe_mfait_lock", NULL },
+#endif
{ "nodes_monitors", NULL },
{ "driver_list", NULL },
{ "proc_link", "pid" },
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index 81fbdfbd5a..a056fce0c5 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1997-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/*
@@ -114,12 +114,8 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size,
nbp = (ErlHeapFragment*) ERTS_HEAP_REALLOC(ERTS_ALC_T_HEAP_FRAG,
(void *) bp,
- (sizeof(ErlHeapFragment)
- - sizeof(Eterm)
- + bp->size*sizeof(Eterm)),
- (sizeof(ErlHeapFragment)
- - sizeof(Eterm)
- + size*sizeof(Eterm)));
+ ERTS_HEAP_FRAG_SIZE(bp->size),
+ ERTS_HEAP_FRAG_SIZE(size));
if (bp != nbp) {
Uint off_sz = size < nbp->size ? size : nbp->size;
Eterm *sp = &bp->mem[0];
@@ -140,7 +136,7 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size,
#endif
}
nbp->size = size;
-
+ nbp->used_size = size;
#ifdef HARD_DEBUG
for (i = 0; i < brefs_size; i++)
@@ -175,9 +171,7 @@ free_message_buffer(ErlHeapFragment* bp)
erts_cleanup_offheap(&bp->off_heap);
ERTS_HEAP_FREE(ERTS_ALC_T_HEAP_FRAG,
(void *) bp,
- (sizeof(ErlHeapFragment)
- - sizeof(Eterm)
- + bp->size*sizeof(Eterm)));
+ ERTS_HEAP_FRAG_SIZE(bp->size));
}
static ERTS_INLINE void
diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h
index f14f14a586..5cf7c209bd 100644
--- a/erts/emulator/beam/erl_message.h
+++ b/erts/emulator/beam/erl_message.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1997-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -50,19 +50,10 @@ struct erl_heap_fragment {
ErlHeapFragment* next; /* Next heap fragment */
ErlOffHeap off_heap; /* Offset heap data. */
unsigned size; /* Size in words of mem */
+ unsigned used_size; /* With terms to be moved to heap by GC */
Eterm mem[1]; /* Data */
};
-#define ERTS_SET_MBUF_HEAP_END(BP, HENDP) \
-do { \
- unsigned real_size__ = (BP)->size; \
- ASSERT((BP)->mem <= (HENDP) && (HENDP) <= (BP)->mem + real_size__); \
- (BP)->size = (HENDP) - (BP)->mem; \
- /* We do not reallocate since buffer *might* be moved. */ \
- /* FIXME: Memory count is wrong, but at least it's almost */ \
- /* right... */ \
-} while (0)
-
typedef struct erl_mesg {
struct erl_mesg* next; /* Next message */
union {
@@ -196,10 +187,12 @@ do { \
#define ERTS_HEAP_FRAG_SIZE(DATA_WORDS) \
(sizeof(ErlHeapFragment) - sizeof(Eterm) + (DATA_WORDS)*sizeof(Eterm))
+
#define ERTS_INIT_HEAP_FRAG(HEAP_FRAG_P, DATA_WORDS) \
do { \
(HEAP_FRAG_P)->next = NULL; \
(HEAP_FRAG_P)->size = (DATA_WORDS); \
+ (HEAP_FRAG_P)->used_size = (DATA_WORDS); \
(HEAP_FRAG_P)->off_heap.mso = NULL; \
(HEAP_FRAG_P)->off_heap.funs = NULL; \
(HEAP_FRAG_P)->off_heap.externals = NULL; \
diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c
index 0fb264a53c..3cb5a966ac 100644
--- a/erts/emulator/beam/erl_port_task.c
+++ b/erts/emulator/beam/erl_port_task.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2006-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2006-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -902,25 +902,45 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
*curr_port_pp = NULL;
- if (pp->sched.taskq) {
+#ifdef ERTS_SMP
+ ASSERT(runq == (ErtsRunQueue *) erts_smp_atomic_read(&pp->run_queue));
+#endif
+
+ if (!pp->sched.taskq) {
+ ASSERT(pp->sched.exe_taskq);
+ pp->sched.exe_taskq = NULL;
+ }
+ else {
+#ifdef ERTS_SMP
+ ErtsRunQueue *xrunq;
+#endif
+
ASSERT(!(pp->status & ERTS_PORT_SFLGS_DEAD));
ASSERT(pp->sched.taskq->first);
- enqueue_port(runq, pp);
- port_was_enqueued = 1;
-
- /*
- erts_smp_notify_inc_runq();
- * No need to notify schedulers about the increase in run
- * queue length since at least this thread, which is a
- * scheduler, will discover that the port run queue isn't
- * empty before trying to go to sleep.
- */
+#ifdef ERTS_SMP
+ xrunq = erts_check_emigration_need(runq, ERTS_PORT_PRIO_LEVEL);
+ if (!xrunq) {
+#endif
+ enqueue_port(runq, pp);
+ ASSERT(pp->sched.exe_taskq);
+ pp->sched.exe_taskq = NULL;
+ /* No need to notify ourselves about inc in runq. */
+#ifdef ERTS_SMP
+ }
+ else {
+ /* Port emigrated ... */
+ erts_smp_atomic_set(&pp->run_queue, (long) xrunq);
+ enqueue_port(xrunq, pp);
+ ASSERT(pp->sched.exe_taskq);
+ pp->sched.exe_taskq = NULL;
+ erts_smp_notify_inc_runq(xrunq);
+ erts_smp_runq_unlock(xrunq);
+ }
+#endif
+ port_was_enqueued = 1;
}
- ASSERT(pp->sched.exe_taskq);
- pp->sched.exe_taskq = NULL;
-
res = erts_smp_atomic_read(&erts_port_task_outstanding_io_tasks) != (long) 0;
ERTS_PT_CHK_PRES_PORTQ(runq, pp);
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index a4afe0574f..2789691c55 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -2522,8 +2522,11 @@ suspend_scheduler(ErtsSchedulerData *esdp)
NULL);
}
- erts_smp_atomic_inc(&schdlr_sspnd.active);
-
+ active_schedulers = erts_smp_atomic_inctest(&schdlr_sspnd.active);
+ if (schdlr_sspnd.changing == ERTS_SCHED_CHANGING_MULTI_SCHED
+ && schdlr_sspnd.online == active_schedulers) {
+ schdlr_sspnd.changing = 0;
+ }
erts_smp_mtx_unlock(&schdlr_sspnd.mtx);
if (erts_system_profile_flags.scheduler)
@@ -2750,18 +2753,19 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
ErtsProcList *plp;
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
- if (on) {
- if (schdlr_sspnd.changing) {
- res = ERTS_SCHDLR_SSPND_YIELD_RESTART; /* Yield */
- }
- else if (erts_is_multi_scheduling_blocked()) {
+
+ if (schdlr_sspnd.changing) {
+ res = ERTS_SCHDLR_SSPND_YIELD_RESTART; /* Yield */
+ }
+ else if (on) { /* ------ BLOCK ------ */
+ if (erts_is_multi_scheduling_blocked()) {
plp = proclist_create(p);
plp->next = schdlr_sspnd.msb.procs;
schdlr_sspnd.msb.procs = plp;
p->flags |= F_HAVE_BLCKD_MSCHED;
ASSERT(erts_smp_atomic_read(&schdlr_sspnd.active) == 1);
ASSERT(p->scheduler_data->no == 1);
- res = 1;
+ res = ERTS_SCHDLR_SSPND_DONE_MSCHED_BLOCKED;
}
else {
p->flags |= F_HAVE_BLCKD_MSCHED;
@@ -2842,10 +2846,11 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
}
}
else if (!ongoing_multi_scheduling_block()) {
+ /* unblock not ongoing */
ASSERT(!schdlr_sspnd.msb.procs);
res = ERTS_SCHDLR_SSPND_DONE;
}
- else {
+ else { /* ------ UNBLOCK ------ */
if (p->flags & F_HAVE_BLCKD_MSCHED) {
ErtsProcList **plpp = &schdlr_sspnd.msb.procs;
plp = schdlr_sspnd.msb.procs;
@@ -2891,12 +2896,16 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
#endif
p->flags &= ~F_HAVE_BLCKD_MSCHED;
erts_smp_atomic_set(&schdlr_sspnd.msb.ongoing, 0);
- if (schdlr_sspnd.online == 1)
- /* No schedulers to resume */;
+ if (schdlr_sspnd.online == 1) {
+ /* No schedulers to resume */
+ ASSERT(erts_smp_atomic_read(&schdlr_sspnd.active) == 1);
+ schdlr_sspnd.changing = 0;
+ }
else if (erts_common_run_queue) {
for (ix = 1; ix < schdlr_sspnd.online; ix++)
erts_smp_atomic_set(&ERTS_SCHEDULER_IX(ix)->suspended, 0);
wake_all_schedulers();
+ erts_smp_cnd_broadcast(&schdlr_sspnd.cnd);
}
else {
int online = schdlr_sspnd.online;
@@ -2928,9 +2937,8 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
erts_smp_runq_unlock(ERTS_RUNQ_IX(0));
erts_smp_mtx_unlock(&balance_info.update_mtx);
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
+ erts_smp_cnd_broadcast(&schdlr_sspnd.cnd);
}
- erts_smp_cnd_broadcast(&schdlr_sspnd.cnd);
- schdlr_sspnd.changing = 0;
res = ERTS_SCHDLR_SSPND_DONE;
}
}
@@ -5517,6 +5525,8 @@ erts_proc_migrate(Process *p, ErtsProcLocks *plcks,
p->run_queue = to_rq;
enqueue_process(to_rq, p);
+ smp_notify_inc_runq(to_rq);
+
return ERTS_MIGRATE_SUCCESS;
}
#endif /* ERTS_SMP */
@@ -6272,7 +6282,7 @@ Process *schedule(Process *p, int calls)
erts_check_my_tracer_proc(p);
#endif
- if ((FLAGS(p) & F_FORCE_GC) || (MSO(p).overhead >= BIN_VHEAP_SZ(p))) {
+ if ((FLAGS(p) & F_FORCE_GC) || (MSO(p).overhead > BIN_VHEAP_SZ(p))) {
reds -= erts_garbage_collect(p, 0, p->arg_reg, p->arity);
if (reds < 0) {
reds = 1;
@@ -6683,13 +6693,15 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
* noone except us has access to the process.
*/
if (so->flags & SPO_USE_ARGS) {
- p->min_heap_size = so->min_heap_size;
- p->prio = so->priority;
- p->max_gen_gcs = so->max_gen_gcs;
+ p->min_heap_size = so->min_heap_size;
+ p->min_vheap_size = so->min_vheap_size;
+ p->prio = so->priority;
+ p->max_gen_gcs = so->max_gen_gcs;
} else {
- p->min_heap_size = H_MIN_SIZE;
- p->prio = PRIORITY_NORMAL;
- p->max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs);
+ p->min_heap_size = H_MIN_SIZE;
+ p->min_vheap_size = BIN_VH_MIN_SIZE;
+ p->prio = PRIORITY_NORMAL;
+ p->max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs);
}
p->skipped = 0;
ASSERT(p->min_heap_size == erts_next_heap_size(p->min_heap_size, 0));
@@ -6736,9 +6748,9 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->heap_sz = sz;
p->catches = 0;
- p->bin_vheap_sz = H_MIN_SIZE;
- p->bin_old_vheap_sz = H_MIN_SIZE;
- p->bin_old_vheap = 0;
+ p->bin_vheap_sz = p->min_vheap_size;
+ p->bin_old_vheap_sz = p->min_vheap_size;
+ p->bin_old_vheap = 0;
/* No need to initialize p->fcalls. */
@@ -6969,6 +6981,7 @@ void erts_init_empty_process(Process *p)
p->gen_gcs = 0;
p->max_gen_gcs = 0;
p->min_heap_size = 0;
+ p->min_vheap_size = 0;
p->status = P_RUNABLE;
p->gcstatus = P_RUNABLE;
p->rstatus = P_RUNABLE;
@@ -6985,8 +6998,8 @@ void erts_init_empty_process(Process *p)
p->ftrace = NIL;
p->fcalls = 0;
- p->bin_vheap_sz=H_MIN_SIZE;
- p->bin_old_vheap_sz=H_MIN_SIZE;
+ p->bin_vheap_sz = BIN_VH_MIN_SIZE;
+ p->bin_old_vheap_sz = BIN_VH_MIN_SIZE;
p->bin_old_vheap = 0;
#ifdef ERTS_SMP
p->u.ptimer = NULL;
@@ -8024,11 +8037,6 @@ erts_do_exit_process(Process* p, Eterm reason)
if (p->bif_timers)
erts_cancel_bif_timers(p, ERTS_PROC_LOCKS_ALL);
-#ifdef ERTS_SMP
- if (p->flags & F_HAVE_BLCKD_MSCHED)
- erts_block_multi_scheduling(p, ERTS_PROC_LOCKS_ALL, 0, 1);
-#endif
-
erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR);
#ifdef ERTS_SMP
@@ -8073,6 +8081,27 @@ continue_exit_process(Process *p
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS);
#endif
+#ifdef ERTS_SMP
+ if (p->flags & F_HAVE_BLCKD_MSCHED) {
+ ErtsSchedSuspendResult ssr;
+ ssr = erts_block_multi_scheduling(p, ERTS_PROC_LOCK_MAIN, 0, 1);
+ switch (ssr) {
+ case ERTS_SCHDLR_SSPND_YIELD_RESTART:
+ goto yield;
+ case ERTS_SCHDLR_SSPND_DONE_MSCHED_BLOCKED:
+ case ERTS_SCHDLR_SSPND_YIELD_DONE_MSCHED_BLOCKED:
+ case ERTS_SCHDLR_SSPND_DONE:
+ case ERTS_SCHDLR_SSPND_YIELD_DONE:
+ p->flags &= ~F_HAVE_BLCKD_MSCHED;
+ break;
+ case ERTS_SCHDLR_SSPND_EINVAL:
+ default:
+ erl_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error: %d\n",
+ __FILE__, __LINE__, (int) ssr);
+ }
+ }
+#endif
+
if (p->flags & F_USING_DB) {
if (erts_db_process_exiting(p, ERTS_PROC_LOCK_MAIN))
goto yield;
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 7597eb5e31..f58b6932b3 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -477,6 +477,7 @@ struct ErtsPendingSuspend_ {
# define MSO(p) (p)->off_heap
# define MIN_HEAP_SIZE(p) (p)->min_heap_size
+# define MIN_VHEAP_SIZE(p) (p)->min_vheap_size
# define BIN_VHEAP_SZ(p) (p)->bin_vheap_sz
# define BIN_OLD_VHEAP_SZ(p) (p)->bin_old_vheap_sz
# define BIN_OLD_VHEAP(p) (p)->bin_old_vheap
@@ -495,6 +496,7 @@ struct process {
Eterm* hend; /* Heap end */
Uint heap_sz; /* Size of heap in words */
Uint min_heap_size; /* Minimum size of heap (in words). */
+ Uint min_vheap_size; /* Minimum size of virtual heap (in words). */
#if !defined(NO_FPE_SIGNALS)
volatile unsigned long fp_exception;
@@ -654,6 +656,11 @@ struct process {
* heap fragments.
*/
#endif
+
+#ifdef FORCE_HEAP_FRAGS
+ Uint space_verified; /* Avoid HAlloc forcing heap fragments when */
+ Eterm* space_verified_from; /* we rely on available heap space (TestHeap) */
+#endif
};
#ifdef CHECK_FOR_HOLES
@@ -725,8 +732,8 @@ typedef struct {
* The following items are only initialized if the SPO_USE_ARGS flag is set.
*/
Uint min_heap_size; /* Minimum heap size (must be a valued returned
- * from next_heap_size()).
- */
+ * from next_heap_size()). */
+ Uint min_vheap_size; /* Minimum virtual heap size */
int priority; /* Priority for process. */
Uint16 max_gen_gcs; /* Maximum number of gen GCs before fullsweep. */
int scheduler;
@@ -738,7 +745,20 @@ typedef struct {
#define KILL_CATCHES(p) (p)->catches = -1
-void erts_arith_shrink(Process* p, Eterm* hp);
+/* Shrink heap fragment from _last_ HAlloc.
+*/
+ERTS_GLB_INLINE void erts_heap_frag_shrink(Process* p, Eterm* hp);
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+ERTS_GLB_INLINE void erts_heap_frag_shrink(Process* p, Eterm* hp)
+{
+ ErlHeapFragment* hf = MBUF(p);
+
+ ASSERT(hf!=NULL && (hp - hf->mem < (unsigned long)hf->size));
+
+ hf->used_size = hp - hf->mem;
+}
+#endif /* inline */
+
Eterm* erts_heap_alloc(Process* p, Uint need);
#ifdef CHECK_FOR_HOLES
Eterm* erts_set_hole_marker(Eterm* ptr, Uint sz);
diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c
index 76bfdecd9f..c15f85f8f1 100644
--- a/erts/emulator/beam/erl_time_sup.c
+++ b/erts/emulator/beam/erl_time_sup.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -754,12 +754,8 @@ get_sys_now(Uint* megasec, Uint* sec, Uint* microsec)
{
SysTimeval now;
- erts_smp_mtx_lock(&erts_timeofday_mtx);
-
sys_gettimeofday(&now);
- erts_smp_mtx_unlock(&erts_timeofday_mtx);
-
*megasec = (Uint) (now.tv_sec / 1000000);
*sec = (Uint) (now.tv_sec % 1000000);
*microsec = (Uint) (now.tv_usec);
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 2afb16fc52..2842c2361a 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -2171,6 +2171,11 @@ erts_bif_trace(int bif_index, Process* p,
void
trace_gc(Process *p, Eterm what)
{
+ ERTS_DECL_AM(bin_vheap_size);
+ ERTS_DECL_AM(bin_vheap_block_size);
+ ERTS_DECL_AM(bin_old_vheap_size);
+ ERTS_DECL_AM(bin_old_vheap_block_size);
+
ErlHeapFragment *bp = NULL;
ErlOffHeap *off_heap;
ERTS_TRACER_REF_TYPE tracer_ref = ERTS_NULL_TRACER_REF; /* Initialized
@@ -2180,6 +2185,7 @@ trace_gc(Process *p, Eterm what)
Eterm* hp;
Eterm msg = NIL;
Uint size;
+
Eterm tags[] = {
am_old_heap_block_size,
am_heap_block_size,
@@ -2187,8 +2193,13 @@ trace_gc(Process *p, Eterm what)
am_recent_size,
am_stack_size,
am_old_heap_size,
- am_heap_size
+ am_heap_size,
+ AM_bin_vheap_size,
+ AM_bin_vheap_block_size,
+ AM_bin_old_vheap_size,
+ AM_bin_old_vheap_block_size
};
+
Uint values[] = {
OLD_HEAP(p) ? OLD_HEND(p) - OLD_HEAP(p) : 0,
HEAP_SIZE(p),
@@ -2196,7 +2207,11 @@ trace_gc(Process *p, Eterm what)
HIGH_WATER(p) - HEAP_START(p),
STACK_START(p) - p->stop,
OLD_HEAP(p) ? OLD_HTOP(p) - OLD_HEAP(p) : 0,
- HEAP_TOP(p) - HEAP_START(p)
+ HEAP_TOP(p) - HEAP_START(p),
+ MSO(p).overhead,
+ BIN_VHEAP_SZ(p),
+ BIN_OLD_VHEAP(p),
+ BIN_OLD_VHEAP_SZ(p)
};
Eterm local_heap[(sizeof(values)/sizeof(Uint))
*(2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE)
diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h
index 4d8315ab95..50b3e5b61c 100644
--- a/erts/emulator/beam/erl_vm.h
+++ b/erts/emulator/beam/erl_vm.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -22,6 +22,13 @@
/* #define ERTS_OPCODE_COUNTER_SUPPORT */
+/* FORCE_HEAP_FRAGS:
+ * Debug provocation to make HAlloc always create heap fragments (if allowed)
+ * even if there is room on heap.
+ */
+/* #define FORCE_HEAP_FRAGS */
+
+
#if defined(HYBRID)
/* # define CHECK_FOR_HOLES */
#endif
@@ -50,7 +57,8 @@
#define INPUT_REDUCTIONS (2 * CONTEXT_REDS)
-#define H_DEFAULT_SIZE 233 /* default (heap + stack) min size */
+#define H_DEFAULT_SIZE 233 /* default (heap + stack) min size */
+#define VH_DEFAULT_SIZE 32768 /* default virtual (bin) heap min size (words) */
#ifdef HYBRID
# define SH_DEFAULT_SIZE 2629425 /* default message area min size */
@@ -70,6 +78,7 @@
&& (P) == (P)->scheduler_data->match_pseudo_process) \
|| erts_is_system_blocked(0))
+
#ifdef DEBUG
/*
* Debug HAlloc that initialize all memory to bad things.
@@ -80,55 +89,43 @@
VERBOSE(DEBUG_ALLOCATION,("HAlloc @ 0x%08lx (%d) %s:%d\n", \
(unsigned long)HEAP_TOP(p),(sz),__FILE__,__LINE__)), \
*/
-#ifdef CHECK_FOR_HOLES
-#define HAlloc(p, sz) \
- (ASSERT_EXPR((sz) >= 0), \
- ErtsHAllocLockCheck(p), \
- ((((HEAP_LIMIT(p) - HEAP_TOP(p)) < (sz))) \
- ? erts_heap_alloc((p),(sz)) \
- : (erts_set_hole_marker(HEAP_TOP(p), (sz)), \
- HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz))))
+# ifdef CHECK_FOR_HOLES
+# define INIT_HEAP_MEM(p,sz) erts_set_hole_marker(HEAP_TOP(p), (sz))
+# else
+# define INIT_HEAP_MEM(p,sz) memset(HEAP_TOP(p),DEBUG_BAD_BYTE,(sz)*sizeof(Eterm*))
+# endif
#else
-#define HAlloc(p, sz) \
- (ASSERT_EXPR((sz) >= 0), \
- ErtsHAllocLockCheck(p), \
- ((((HEAP_LIMIT(p) - HEAP_TOP(p)) < (sz))) \
- ? erts_heap_alloc((p),(sz)) \
- : (memset(HEAP_TOP(p),DEBUG_BAD_BYTE,(sz)*sizeof(Eterm*)), \
- HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz))))
-#endif
+# define INIT_HEAP_MEM(p,sz) ((void)0)
+#endif /* DEBUG */
+
+
+#ifdef FORCE_HEAP_FRAGS
+# define IS_FORCE_HEAP_FRAGS 1
#else
+# define IS_FORCE_HEAP_FRAGS 0
+#endif
/*
* Allocate heap memory, first on the ordinary heap;
* failing that, in a heap fragment.
*/
-#define HAlloc(p, sz) \
- (ASSERT_EXPR((sz) >= 0), \
- ErtsHAllocLockCheck(p), \
- ((((HEAP_LIMIT(p) - HEAP_TOP(p)) < (sz))) \
- ? erts_heap_alloc((p),(sz)) \
- : (HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz))))
+#define HAlloc(p, sz) \
+ (ASSERT_EXPR((sz) >= 0), \
+ ErtsHAllocLockCheck(p), \
+ (IS_FORCE_HEAP_FRAGS || (((HEAP_LIMIT(p) - HEAP_TOP(p)) < (sz))) \
+ ? erts_heap_alloc((p),(sz)) \
+ : (INIT_HEAP_MEM(p,sz), \
+ HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz))))
-#endif /* DEBUG */
-#if defined(CHECK_FOR_HOLES)
-# define HRelease(p, endp, ptr) \
+#define HRelease(p, endp, ptr) \
if ((ptr) == (endp)) { \
; \
} else if (HEAP_START(p) <= (ptr) && (ptr) < HEAP_TOP(p)) { \
HEAP_TOP(p) = (ptr); \
} else { \
- erts_arith_shrink(p, ptr); \
+ erts_heap_frag_shrink(p, ptr); \
}
-#else
-# define HRelease(p, endp, ptr) \
- if ((ptr) == (endp)) { \
- ; \
- } else if (HEAP_START(p) <= (ptr) && (ptr) < HEAP_TOP(p)) { \
- HEAP_TOP(p) = (ptr); \
- }
-#endif
#define HeapWordsLeft(p) (HEAP_LIMIT(p) - HEAP_TOP(p))
@@ -182,6 +179,9 @@ extern int num_instructions; /* Number of instruction in opc[]. */
#define MAX_PORT_LINK 8 /* Maximum number of links to a port */
extern int H_MIN_SIZE; /* minimum (heap + stack) */
+extern int BIN_VH_MIN_SIZE; /* minimum virtual (bin) heap */
+
+extern int erts_atom_table_size;/* Atom table size */
#define ORIG_CREATION 0
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index f856cce18f..b011d4c0de 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -271,11 +271,8 @@ erts_encode_ext_dist_header_size(ErtsAtomCacheMap *acmp)
byte *erts_encode_ext_dist_header_setup(byte *ctl_ext, ErtsAtomCacheMap *acmp)
{
-#ifndef ARCH_32
-#if ATOM_LIMIT >= (1UL << 32)
-#error "ATOM_LIMIT too large for interal atom cache update instructions. New instructions needed."
-#endif
-#endif
+ /* Maximum number of atom must be less than the maximum of a 32 bits
+ unsigned integer. Check is done in erl_init.c, erl_start function. */
if (!acmp)
return ctl_ext;
else {
@@ -1013,6 +1010,34 @@ term_to_binary_2(Process* p, Eterm Term, Eterm Flags)
return erts_term_to_binary(p, Term, level, flags);
}
+static uLongf binary2term_uncomp_size(byte* data, Sint size)
+{
+ z_stream stream;
+ int err;
+ const uInt chunk_size = 64*1024; /* Ask tmp-alloc about a suitable size? */
+ void* tmp_buf = erts_alloc(ERTS_ALC_T_TMP, chunk_size);
+ uLongf uncomp_size = 0;
+
+ stream.next_in = (Bytef*)data;
+ stream.avail_in = (uInt)size;
+ stream.next_out = tmp_buf;
+ stream.avail_out = (uInt)chunk_size;
+
+ erl_zlib_alloc_init(&stream);
+
+ err = inflateInit(&stream);
+ if (err == Z_OK) {
+ while ((err = inflate(&stream, Z_NO_FLUSH)) == Z_OK) {
+ uncomp_size += chunk_size - stream.avail_out;
+ stream.next_out = tmp_buf;
+ stream.avail_out = chunk_size;
+ }
+ inflateEnd(&stream);
+ }
+ erts_free(ERTS_ALC_T_TMP, tmp_buf);
+ return err == Z_STREAM_END ? uncomp_size : 0;
+}
+
static ERTS_INLINE Sint
binary2term_prepare(ErtsBinary2TermState *state, byte *data, Sint data_size)
{
@@ -1036,10 +1061,18 @@ binary2term_prepare(ErtsBinary2TermState *state, byte *data, Sint data_size)
state->extp = bytes;
}
else {
- uLongf dest_len = get_int32(bytes+1);
- state->extp = erts_alloc(ERTS_ALC_T_TMP, dest_len);
+ uLongf dest_len = (Uint32) get_int32(bytes+1);
+ bytes += 5;
+ size -= 5;
+ if (dest_len > 32*1024*1024
+ || (state->extp = erts_alloc_fnf(ERTS_ALC_T_TMP, dest_len)) == NULL) {
+ if (dest_len != binary2term_uncomp_size(bytes, size)) {
+ goto error;
+ }
+ state->extp = erts_alloc(ERTS_ALC_T_TMP, dest_len);
+ }
state->exttmp = 1;
- if (erl_zlib_uncompress(state->extp, &dest_len, bytes+5, size-5) != Z_OK)
+ if (erl_zlib_uncompress(state->extp, &dest_len, bytes, size) != Z_OK)
goto error;
size = (Sint) dest_len;
}
@@ -1059,10 +1092,10 @@ binary2term_abort(ErtsBinary2TermState *state)
}
static ERTS_INLINE Eterm
-binary2term_create(ErtsBinary2TermState *state, Eterm **hpp, ErlOffHeap *ohp)
+binary2term_create(ErtsDistExternal *edep, ErtsBinary2TermState *state, Eterm **hpp, ErlOffHeap *ohp)
{
Eterm res;
- if (!dec_term(NULL, hpp, state->extp, ohp, &res))
+ if (!dec_term(edep, hpp, state->extp, ohp, &res))
res = THE_NON_VALUE;
if (state->exttmp) {
state->exttmp = 0;
@@ -1086,7 +1119,7 @@ erts_binary2term_abort(ErtsBinary2TermState *state)
Eterm
erts_binary2term_create(ErtsBinary2TermState *state, Eterm **hpp, ErlOffHeap *ohp)
{
- return binary2term_create(state, hpp, ohp);
+ return binary2term_create(NULL,state, hpp, ohp);
}
BIF_RETTYPE binary_to_term_1(BIF_ALIST_1)
@@ -1114,7 +1147,67 @@ BIF_RETTYPE binary_to_term_1(BIF_ALIST_1)
hp = HAlloc(BIF_P, heap_size);
endp = hp + heap_size;
- res = binary2term_create(&b2ts, &hp, &MSO(BIF_P));
+ res = binary2term_create(NULL, &b2ts, &hp, &MSO(BIF_P));
+
+ erts_free_aligned_binary_bytes(temp_alloc);
+
+ if (hp > endp) {
+ erl_exit(1, ":%s, line %d: heap overrun by %d words(s)\n",
+ __FILE__, __LINE__, hp-endp);
+ }
+
+ HRelease(BIF_P, endp, hp);
+
+ if (res == THE_NON_VALUE)
+ goto error;
+
+ return res;
+}
+
+BIF_RETTYPE binary_to_term_2(BIF_ALIST_2)
+{
+ Sint heap_size;
+ Eterm res;
+ Eterm opts;
+ Eterm opt;
+ Eterm* hp;
+ Eterm* endp;
+ Sint size;
+ byte* bytes;
+ byte* temp_alloc = NULL;
+ ErtsBinary2TermState b2ts;
+ ErtsDistExternal fakedep;
+
+ fakedep.flags = 0;
+ opts = BIF_ARG_2;
+ while (is_list(opts)) {
+ opt = CAR(list_val(opts));
+ if (opt == am_safe) {
+ fakedep.flags |= ERTS_DIST_EXT_BTT_SAFE;
+ } else {
+ goto error;
+ }
+ opts = CDR(list_val(opts));
+ }
+
+ if (is_not_nil(opts))
+ goto error;
+
+ if ((bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc)) == NULL) {
+ error:
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_ERROR(BIF_P, BADARG);
+ }
+ size = binary_size(BIF_ARG_1);
+
+ heap_size = binary2term_prepare(&b2ts, bytes, size);
+ if (heap_size < 0)
+ goto error;
+
+ hp = HAlloc(BIF_P, heap_size);
+ endp = hp + heap_size;
+
+ res = binary2term_create(&fakedep, &b2ts, &hp, &MSO(BIF_P));
erts_free_aligned_binary_bytes(temp_alloc);
@@ -1300,7 +1393,7 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp)
switch (*ep++) {
case ATOM_CACHE_REF:
- if (!(edep->flags & ERTS_DIST_EXT_ATOM_TRANS_TAB))
+ if (!(edep && (edep->flags & ERTS_DIST_EXT_ATOM_TRANS_TAB)))
goto error;
n = get_int8(ep);
ep++;
@@ -1312,13 +1405,18 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp)
case ATOM_EXT:
len = get_int16(ep),
ep += 2;
- *objp = am_atom_put((char*)ep, len);
- ep += len;
- break;
+ goto dec_atom_common;
case SMALL_ATOM_EXT:
len = get_int8(ep);
ep++;
- *objp = am_atom_put((char*)ep, len);
+ dec_atom_common:
+ if (edep && (edep->flags & ERTS_DIST_EXT_BTT_SAFE)) {
+ if (!erts_atom_get((char*)ep, len, objp)) {
+ goto error;
+ }
+ } else {
+ *objp = am_atom_put((char*)ep, len);
+ }
ep += len;
break;
default:
@@ -1775,9 +1873,80 @@ is_external_string(Eterm list, int* p_is_string)
return len;
}
+/* Assumes that the ones to undo are preluding the lists. */
+static void
+undo_offheap_in_area(ErlOffHeap* off_heap, Eterm* start, Eterm* end)
+{
+ const Uint area_sz = (end - start) * sizeof(Eterm);
+ struct proc_bin* mso;
+ struct proc_bin** mso_nextp = NULL;
+#ifndef HYBRID /* FIND ME! */
+ struct erl_fun_thing* funs;
+ struct erl_fun_thing** funs_nextp = NULL;
+#endif
+ struct external_thing_* ext;
+ struct external_thing_** ext_nextp = NULL;
+
+ for (mso = off_heap->mso; ; mso=mso->next) {
+ if (!in_area(mso, start, area_sz)) {
+ if (mso_nextp != NULL) {
+ *mso_nextp = NULL;
+ erts_cleanup_mso(off_heap->mso);
+ off_heap->mso = mso;
+ }
+ break;
+ }
+ mso_nextp = &mso->next;
+ }
+
+#ifndef HYBRID /* FIND ME! */
+ for (funs = off_heap->funs; ; funs=funs->next) {
+ if (!in_area(funs, start, area_sz)) {
+ if (funs_nextp != NULL) {
+ *funs_nextp = NULL;
+ erts_cleanup_funs(off_heap->funs);
+ off_heap->funs = funs;
+ }
+ break;
+ }
+ funs_nextp = &funs->next;
+ }
+#endif
+ for (ext = off_heap->externals; ; ext=ext->next) {
+ if (!in_area(ext, start, area_sz)) {
+ if (ext_nextp != NULL) {
+ *ext_nextp = NULL;
+ erts_cleanup_externals(off_heap->externals);
+ off_heap->externals = ext;
+ }
+ break;
+ }
+ ext_nextp = &ext->next;
+ }
+
+ /* Assert that the ones to undo were indeed preluding the lists. */
+#ifdef DEBUG
+ for (mso = off_heap->mso; mso != NULL; mso=mso->next) {
+ ASSERT(!in_area(mso, start, area_sz));
+ }
+# ifndef HYBRID /* FIND ME! */
+ for (funs = off_heap->funs; funs != NULL; funs=funs->next) {
+ ASSERT(!in_area(funs, start, area_sz));
+ }
+# endif
+ for (ext = off_heap->externals; ext != NULL; ext=ext->next) {
+ ASSERT(!in_area(ext, start, area_sz));
+ }
+#endif /* DEBUG */
+}
+
+/* Decode term from external format into *objp.
+** On failure return NULL and (R13B04) *hpp will be unchanged.
+*/
static byte*
dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Eterm* objp)
{
+ Eterm* hp_saved = *hpp;
int n;
register Eterm* hp = *hpp; /* Please don't take the address of hp */
Eterm* next = objp;
@@ -1864,13 +2033,18 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
case ATOM_EXT:
n = get_int16(ep);
ep += 2;
- *objp = am_atom_put((char*)ep, n);
- ep += n;
- break;
+ goto dec_term_atom_common;
case SMALL_ATOM_EXT:
n = get_int8(ep);
ep++;
- *objp = am_atom_put((char*)ep, n);
+dec_term_atom_common:
+ if (edep && (edep->flags & ERTS_DIST_EXT_BTT_SAFE)) {
+ if (!erts_atom_get((char*)ep, n, objp)) {
+ goto error;
+ }
+ } else {
+ *objp = am_atom_put((char*)ep, n);
+ }
ep += n;
break;
case LARGE_TUPLE_EXT:
@@ -1973,7 +2147,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
ep = dec_pid(edep, hpp, ep, off_heap, objp);
hp = *hpp;
if (ep == NULL) {
- return NULL;
+ goto error;
}
break;
case PORT_EXT:
@@ -2039,7 +2213,6 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
goto ref_ext_common;
case NEW_REFERENCE_EXT:
-
ref_words = get_int16(ep);
ep += 2;
@@ -2209,7 +2382,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
ep = dec_term(edep, hpp, ep, off_heap, &temp);
hp = *hpp;
if (ep == NULL) {
- return NULL;
+ goto error;
}
if (!is_small(temp)) {
goto error;
@@ -2218,6 +2391,10 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
if (arity < 0) {
goto error;
}
+ if (edep && (edep->flags & ERTS_DIST_EXT_BTT_SAFE)) {
+ if (!erts_find_export_entry(mod, name, arity))
+ goto error;
+ }
*objp = make_export(hp);
*hp++ = HEADER_EXPORT;
*hp++ = (Eterm) erts_export_get_or_make_stub(mod, name, arity);
@@ -2235,8 +2412,6 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
Sint old_index;
unsigned num_free;
int i;
- Eterm* temp_hp;
- Eterm** hpp = &temp_hp;
Eterm temp;
ep += 4; /* Skip total size in bytes */
@@ -2248,23 +2423,16 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
num_free = get_int32(ep);
ep += 4;
hp += ERL_FUN_SIZE;
- if (num_free > 0) {
- /* Don't leave a hole in case we fail */
- *hp = make_pos_bignum_header(num_free-1);
- }
hp += num_free;
- *hpp = hp;
funp->thing_word = HEADER_FUN;
funp->num_free = num_free;
- funp->creator = NIL; /* Don't leave a hole in case we fail */
*objp = make_fun(funp);
/* Module */
- if ((ep = dec_atom(edep, ep, &temp)) == NULL) {
+ if ((ep = dec_atom(edep, ep, &module)) == NULL) {
goto error;
}
- module = temp;
-
+ *hpp = hp;
/* Index */
if ((ep = dec_term(edep, hpp, ep, off_heap, &temp)) == NULL) {
goto error;
@@ -2321,17 +2489,11 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
Sint old_index;
unsigned num_free;
int i;
- Eterm* temp_hp;
- Eterm** hpp = &temp_hp;
Eterm temp;
num_free = get_int32(ep);
ep += 4;
hp += ERL_FUN_SIZE;
- if (num_free > 0) {
- /* Don't leave a hole in the heap in case we fail. */
- *hp = make_pos_bignum_header(num_free-1);
- }
hp += num_free;
*hpp = hp;
funp->thing_word = HEADER_FUN;
@@ -2339,23 +2501,16 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
*objp = make_fun(funp);
/* Creator pid */
- switch(*ep) {
- case PID_EXT:
- ep = dec_pid(edep, hpp, ++ep, off_heap, &funp->creator);
- if (ep == NULL) {
- funp->creator = NIL; /* Don't leave a hole in the heap */
- goto error;
- }
- break;
- default:
+ if (*ep != PID_EXT
+ || (ep = dec_pid(edep, hpp, ++ep, off_heap,
+ &funp->creator))==NULL) {
goto error;
}
/* Module */
- if ((ep = dec_atom(edep, ep, &temp)) == NULL) {
+ if ((ep = dec_atom(edep, ep, &module)) == NULL) {
goto error;
}
- module = temp;
/* Index */
if ((ep = dec_term(edep, hpp, ep, off_heap, &temp)) == NULL) {
@@ -2382,7 +2537,6 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
funp->next = off_heap->funs;
off_heap->funs = funp;
#endif
-
old_uniq = unsigned_val(temp);
funp->fe = erts_put_fun_entry(module, old_uniq, old_index);
@@ -2401,12 +2555,15 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
}
default:
error:
- /*
- * Be careful to return the updated heap pointer, to avoid
- * that the caller wipes out binaries or other off-heap objects
- * that may have been linked into the process.
+ /* UNDO:
+ * Must unlink all off-heap objects that may have been
+ * linked into the process.
*/
- *hpp = hp;
+ if (hp < *hpp) { /* Sometimes we used hp and sometimes *hpp */
+ hp = *hpp; /* the largest must be the freshest */
+ }
+ undo_offheap_in_area(off_heap, hp_saved, hp);
+ *hpp = hp_saved;
return NULL;
}
}
diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h
index f308680f89..eada6d4f27 100644
--- a/erts/emulator/beam/external.h
+++ b/erts/emulator/beam/external.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -98,9 +98,19 @@ typedef struct {
Eterm atom[ERTS_ATOM_CACHE_SIZE];
} ErtsAtomTranslationTable;
-#define ERTS_DIST_EXT_DFLAG_HDR (((Uint32) 1) << 31)
-#define ERTS_DIST_EXT_ATOM_TRANS_TAB (((Uint32) 1) << 30)
-#define ERTS_DIST_EXT_CON_ID_MASK ((Uint32) 0x3fffffff)
+/*
+ * These flags are tagged onto the high bits of a connection ID and stored in
+ * the ErtsDistExternal structure's flags field. They are used to indicate
+ * various bits of state necessary to decode binaries in a variety of
+ * scenarios. The mask ERTS_DIST_EXT_CON_ID_MASK is used later to separate the
+ * connection ID from the flags. Be careful to ensure that the mask does not
+ * overlap any of the bits used for flags, or ERTS will leak flags bits into
+ * connection IDs and leak connection ID bits into the flags.
+ */
+#define ERTS_DIST_EXT_DFLAG_HDR ((Uint32) 0x80000000)
+#define ERTS_DIST_EXT_ATOM_TRANS_TAB ((Uint32) 0x40000000)
+#define ERTS_DIST_EXT_BTT_SAFE ((Uint32) 0x20000000)
+#define ERTS_DIST_EXT_CON_ID_MASK ((Uint32) 0x1fffffff)
#define ERTS_DIST_EXT_CON_ID(DIST_EXTP) \
((DIST_EXTP)->flags & ERTS_DIST_EXT_CON_ID_MASK)
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 62a788cbff..df0ab40074 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -1658,7 +1658,6 @@ void erts_bif_trace_init(void);
/*
** Call_trace uses this API for the parameter matching functions
*/
- struct erl_heap_fragment* saved_program_buf;
#define MatchSetRef(MPSP) \
do { \
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index be442fa480..c162395159 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -95,6 +95,7 @@ dispatch_profile_msg_q(profile_sched_msg_q *psmq)
#endif
+
Eterm*
erts_heap_alloc(Process* p, Uint need)
{
@@ -105,13 +106,29 @@ erts_heap_alloc(Process* p, Uint need)
Uint i;
#endif
+#ifdef FORCE_HEAP_FRAGS
+ if (p->space_verified && p->space_verified_from!=NULL
+ && HEAP_TOP(p) >= p->space_verified_from
+ && HEAP_TOP(p) + need <= p->space_verified_from + p->space_verified
+ && HEAP_LIMIT(p) - HEAP_TOP(p) >= need) {
+
+ Uint consumed = need + (HEAP_TOP(p) - p->space_verified_from);
+ ASSERT(consumed <= p->space_verified);
+ p->space_verified -= consumed;
+ p->space_verified_from += consumed;
+ HEAP_TOP(p) = p->space_verified_from;
+ return HEAP_TOP(p) - need;
+ }
+ p->space_verified = 0;
+ p->space_verified_from = NULL;
+#endif /* FORCE_HEAP_FRAGS */
+
n = need;
#ifdef DEBUG
n++;
#endif
bp = (ErlHeapFragment*)
- ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP_FRAG,
- sizeof(ErlHeapFragment) + ((n-1)*sizeof(Eterm)));
+ ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP_FRAG, ERTS_HEAP_FRAG_SIZE(n));
#ifdef DEBUG
n--;
@@ -140,6 +157,7 @@ erts_heap_alloc(Process* p, Uint need)
bp->next = MBUF(p);
MBUF(p) = bp;
bp->size = n;
+ bp->used_size = n;
MBUF_SIZE(p) += n;
bp->off_heap.mso = NULL;
#ifndef HYBRID /* FIND ME! */
@@ -151,34 +169,6 @@ erts_heap_alloc(Process* p, Uint need)
return bp->mem;
}
-void erts_arith_shrink(Process* p, Eterm* hp)
-{
-#if defined(CHECK_FOR_HOLES)
- ErlHeapFragment* hf;
-
- /*
- * We must find the heap fragment that hp points into.
- * If we are unlucky, we might have to search through
- * a large part of the list. We'll hope that will not
- * happen too often.
- */
- for (hf = MBUF(p); hf != 0; hf = hf->next) {
- if (hp - hf->mem < (unsigned long)hf->size) {
- /*
- * We are not allowed to changed hf->size (because the
- * size must be correct when deallocating). Therefore,
- * clear out the uninitialized part of the heap fragment.
- */
- Eterm* to = hf->mem + hf->size;
- while (hp < to) {
- *hp++ = NIL;
- }
- break;
- }
- }
-#endif
-}
-
#ifdef CHECK_FOR_HOLES
Eterm*
erts_set_hole_marker(Eterm* ptr, Uint sz)
diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c
index 032bf2e896..5291374e25 100644
--- a/erts/emulator/hipe/hipe_bif0.c
+++ b/erts/emulator/hipe/hipe_bif0.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2001-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2001-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/* $Id$
@@ -656,6 +656,7 @@ static void *hipe_get_emu_address(Eterm m, Eterm f, unsigned int arity, int is_r
address = hipe_find_emu_address(m, f, arity);
if (!address) {
/* if not found, stub it via the export entry */
+ /* no lock needed around erts_export_get_or_make_stub() */
Export *export_entry = erts_export_get_or_make_stub(m, f, arity);
address = export_entry->address;
}
@@ -1188,8 +1189,31 @@ static struct {
unsigned int mask; /* INV: mask == (1 << log2size)-1 */
unsigned int used;
struct hipe_mfa_info **bucket;
+ /*
+ * The mfa info table is normally updated by the loader,
+ * which runs in non-concurrent mode. Unfortunately runtime
+ * apply operations (get_na_nofail) update the table if
+ * they create a new stub for the mfa, which forces locking.
+ * XXX: Redesign apply et al to avoid those updates.
+ */
+ erts_smp_mtx_t lock;
} hipe_mfa_info_table;
+static inline void hipe_mfa_info_table_init_lock(void)
+{
+ erts_smp_mtx_init(&hipe_mfa_info_table.lock, "hipe_mfait_lock");
+}
+
+static inline void hipe_mfa_info_table_lock(void)
+{
+ erts_smp_mtx_lock(&hipe_mfa_info_table.lock);
+}
+
+static inline void hipe_mfa_info_table_unlock(void)
+{
+ erts_smp_mtx_unlock(&hipe_mfa_info_table.lock);
+}
+
#define HIPE_MFA_HASH(M,F,A) ((M) * (F) + (A))
static struct hipe_mfa_info **hipe_mfa_info_table_alloc_bucket(unsigned int size)
@@ -1258,9 +1282,11 @@ void hipe_mfa_info_table_init(void)
hipe_mfa_info_table.mask = size - 1;
hipe_mfa_info_table.used = 0;
hipe_mfa_info_table.bucket = hipe_mfa_info_table_alloc_bucket(size);
+
+ hipe_mfa_info_table_init_lock();
}
-static inline struct hipe_mfa_info *hipe_mfa_info_table_get(Eterm m, Eterm f, unsigned int arity)
+static inline struct hipe_mfa_info *hipe_mfa_info_table_get_locked(Eterm m, Eterm f, unsigned int arity)
{
unsigned long h;
unsigned int i;
@@ -1286,7 +1312,7 @@ void *hipe_mfa_find_na(Eterm m, Eterm f, unsigned int arity)
}
#endif
-static struct hipe_mfa_info *hipe_mfa_info_table_put(Eterm m, Eterm f, unsigned int arity)
+static struct hipe_mfa_info *hipe_mfa_info_table_put_locked(Eterm m, Eterm f, unsigned int arity)
{
unsigned long h;
unsigned int i;
@@ -1313,7 +1339,10 @@ static struct hipe_mfa_info *hipe_mfa_info_table_put(Eterm m, Eterm f, unsigned
static void hipe_mfa_set_na(Eterm m, Eterm f, unsigned int arity, void *address, int is_exported)
{
- struct hipe_mfa_info *p = hipe_mfa_info_table_put(m, f, arity);
+ struct hipe_mfa_info *p;
+
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_put_locked(m, f, arity);
#ifdef DEBUG_LINKER
printf("%s: ", __FUNCTION__);
print_mfa(m, f, arity);
@@ -1322,19 +1351,30 @@ static void hipe_mfa_set_na(Eterm m, Eterm f, unsigned int arity, void *address,
p->local_address = address;
if (is_exported)
p->remote_address = address;
+ hipe_mfa_info_table_unlock();
}
#if defined(__powerpc__) || defined(__ppc__) || defined(__powerpc64__) || defined(__arm__)
void *hipe_mfa_get_trampoline(Eterm m, Eterm f, unsigned int arity)
{
- struct hipe_mfa_info *p = hipe_mfa_info_table_put(m, f, arity);
- return p->trampoline;
+ struct hipe_mfa_info *p;
+ void *trampoline;
+
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_put_locked(m, f, arity);
+ trampoline = p->trampoline;
+ hipe_mfa_info_table_unlock();
+ return trampoline;
}
void hipe_mfa_set_trampoline(Eterm m, Eterm f, unsigned int arity, void *trampoline)
{
- struct hipe_mfa_info *p = hipe_mfa_info_table_put(m, f, arity);
+ struct hipe_mfa_info *p;
+
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_put_locked(m, f, arity);
p->trampoline = trampoline;
+ hipe_mfa_info_table_unlock();
}
#endif
@@ -1365,12 +1405,13 @@ BIF_RETTYPE hipe_bifs_invalidate_funinfo_native_addresses_1(BIF_ALIST_1)
struct mfa mfa;
struct hipe_mfa_info *p;
+ hipe_mfa_info_table_lock();
lst = BIF_ARG_1;
while (is_list(lst)) {
if (!term_to_mfa(CAR(list_val(lst)), &mfa))
- BIF_ERROR(BIF_P, BADARG);
+ break;
lst = CDR(list_val(lst));
- p = hipe_mfa_info_table_get(mfa.mod, mfa.fun, mfa.ari);
+ p = hipe_mfa_info_table_get_locked(mfa.mod, mfa.fun, mfa.ari);
if (p) {
p->remote_address = NULL;
p->local_address = NULL;
@@ -1393,6 +1434,7 @@ BIF_RETTYPE hipe_bifs_invalidate_funinfo_native_addresses_1(BIF_ALIST_1)
}
}
}
+ hipe_mfa_info_table_unlock();
if (is_not_nil(lst))
BIF_ERROR(BIF_P, BADARG);
BIF_RET(NIL);
@@ -1406,7 +1448,8 @@ void hipe_mfa_save_orig_beam_op(Eterm mod, Eterm fun, unsigned int ari, Eterm *p
orig_beam_op = pc[0];
if (orig_beam_op != BeamOpCode(op_hipe_trap_call_closure) &&
orig_beam_op != BeamOpCode(op_hipe_trap_call)) {
- p = hipe_mfa_info_table_put(mod, fun, ari);
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_put_locked(mod, fun, ari);
#ifdef DEBUG_LINKER
printf("%s: ", __FUNCTION__);
print_mfa(mod, fun, ari);
@@ -1414,6 +1457,7 @@ void hipe_mfa_save_orig_beam_op(Eterm mod, Eterm fun, unsigned int ari, Eterm *p
#endif
p->beam_code = pc;
p->orig_beam_op = orig_beam_op;
+ hipe_mfa_info_table_unlock();
} else {
#ifdef DEBUG_LINKER
printf("%s: ", __FUNCTION__);
@@ -1440,12 +1484,12 @@ static void *hipe_make_stub(Eterm m, Eterm f, unsigned int arity, int is_remote)
return StubAddress;
}
-static void *hipe_get_na_nofail(Eterm m, Eterm f, unsigned int a, int is_remote)
+static void *hipe_get_na_nofail_locked(Eterm m, Eterm f, unsigned int a, int is_remote)
{
struct hipe_mfa_info *p;
void *address;
- p = hipe_mfa_info_table_get(m, f, a);
+ p = hipe_mfa_info_table_get_locked(m, f, a);
if (p) {
/* find address, predicting for a runtime apply call */
address = p->remote_address;
@@ -1459,13 +1503,23 @@ static void *hipe_get_na_nofail(Eterm m, Eterm f, unsigned int a, int is_remote)
if (address)
return address;
} else
- p = hipe_mfa_info_table_put(m, f, a);
+ p = hipe_mfa_info_table_put_locked(m, f, a);
address = hipe_make_stub(m, f, a, is_remote);
/* XXX: how to tell if a BEAM MFA is exported or not? */
p->remote_address = address;
return address;
}
+static void *hipe_get_na_nofail(Eterm m, Eterm f, unsigned int a, int is_remote)
+{
+ void *p;
+
+ hipe_mfa_info_table_lock();
+ p = hipe_get_na_nofail_locked(m, f, a, is_remote);
+ hipe_mfa_info_table_unlock();
+ return p;
+}
+
/* used for apply/3 in hipe_mode_switch */
void *hipe_get_remote_na(Eterm m, Eterm f, unsigned int a)
{
@@ -1549,6 +1603,8 @@ int hipe_find_mfa_from_ra(const void *ra, Eterm *m, Eterm *f, unsigned int *a)
/* Note about locking: the table is only updated from the
loader, which runs with the rest of the system suspended. */
+ /* XXX: alas not true; see comment at hipe_mfa_info_table.lock */
+ hipe_mfa_info_table_lock();
bucket = hipe_mfa_info_table.bucket;
nrbuckets = 1 << hipe_mfa_info_table.log2size;
mfa = NULL;
@@ -1564,12 +1620,13 @@ int hipe_find_mfa_from_ra(const void *ra, Eterm *m, Eterm *f, unsigned int *a)
b = b->bucket.next;
}
}
- if (!mfa)
- return 0;
- *m = mfa->m;
- *f = mfa->f;
- *a = mfa->a;
- return 1;
+ if (mfa) {
+ *m = mfa->m;
+ *f = mfa->f;
+ *a = mfa->a;
+ }
+ hipe_mfa_info_table_unlock();
+ return mfa ? 1 : 0;
}
/*
@@ -1645,8 +1702,9 @@ BIF_RETTYPE hipe_bifs_add_ref_2(BIF_ALIST_2)
default:
goto badarg;
}
- callee_mfa = hipe_mfa_info_table_put(callee.mod, callee.fun, callee.ari);
- caller_mfa = hipe_mfa_info_table_put(caller.mod, caller.fun, caller.ari);
+ hipe_mfa_info_table_lock();
+ callee_mfa = hipe_mfa_info_table_put_locked(callee.mod, callee.fun, callee.ari);
+ caller_mfa = hipe_mfa_info_table_put_locked(caller.mod, caller.fun, caller.ari);
refers_to = erts_alloc(ERTS_ALC_T_HIPE, sizeof(*refers_to));
refers_to->mfa = callee_mfa;
@@ -1660,6 +1718,7 @@ BIF_RETTYPE hipe_bifs_add_ref_2(BIF_ALIST_2)
ref->flags = flags;
ref->next = callee_mfa->referred_from;
callee_mfa->referred_from = ref;
+ hipe_mfa_info_table_unlock();
BIF_RET(NIL);
@@ -1679,10 +1738,12 @@ BIF_RETTYPE hipe_bifs_mark_referred_from_1(BIF_ALIST_1) /* get_refs_from */
if (!term_to_mfa(BIF_ARG_1, &mfa))
BIF_ERROR(BIF_P, BADARG);
- p = hipe_mfa_info_table_get(mfa.mod, mfa.fun, mfa.ari);
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_get_locked(mfa.mod, mfa.fun, mfa.ari);
if (p)
for (ref = p->referred_from; ref != NULL; ref = ref->next)
ref->flags |= REF_FLAG_PENDING_REDIRECT;
+ hipe_mfa_info_table_unlock();
BIF_RET(NIL);
}
@@ -1695,7 +1756,8 @@ BIF_RETTYPE hipe_bifs_remove_refs_from_1(BIF_ALIST_1)
if (!term_to_mfa(BIF_ARG_1, &mfa))
BIF_ERROR(BIF_P, BADARG);
- caller_mfa = hipe_mfa_info_table_get(mfa.mod, mfa.fun, mfa.ari);
+ hipe_mfa_info_table_lock();
+ caller_mfa = hipe_mfa_info_table_get_locked(mfa.mod, mfa.fun, mfa.ari);
if (caller_mfa) {
refers_to = caller_mfa->refers_to;
while (refers_to) {
@@ -1725,6 +1787,7 @@ BIF_RETTYPE hipe_bifs_remove_refs_from_1(BIF_ALIST_1)
}
caller_mfa->refers_to = NULL;
}
+ hipe_mfa_info_table_unlock();
BIF_RET(NIL);
}
@@ -1742,14 +1805,15 @@ BIF_RETTYPE hipe_bifs_redirect_referred_from_1(BIF_ALIST_1)
if (!term_to_mfa(BIF_ARG_1, &mfa))
BIF_ERROR(BIF_P, BADARG);
- p = hipe_mfa_info_table_get(mfa.mod, mfa.fun, mfa.ari);
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_get_locked(mfa.mod, mfa.fun, mfa.ari);
if (p) {
prev = &p->referred_from;
ref = *prev;
while (ref) {
if (ref->flags & REF_FLAG_PENDING_REDIRECT) {
is_remote = ref->flags & REF_FLAG_IS_REMOTE;
- new_address = hipe_get_na_nofail(p->m, p->f, p->a, is_remote);
+ new_address = hipe_get_na_nofail_locked(p->m, p->f, p->a, is_remote);
if (ref->flags & REF_FLAG_IS_LOAD_MFA)
res = hipe_patch_insn(ref->address, (Uint)new_address, am_load_mfa);
else
@@ -1772,6 +1836,7 @@ BIF_RETTYPE hipe_bifs_redirect_referred_from_1(BIF_ALIST_1)
}
}
}
+ hipe_mfa_info_table_unlock();
BIF_RET(NIL);
}
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index e47dfa18f7..db2b3e10db 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -27,6 +27,7 @@
%% binary_to_list/1
%% binary_to_list/3
%% binary_to_term/1
+%% binary_to_term/2
%% bitstr_to_list/1
%% term_to_binary/1
%% erlang:external_size/1
@@ -49,7 +50,7 @@
t_hash/1,
bad_size/1,
bad_term_to_binary/1,
- bad_binary_to_term_2/1,
+ bad_binary_to_term_2/1,safe_binary_to_term2/1,
bad_binary_to_term/1, bad_terms/1, more_bad_terms/1,
otp_5484/1,otp_5933/1,
ordering/1,unaligned_order/1,gc_test/1,
@@ -66,7 +67,7 @@ all(suite) ->
t_split_binary, bad_split, t_concat_binary,
bad_list_to_binary, bad_binary_to_list, terms, terms_float,
external_size, t_iolist_size,
- bad_binary_to_term_2,
+ bad_binary_to_term_2,safe_binary_to_term2,
bad_binary_to_term, bad_terms, t_hash, bad_size, bad_term_to_binary,
more_bad_terms, otp_5484, otp_5933, ordering, unaligned_order,
gc_test, bit_sized_binary_sizes, bitlevel_roundtrip, otp_6817, otp_8117,
@@ -438,8 +439,11 @@ terms(Config) when is_list(Config) ->
ok
end,
Term = binary_to_term(Bin),
+ Term = erlang:binary_to_term(Bin, [safe]),
Unaligned = make_unaligned_sub_binary(Bin),
Term = binary_to_term(Unaligned),
+ Term = erlang:binary_to_term(Unaligned, []),
+ Term = erlang:binary_to_term(Bin, [safe]),
BinC = erlang:term_to_binary(Term, [compressed]),
Term = binary_to_term(BinC),
true = size(BinC) =< size(Bin),
@@ -538,6 +542,23 @@ bad_binary_to_term(Config) when is_list(Config) ->
bad_bin_to_term(BadBin) ->
{'EXIT',{badarg,_}} = (catch binary_to_term(BadBin)).
+bad_bin_to_term(BadBin,Opts) ->
+ {'EXIT',{badarg,_}} = (catch erlang:binary_to_term(BadBin,Opts)).
+
+safe_binary_to_term2(doc) -> "Test safety options for binary_to_term/2";
+safe_binary_to_term2(Config) when is_list(Config) ->
+ ?line bad_bin_to_term(<<131,100,0,14,"undefined_atom">>, [safe]),
+ ?line bad_bin_to_term(<<131,100,0,14,"other_bad_atom">>, [safe]),
+ BadHostAtom = <<100,0,14,"badguy@badhost">>,
+ Empty = <<0,0,0,0>>,
+ BadRef = <<131,114,0,3,BadHostAtom/binary,0,<<0,0,0,255>>/binary,
+ Empty/binary,Empty/binary>>,
+ ?line bad_bin_to_term(BadRef, [safe]), % good ref, with a bad atom
+ ?line fullsweep_after = erlang:binary_to_term(<<131,100,0,15,"fullsweep_after">>, [safe]), % should be a good atom
+ BadExtFun = <<131,113,100,0,4,98,108,117,101,100,0,4,109,111,111,110,97,3>>,
+ ?line bad_bin_to_term(BadExtFun, [safe]),
+ ok.
+
%% Tests bad input to binary_to_term/1.
bad_terms(suite) -> [];
@@ -559,11 +580,18 @@ corrupter(Term) ->
?line corrupter(CompressedBin, size(CompressedBin)-1).
corrupter(Bin, Pos) when Pos >= 0 ->
- ?line {ShorterBin, _} = split_binary(Bin, Pos),
+ ?line {ShorterBin, Rest} = split_binary(Bin, Pos),
?line catch binary_to_term(ShorterBin), %% emulator shouldn't crash
?line MovedBin = list_to_binary([ShorterBin]),
?line catch binary_to_term(MovedBin), %% emulator shouldn't crash
- ?line corrupter(MovedBin, Pos-1);
+
+ %% Bit faults, shouldn't crash
+ <<Byte,Tail/binary>> = Rest,
+ Fun = fun(M) -> FaultyByte = Byte bxor M,
+ catch binary_to_term(<<ShorterBin/binary,
+ FaultyByte, Tail/binary>>) end,
+ ?line lists:foreach(Fun,[1,2,4,8,16,32,64,128,255]),
+ ?line corrupter(Bin, Pos-1);
corrupter(_Bin, _) ->
ok.
diff --git a/erts/emulator/test/fun_SUITE.erl b/erts/emulator/test/fun_SUITE.erl
index 716ee3707d..a7889dfe90 100644
--- a/erts/emulator/test/fun_SUITE.erl
+++ b/erts/emulator/test/fun_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -627,7 +627,13 @@ refc_dist_1() ->
%% Fun is passed in an exit signal. Wait until it is gone.
?line wait_until(fun () -> 4 =/= fun_refc(F2) end),
?line 3 = fun_refc(F2),
- ?line 3 = fun_refc(F),
+ erts_debug:set_internal_state(available_internal_state, true),
+ ?line F_refc = case erts_debug:get_internal_state(force_heap_frags) of
+ false -> 3;
+ true -> 2 % GC after bif already decreased it
+ end,
+ ?line F_refc = fun_refc(F),
+ erts_debug:set_internal_state(available_internal_state, false),
refc_dist_send(Node, F).
refc_dist_send(Node, F) ->
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index fdedf30e78..77f850d0fb 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -41,7 +41,8 @@
bump_reductions/1, low_prio/1, binary_owner/1, yield/1, yield2/1,
process_status_exiting/1,
otp_4725/1, bad_register/1, garbage_collect/1, otp_6237/1,
- process_info_messages/1, process_flag_badarg/1,
+ process_info_messages/1, process_flag_badarg/1, process_flag_heap_size/1,
+ spawn_opt_heap_size/1,
processes_large_tab/1, processes_default_tab/1, processes_small_tab/1,
processes_this_tab/1, processes_apply_trap/1,
processes_last_call_trap/1, processes_gc_trap/1,
@@ -63,9 +64,8 @@ all(suite) ->
process_info_lock_reschedule, process_info_lock_reschedule2,
process_status_exiting,
bump_reductions, low_prio, yield, yield2, otp_4725, bad_register,
- garbage_collect, process_info_messages, process_flag_badarg, otp_6237,
- processes_bif,
- otp_7738].
+ garbage_collect, process_info_messages, process_flag_badarg, process_flag_heap_size,
+ spawn_opt_heap_size, otp_6237, processes_bif, otp_7738].
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(10)),
@@ -388,6 +388,8 @@ t_process_info(Config) when is_list(Config) ->
?line register(my_name, self()),
?line {registered_name, my_name} = process_info(self(), registered_name),
?line {status, running} = process_info(self(), status),
+ ?line {min_heap_size, 233} = process_info(self(), min_heap_size),
+ ?line {min_bin_vheap_size, 46368} = process_info(self(), min_bin_vheap_size),
?line {current_function, {?MODULE, t_process_info, 1}} =
process_info(self(), current_function),
?line Gleader = group_leader(),
@@ -437,6 +439,10 @@ process_info_other_msg(Config) when is_list(Config) ->
empty -> ok
end,
?line {messages,[]} = process_info(Pid, messages),
+
+ ?line {min_heap_size, 233} = process_info(Pid, min_heap_size),
+ ?line {min_bin_vheap_size, 46368} = process_info(Pid, min_bin_vheap_size),
+
?line Pid ! stop,
ok.
@@ -1148,6 +1154,8 @@ process_flag_badarg(Config) when is_list(Config) ->
?line chk_badarg(fun () -> process_flag(trap_exit, gurka) end),
?line chk_badarg(fun () -> process_flag(error_handler, 1) end),
?line chk_badarg(fun () -> process_flag(min_heap_size, gurka) end),
+ ?line chk_badarg(fun () -> process_flag(min_bin_vheap_size, gurka) end),
+ ?line chk_badarg(fun () -> process_flag(min_bin_vheap_size, -1) end),
?line chk_badarg(fun () -> process_flag(priority, 4711) end),
?line chk_badarg(fun () -> process_flag(save_calls, hmmm) end),
?line P= spawn_link(fun () -> receive die -> ok end end),
@@ -1774,6 +1782,34 @@ processes_gc_trap(Config) when is_list(Config) ->
?line exit(Suspendee, bang),
?line ok.
+process_flag_heap_size(doc) ->
+ [];
+process_flag_heap_size(suite) ->
+ [];
+process_flag_heap_size(Config) when is_list(Config) ->
+ HSize = 2584, % must be gc fib number
+ VHSize = 317811, % must be gc fib number
+ ?line OldHmin = erlang:process_flag(min_heap_size, HSize),
+ ?line {min_heap_size, HSize} = erlang:process_info(self(), min_heap_size),
+ ?line OldVHmin = erlang:process_flag(min_bin_vheap_size, VHSize),
+ ?line {min_bin_vheap_size, VHSize} = erlang:process_info(self(), min_bin_vheap_size),
+ ?line HSize = erlang:process_flag(min_heap_size, OldHmin),
+ ?line VHSize = erlang:process_flag(min_bin_vheap_size, OldVHmin),
+ ?line ok.
+
+spawn_opt_heap_size(doc) ->
+ [];
+spawn_opt_heap_size(suite) ->
+ [];
+spawn_opt_heap_size(Config) when is_list(Config) ->
+ HSize = 987, % must be gc fib number
+ VHSize = 46368, % must be gc fib number
+ ?line Pid = spawn_opt(fun () -> receive stop -> ok end end,
+ [{min_heap_size, HSize},{ min_bin_vheap_size, VHSize}]),
+ ?line {min_heap_size, HSize} = process_info(Pid, min_heap_size),
+ ?line {min_bin_vheap_size, VHSize} = process_info(Pid, min_bin_vheap_size),
+ ?line Pid ! stop,
+ ?line ok.
processes_term_proc_list(doc) ->
[];
diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl
index e644ad4dc8..c9101b77c2 100644
--- a/erts/emulator/test/scheduler_SUITE.erl
+++ b/erts/emulator/test/scheduler_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -48,7 +48,8 @@
scheduler_bind_types/1,
cpu_topology/1,
sct_cmd/1,
- sbt_cmd/1]).
+ sbt_cmd/1,
+ scheduler_suspend/1]).
-define(DEFAULT_TIMEOUT, ?t:minutes(10)).
@@ -65,7 +66,8 @@ all(suite) ->
equal_with_high,
equal_with_high_max,
bound_process,
- scheduler_bind].
+ scheduler_bind,
+ scheduler_suspend].
init_per_testcase(Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
@@ -882,11 +884,103 @@ sbt_test(Config, CpuTCmd, ClBt, Bt, LP) ->
?line stop_node(Node),
?line ok.
+scheduler_suspend(Config) when is_list(Config) ->
+ ?line Dog = ?t:timetrap(?t:minutes(2)),
+ ?line lists:foreach(fun (S) -> scheduler_suspend_test(Config, S) end,
+ [64, 32, 16, default]),
+ ?line ?t:timetrap_cancel(Dog),
+ ?line ok.
+scheduler_suspend_test(Config, Schedulers) ->
+ ?line Cmd = case Schedulers of
+ default ->
+ "";
+ _ ->
+ S = integer_to_list(Schedulers),
+ "+S"++S++":"++S
+ end,
+ ?line {ok, Node} = start_node(Config, Cmd),
+ ?line [SState] = mcall(Node, [fun () ->
+ erlang:system_info(schedulers_state)
+ end]),
+ ?line {Sched, _, _} = SState,
+ ?line true = is_integer(Sched),
+ ?line [ok] = mcall(Node, [fun () -> sst0_loop(300) end]),
+ ?line [ok] = mcall(Node, [fun () -> sst1_loop(300) end]),
+ ?line [ok] = mcall(Node, [fun () -> sst2_loop(300) end]),
+ ?line [ok, ok, ok, ok, ok] = mcall(Node,
+ [fun () -> sst0_loop(200) end,
+ fun () -> sst1_loop(200) end,
+ fun () -> sst2_loop(200) end,
+ fun () -> sst2_loop(200) end,
+ fun () -> sst3_loop(Sched, 200) end]),
+ ?line [SState] = mcall(Node, [fun () ->
+ erlang:system_info(schedulers_state)
+ end]),
+ ?line stop_node(Node),
+ ?line ok.
+
+
+sst0_loop(0) ->
+ ok;
+sst0_loop(N) ->
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, unblock),
+ erlang:yield(),
+ sst0_loop(N-1).
+
+sst1_loop(0) ->
+ ok;
+sst1_loop(N) ->
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, unblock),
+ sst1_loop(N-1).
+
+sst2_loop(0) ->
+ ok;
+sst2_loop(N) ->
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, unblock),
+ erlang:system_flag(multi_scheduling, unblock),
+ erlang:system_flag(multi_scheduling, unblock),
+ sst2_loop(N-1).
+
+sst3_loop(_S, 0) ->
+ ok;
+sst3_loop(S, N) ->
+ erlang:system_flag(schedulers_online, (S div 2)+1),
+ erlang:system_flag(schedulers_online, 1),
+ erlang:system_flag(schedulers_online, (S div 2)+1),
+ erlang:system_flag(schedulers_online, S),
+ erlang:system_flag(schedulers_online, 1),
+ erlang:system_flag(schedulers_online, S),
+ sst3_loop(S, N-1).
+
-%
+%%
%% Utils
%%
+mcall(Node, Funs) ->
+ Parent = self(),
+ Refs = lists:map(fun (Fun) ->
+ Ref = make_ref(),
+ spawn_link(Node,
+ fun () ->
+ Res = Fun(),
+ unlink(Parent),
+ Parent ! {Ref, Res}
+ end),
+ Ref
+ end, Funs),
+ lists:map(fun (Ref) ->
+ receive
+ {Ref, Res} ->
+ Res
+ end
+ end, Refs).
+
erl_rel_flag_var() ->
"ERL_"++erlang:system_info(otp_release)++"_FLAGS".
diff --git a/erts/emulator/test/statistics_SUITE.erl b/erts/emulator/test/statistics_SUITE.erl
index bc12821887..898908c40f 100644
--- a/erts/emulator/test/statistics_SUITE.erl
+++ b/erts/emulator/test/statistics_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -25,7 +25,7 @@
init_per_testcase/2,
fin_per_testcase/2,
wall_clock/1, wall_clock_zero_diff/1, wall_clock_update/1,
- runtime/1, runtime_zero_diff/1, runtime_zero_update/1,
+ runtime/1, runtime_zero_diff/1,
runtime_update/1, runtime_diff/1,
run_queue/1, run_queue_one/1,
reductions/1, reductions_big/1, garbage_collection/1, io/1,
@@ -99,8 +99,7 @@ wall_clock_update1(0) ->
%%% Test statistics(runtime).
-runtime(suite) -> [runtime_zero_diff, runtime_zero_update, runtime_update,
- runtime_diff].
+runtime(suite) -> [runtime_zero_diff, runtime_update, runtime_diff].
runtime_zero_diff(doc) ->
"Tests that the difference between the times returned from two consectuitive "
@@ -117,55 +116,32 @@ runtime_zero_diff1(N) when N > 0 ->
runtime_zero_diff1(0) ->
?line test_server:fail("statistics(runtime) never returned zero difference").
-runtime_zero_update(doc) ->
- "Test that the time differences returned by two calls to "
- "statistics(runtime) several seconds apart is zero.";
-runtime_zero_update(Config) when is_list(Config) ->
- case ?t:is_debug() of
- false -> ?line runtime_zero_update1(6);
- true -> {skip,"Unreliable in DEBUG build"}
- end.
-
-runtime_zero_update1(N) when N > 0 ->
- ?line {T1, _} = statistics(runtime),
- ?line receive after 7000 -> ok end,
- ?line case statistics(runtime) of
- {T, Td} when Td =< 80 ->
- test_server:format("ok, Runtime before: {~p, _} after: {~p, ~p}",
- [T1, T, Td]),
- ok;
- {T, R} ->
- test_server:format("nok, Runtime before: {~p, _} after: {~p, ~p}",
- [T1, T, R]),
- runtime_zero_update1(N-1)
- end;
-runtime_zero_update1(0) ->
- ?line test_server:fail("statistics(runtime) never returned zero difference").
-
runtime_update(doc) ->
- "Test that the statistics(runtime) returns a substanstially updated difference "
- "after running a process that takes all CPU power of the Erlang process "
- "for a second.";
+ "Test that the statistics(runtime) returns a substanstially "
+ "updated difference after running a process that takes all CPU "
+ " power of the Erlang process for a second.";
runtime_update(Config) when is_list(Config) ->
case ?t:is_cover() of
false ->
?line process_flag(priority, high),
- ?line test_server:m_out_of_n(1, 10, fun runtime_update/0);
+ do_runtime_update(10);
true ->
{skip,"Cover-compiled"}
end.
-runtime_update() ->
- ?line {T1,_} = statistics(runtime),
+do_runtime_update(0) ->
+ {comment,"Never close enough"};
+do_runtime_update(N) ->
+ ?line {T1,Diff0} = statistics(runtime),
?line spawn_link(fun cpu_heavy/0),
receive after 1000 -> ok end,
?line {T2,Diff} = statistics(runtime),
- ?line Delta = abs(Diff-1000),
- ?line test_server:format("T1 = ~p, T2 = ~p, Diff = ~p, abs(Diff-1000) = ~p",
- [T1,T2,Diff,Delta]),
+ ?line true = is_integer(T1+T2+Diff0+Diff),
+ ?line test_server:format("T1 = ~p, T2 = ~p, Diff = ~p, T2-T1 = ~p",
+ [T1,T2,Diff,T2-T1]),
?line if
- abs(Diff-1000) =:= Delta, Delta =< 100 ->
- ok
+ T2 - T1 =:= Diff, 900 =< Diff, Diff =< 1500 -> ok;
+ true -> do_runtime_update(N-1)
end.
cpu_heavy() ->
@@ -212,17 +188,18 @@ reductions(Config) when is_list(Config) ->
%% 300 * 4 is more than CONTEXT_REDS (1000). Thus, there will be one or
%% more context switches.
- reductions(300, Reductions).
+ Mask = (1 bsl erlang:system_info(wordsize)*8) - 1,
+ reductions(300, Reductions, Mask).
-reductions(N, Previous) when N > 0 ->
+reductions(N, Previous, Mask) when N > 0 ->
?line {Reductions, Diff} = statistics(reductions),
?line build_some_garbage(),
?line if Reductions > 0 -> ok end,
?line if Diff >= 0 -> ok end,
io:format("Previous = ~p, Reductions = ~p, Diff = ~p, DiffShouldBe = ~p",
- [Previous, Reductions, Diff, Reductions-Previous]),
- ?line if Reductions == Previous+Diff -> reductions(N-1, Reductions) end;
-reductions(0, _) ->
+ [Previous, Reductions, Diff, (Reductions-Previous) band Mask]),
+ ?line if Reductions == ((Previous+Diff) band Mask) -> reductions(N-1, Reductions, Mask) end;
+reductions(0, _, _) ->
ok.
build_some_garbage() ->
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl
index 2c7124839a..e782d2f293 100644
--- a/erts/emulator/test/system_info_SUITE.erl
+++ b/erts/emulator/test/system_info_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -35,12 +35,12 @@
%-compile(export_all).
-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
--export([process_count/1, system_version/1, misc_smoke_tests/1]).
+-export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1]).
-define(DEFAULT_TIMEOUT, ?t:minutes(2)).
all(doc) -> [];
-all(suite) -> [process_count, system_version, misc_smoke_tests].
+all(suite) -> [process_count, system_version, misc_smoke_tests, heap_size].
init_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
@@ -135,8 +135,13 @@ misc_smoke_tests(Config) when is_list(Config) ->
?line ok.
-
-
-
-
+heap_size(doc) -> [];
+heap_size(suite) -> [];
+heap_size(Config) when is_list(Config) ->
+ ?line {min_bin_vheap_size, VHmin} = erlang:system_info(min_bin_vheap_size),
+ ?line {min_heap_size, Hmin} = erlang:system_info(min_heap_size),
+ ?line GCinf = erlang:system_info(garbage_collection),
+ ?line VHmin = proplists:get_value(min_bin_vheap_size, GCinf),
+ ?line Hmin = proplists:get_value(min_heap_size, GCinf),
+ ok.
diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl
index 2c60ba6838..e9713fcf0f 100644
--- a/erts/emulator/test/trace_SUITE.erl
+++ b/erts/emulator/test/trace_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -498,19 +498,23 @@ system_monitor_long_gc_1(doc) ->
["Tests erlang:system_monitor(Pid, [{long_gc,Time}])"];
system_monitor_long_gc_1(Config) when is_list(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
- try
- %% Add ?LONG_GC_SLEEP ms to all gc
- ?line erts_debug:set_internal_state(test_long_gc_sleep,
- ?LONG_GC_SLEEP),
- ?line LoadFun =
- fun () ->
- garbage_collect(),
- self()
- end,
- ?line long_gc(LoadFun, false)
+ try
+ case erts_debug:get_internal_state(force_heap_frags) of
+ true ->
+ {skip,"emulator with FORCE_HEAP_FRAGS defined"};
+ false ->
+ %% Add ?LONG_GC_SLEEP ms to all gc
+ ?line erts_debug:set_internal_state(test_long_gc_sleep,
+ ?LONG_GC_SLEEP),
+ ?line LoadFun = fun () ->
+ garbage_collect(),
+ self()
+ end,
+ ?line long_gc(LoadFun, false)
+ end
after
erts_debug:set_internal_state(test_long_gc_sleep, 0),
- erts_debug:set_internal_state(available_internal_state, false)
+ erts_debug:set_internal_state(available_internal_state, false)
end.
system_monitor_long_gc_2(suite) ->
@@ -520,24 +524,29 @@ system_monitor_long_gc_2(doc) ->
system_monitor_long_gc_2(Config) when is_list(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
try
- %% Add ?LONG_GC_SLEEP ms to all gc
- ?line erts_debug:set_internal_state(test_long_gc_sleep,
- ?LONG_GC_SLEEP),
- ?line Parent = self(),
- ?line LoadFun =
- fun () ->
- Ref = make_ref(),
- Pid =
- spawn_link(
- fun () ->
- garbage_collect(),
- Parent ! {Ref, self()}
- end),
- receive {Ref, Pid} -> Pid end
- end,
- ?line long_gc(LoadFun, true),
- ?line long_gc(LoadFun, true),
- ?line long_gc(LoadFun, true)
+ case erts_debug:get_internal_state(force_heap_frags) of
+ true ->
+ {skip,"emulator with FORCE_HEAP_FRAGS defined"};
+ false ->
+ %% Add ?LONG_GC_SLEEP ms to all gc
+ ?line erts_debug:set_internal_state(test_long_gc_sleep,
+ ?LONG_GC_SLEEP),
+ ?line Parent = self(),
+ ?line LoadFun =
+ fun () ->
+ Ref = make_ref(),
+ Pid =
+ spawn_link(
+ fun () ->
+ garbage_collect(),
+ Parent ! {Ref, self()}
+ end),
+ receive {Ref, Pid} -> Pid end
+ end,
+ ?line long_gc(LoadFun, true),
+ ?line long_gc(LoadFun, true),
+ ?line long_gc(LoadFun, true)
+ end
after
erts_debug:set_internal_state(test_long_gc_sleep, 0),
erts_debug:set_internal_state(available_internal_state, false)
diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h
index b120b44579..65fcf9bacb 100644
--- a/erts/epmd/src/epmd_int.h
+++ b/erts/epmd/src/epmd_int.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/*
@@ -294,6 +294,7 @@ struct enode {
char protocol; /* 0 = tcp/ipv4 */
unsigned short highvsn; /* 0 = OTP-R3 erts-4.6.x, 1 = OTP-R4 erts-4.7.x*/
unsigned short lowvsn;
+ int extralen;
char extra[MAXSYMLEN+1];
};
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index b71e27cffd..a033fab244 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -1,20 +1,20 @@
/* -*- c-indent-level: 2; c-continued-statement-offset: 2 -*- */
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -99,7 +99,7 @@ static int conn_close_fd(EpmdVars*,int);
static void node_init(EpmdVars*);
static Node *node_reg(EpmdVars*,char*,int,int);
-static Node *node_reg2(EpmdVars*,char*, int, int, unsigned char, unsigned char, int, int, char*);
+static Node *node_reg2(EpmdVars*,char*, int, int, unsigned char, unsigned char, int, int, int, char*);
static int node_unreg(EpmdVars*,char*);
static int node_unreg_sock(EpmdVars*,int);
@@ -558,11 +558,11 @@ static void do_request(g, fd, s, buf, bsize)
}
name = &buf[11];
name[namelen]='\000';
- extra = &buf[11+namelen+1];
+ extra = &buf[11+namelen+2];
extra[extralen]='\000';
wbuf[0] = EPMD_ALIVE2_RESP;
if ((node = node_reg2(g, name, fd, eport, nodetype, protocol,
- highvsn, lowvsn, extra)) == NULL) {
+ highvsn, lowvsn, extralen, extra)) == NULL) {
wbuf[1] = 1; /* error */
put_int16(99, wbuf+2);
} else {
@@ -622,10 +622,10 @@ static void do_request(g, fd, s, buf, bsize)
offset = 12;
strcpy(wbuf + offset,node->symname);
offset += strlen(node->symname);
- put_int16(strlen(node->extra),wbuf + offset);
+ put_int16(node->extralen,wbuf + offset);
offset += 2;
- strcpy(wbuf + offset,node->extra);
- offset += (strlen(node->extra)-1);
+ memcpy(wbuf + offset,node->extra,node->extralen);
+ offset += node->extralen;
if (reply(g, fd, wbuf, offset) != offset)
{
dbg_tty_printf(g,1,"** failed to send PORT2_RESP (ok) for \"%s\"",name);
@@ -994,7 +994,7 @@ static int node_unreg_sock(EpmdVars *g,int fd)
static Node *node_reg(EpmdVars *g,char *name,int fd, int port)
{
- return node_reg2(g, name, fd, port, 0, 0, 0, 0, NULL);
+ return node_reg2(g, name, fd, port, 0, 0, 0, 0, 0, NULL);
}
static Node *node_reg2(EpmdVars *g,
@@ -1005,6 +1005,7 @@ static Node *node_reg2(EpmdVars *g,
unsigned char protocol,
int highvsn,
int lowvsn,
+ int extralen,
char* extra)
{
Node *prev; /* Point to previous node or NULL */
@@ -1103,7 +1104,8 @@ static Node *node_reg2(EpmdVars *g,
node->protocol = protocol;
node->highvsn = highvsn;
node->lowvsn = lowvsn;
- strcpy(node->extra,extra);
+ node->extralen = extralen;
+ memcpy(node->extra,extra,extralen);
strcpy(node->symname,name);
FD_SET(fd,&g->orig_read_mask);
diff --git a/erts/epmd/test/Makefile b/erts/epmd/test/Makefile
index c1d62f0f93..13dad09ae3 100644
--- a/erts/epmd/test/Makefile
+++ b/erts/epmd/test/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1998-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1998-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
@@ -34,6 +34,8 @@ ERL_FILES= $(MODULES:%=%.erl)
TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+EMAKEFILE=Emakefile
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
@@ -43,15 +45,17 @@ RELEPMDDIR = $(RELEASE_PATH)/epmd_test
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \
- -I$(ERL_TOP)/lib/kernel/src/ \
- $(EPMD_FLAGS)
+ERL_COMPILE_FLAGS += $(EPMD_FLAGS)
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
-tests debug opt: $(TARGET_FILES)
+tests debug opt: $(EMAKEFILE)
+
+$(EMAKEFILE): Makefile $(ERL_FILES)
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) \
+ -o$(EBIN) $(MODULES) > $(EMAKEFILE)
clean:
rm -f $(TARGET_FILES)
@@ -69,7 +73,7 @@ release_spec:
release_tests_spec: opt
$(INSTALL_DIR) $(RELEPMDDIR)
$(INSTALL_DATA) epmd.spec epmd.spec.vxworks $(ERL_FILES) \
- $(TARGET_FILES) $(RELEPMDDIR)
+ $(EMAKEFILE) $(RELEPMDDIR)
chmod -f -R u+w $(RELEPMDDIR)
release_docs_spec:
diff --git a/erts/epmd/test/epmd_SUITE.erl b/erts/epmd/test/epmd_SUITE.erl
index 513c87a13e..91e09faf75 100644
--- a/erts/epmd/test/epmd_SUITE.erl
+++ b/erts/epmd/test/epmd_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(epmd_SUITE).
@@ -31,6 +31,9 @@
-define(MEDIUM_PAUSE, ?t:seconds(1)).
-define(LONG_PAUSE, ?t:seconds(5)).
+% Information about nodes
+-record(node_info, {port, node_type, prot, lvsn, hvsn, node_name, extra}).
+
% Test server specific exports
-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
@@ -57,7 +60,10 @@
too_large/1,
alive_req_too_small_1/1,
alive_req_too_small_2/1,
- alive_req_too_large/1
+ alive_req_too_large/1,
+
+ returns_valid_empty_extra/1,
+ returns_valid_populated_extra_with_nulls/1
]).
@@ -76,9 +82,13 @@
-define(REG_REPEAT_LIM,1000).
% Message codes in epmd protocol
--define(EPMD_ALIVE_REQ, $a).
--define(EPMD_ALIVE_OK_RESP, $Y).
--define(EPMD_PORT_REQ, $p).
+-define(EPMD_ALIVE_REQ, $a).
+-define(EPMD_ALIVE2_REQ, $x).
+-define(EPMD_ALIVE_OK_RESP, $Y).
+-define(EPMD_ALIVE2_RESP, $y).
+-define(EPMD_PORT_REQ, $p).
+-define(EPMD_PORT_PLEASE2_REQ, $z).
+-define(EPMD_PORT2_RESP, $w).
-define(EPMD_NAMES_REQ, $n).
-define(EPMD_DUMP_REQ, $d).
-define(EPMD_KILL_REQ, $k).
@@ -111,7 +121,10 @@ all(suite) ->
too_large,
alive_req_too_small_1,
alive_req_too_small_2,
- alive_req_too_large
+ alive_req_too_large,
+
+ returns_valid_empty_extra,
+ returns_valid_populated_extra_with_nulls
].
%%
@@ -182,29 +195,70 @@ register_node(Name) ->
register_node(Name,?DUMMY_PORT).
register_node(Name, Port) ->
- case connect() of
+ case send_req([?EPMD_ALIVE_REQ, put16(Port), Name]) of
{ok,Sock} ->
- M = [?EPMD_ALIVE_REQ, put16(Port), Name],
- case send(Sock, [size16(M), M]) of
- ok ->
- case recv(Sock,3) of
- {ok, [?EPMD_ALIVE_OK_RESP,_D1,_D0]} ->
- {ok,Sock};
- Other ->
- test_server:format("recv on sock ~w: ~p~n",
- [Sock,Other]),
- error
- end;
+ case recv(Sock,3) of
+ {ok, [?EPMD_ALIVE_OK_RESP,_D1,_D0]} ->
+ {ok,Sock};
Other ->
- test_server:format("send on sock ~w: ~w~n",[Sock,Other]),
+ test_server:format("recv on sock ~w: ~p~n",
+ [Sock,Other]),
error
end;
- Other ->
- test_server:format("Connect on port ~w: ~p~n",[Port,Other]),
+ error ->
+ error
+ end.
+
+register_node_v2(Port, NodeType, Prot, HVsn, LVsn, Name, Extra) ->
+ Req = [?EPMD_ALIVE2_REQ, put16(Port), NodeType, Prot,
+ put16(HVsn), put16(LVsn),
+ size16(Name), Name,
+ size16(Extra), Extra],
+ case send_req(Req) of
+ {ok,Sock} ->
+ case recv(Sock,4) of
+ {ok, [?EPMD_ALIVE2_RESP,_Res=0,_C0,_C1]} ->
+ {ok,Sock};
+ Other ->
+ test_server:format("recv on sock ~w: ~p~n",
+ [Sock,Other]),
+ error
+ end;
+ error ->
error
end.
+% Internal function to fetch information about a node
+
+port_please_v2(Name) ->
+ case send_req([?EPMD_PORT_PLEASE2_REQ, Name]) of
+ {ok,Sock} ->
+ case recv_until_sock_closes(Sock) of
+ {ok, Resp} ->
+ parse_port2_resp(Resp);
+ Other ->
+ test_server:format("recv on sock ~w: ~p~n",
+ [Sock,Other]),
+ error
+ end;
+ error ->
+ error
+ end.
+parse_port2_resp(Resp) ->
+ case list_to_binary(Resp) of
+ <<?EPMD_PORT2_RESP,Res,Port:16,NodeType,Prot,HVsn:16,LVsn:16,
+ NLen:16,NodeName:NLen/binary,
+ ELen:16,Extra:ELen/binary>> when Res =:= 0 ->
+ {ok, #node_info{port=Port,node_type=NodeType,prot=Prot,
+ hvsn=HVsn,lvsn=LVsn,
+ node_name=binary_to_list(NodeName),
+ extra=binary_to_list(Extra)}};
+ Other ->
+ test_server:format("invalid port2 resp: ~p~n",
+ [Resp]),
+ error
+ end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -631,6 +685,32 @@ alive_req_too_large(Config) when list(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+returns_valid_empty_extra(doc) ->
+ ["Check that an empty extra is prefixed by a two byte length"];
+returns_valid_empty_extra(suite) ->
+ [];
+returns_valid_empty_extra(Config) when list(Config) ->
+ ?line ok = epmdrun(),
+ ?line {ok,Sock} = register_node_v2(4711, 72, 0, 5, 5, "foo", []),
+ ?line {ok,#node_info{extra=[]}} = port_please_v2("foo"),
+ ?line ok = close(Sock),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+returns_valid_populated_extra_with_nulls(doc) ->
+ ["Check a populated extra with embedded null characters"];
+returns_valid_populated_extra_with_nulls(suite) ->
+ [];
+returns_valid_populated_extra_with_nulls(Config) when list(Config) ->
+ ?line ok = epmdrun(),
+ ?line {ok,Sock} = register_node_v2(4711, 72, 0, 5, 5, "foo", "ABC\000\000"),
+ ?line {ok,#node_info{extra="ABC\000\000"}} = port_please_v2("foo"),
+ ?line ok = close(Sock),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Terminate all tests with killing epmd.
cleanup() ->
@@ -813,6 +893,36 @@ send_direct(Sock, Bytes) ->
Any
end.
+send_req(Req) ->
+ case connect() of
+ {ok,Sock} ->
+ case send(Sock, [size16(Req), Req]) of
+ ok ->
+ {ok,Sock};
+ Other ->
+ test_server:format("Failed to send ~w on sock ~w: ~w~n",
+ [Req,Sock,Other]),
+ error
+ end;
+ Other ->
+ test_server:format("Connect failed when sending ~w: ~p~n",
+ [Req, Other]),
+ error
+ end.
+
+recv_until_sock_closes(Sock) ->
+ recv_until_sock_closes_2(Sock,[]).
+
+recv_until_sock_closes_2(Sock,AccData) ->
+ case recv(Sock,0) of
+ {ok,Data} ->
+ recv_until_sock_closes_2(Sock,AccData++Data);
+ closed ->
+ {ok,AccData};
+ Other ->
+ Other
+ end.
+
sleep(MilliSeconds) ->
timer:sleep(MilliSeconds).
diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c
index c958fed741..09aca19e6c 100644
--- a/erts/etc/common/erlc.c
+++ b/erts/etc/common/erlc.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1997-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/*
@@ -310,6 +310,8 @@ main(int argc, char** argv)
case 'W': /* Enable warnings. */
if (strcmp(argv[1]+2, "all") == 0) {
PUSH2("@warn", "999");
+ } else if (strcmp(argv[1]+2, "error") == 0) {
+ PUSH2("@option", "warnings_as_errors");
} else if (isdigit((int)argv[1][2])) {
PUSH2("@warn", argv[1]+2);
} else {
@@ -566,6 +568,7 @@ usage(void)
{"-pz path", "add path to the end of Erlang's code path"},
{"-smp", "compile using SMP emulator"},
{"-v", "verbose compiler output"},
+ {"-Werror", "make all warnings into errors"},
{"-W0", "disable warnings"},
{"-Wnumber", "set warning level to number"},
{"-Wall", "enable all warnings"},
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index 4325418e7c..f79f5cc978 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -123,6 +123,14 @@ static char *pluss_val_switches[] = {
"ss",
NULL
};
+/* +h arguments with values */
+static char *plush_val_switches[] = {
+ "ms",
+ "mbs",
+ "",
+ NULL
+};
+
/*
* Define sleep(seconds) in terms of Sleep() on Windows.
@@ -783,10 +791,10 @@ int main(int argc, char **argv)
case 'a':
case 'A':
case 'b':
- case 'h':
case 'i':
case 'P':
case 'S':
+ case 't':
case 'T':
case 'R':
case 'W':
@@ -850,6 +858,20 @@ int main(int argc, char **argv)
goto the_default;
break;
}
+ case 'h':
+ if (!is_one_of_strings(&argv[i][2], plush_val_switches)) {
+ goto the_default;
+ } else {
+ if (i+1 >= argc
+ || argv[i+1][0] == '-'
+ || argv[i+1][0] == '+')
+ usage(argv[i]);
+ argv[i][0] = '-';
+ add_Eargs(argv[i]);
+ add_Eargs(argv[i+1]);
+ i++;
+ }
+ break;
case 's':
if (!is_one_of_strings(&argv[i][2],
pluss_val_switches))
@@ -1048,7 +1070,7 @@ usage_aux(void)
#endif
"[-make] [-man [manopts] MANPAGE] [-x] [-emu_args] "
"[-args_file FILENAME] "
- "[+A THREADS] [+a SIZE] [+B[c|d|i]] [+c] [+h HEAP_SIZE] [+K BOOLEAN] "
+ "[+A THREADS] [+a SIZE] [+B[c|d|i]] [+c] [+h HEAP_SIZE_OPTION] [+K BOOLEAN] "
"[+l] [+M<SUBSWITCH> <ARGUMENT>] [+P MAX_PROCS] [+R COMPAT_REL] "
"[+r] [+s SCHEDULER_OPTION] [+S NO_SCHEDULERS:NO_SCHEDULERS_ONLINE] [+T LEVEL] [+V] [+v] [+W<i|w>] "
"[args ...]\n");
diff --git a/erts/lib_src/Makefile.in b/erts/lib_src/Makefile.in
index ce5c846677..49f5b1f048 100644
--- a/erts/lib_src/Makefile.in
+++ b/erts/lib_src/Makefile.in
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -483,6 +483,8 @@ ifneq ($(strip $(INTERNAL_RELEASE_LIBS)),)
$(INSTALL_DATA) $(INTERNAL_RELEASE_LIBS) $(RELSYSDIR)/lib/internal
endif
+docs:
+
release_docs_spec:
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index d7134967bf..e966f727c4 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index f490fe7c3d..620ee733bd 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 39118a0109..aa9bd13dd0 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam
index 4680d645cb..f060ac73b7 100644
--- a/erts/preloaded/ebin/otp_ring0.beam
+++ b/erts/preloaded/ebin/otp_ring0.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 2cacb6808c..34f9565fe3 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index aa9b255ebb..0ec3130d44 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index 0e7adad9e8..b7897dd798 100644
--- a/erts/preloaded/ebin/prim_zip.beam
+++ b/erts/preloaded/ebin/prim_zip.beam
Binary files differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 93b05172d8..c9be5d2aa0 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index 399c2bb55d..c0785083de 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -49,7 +49,7 @@
prim_read_file_info/2, prim_get_cwd/2]).
%% Used by escript and code
--export([set_primary_archive/2, release_archives/0]).
+-export([set_primary_archive/3, release_archives/0]).
%% Internal function. Exported to avoid dialyzer warnings
-export([concat/1]).
@@ -220,14 +220,15 @@ get_cwd(Drive) ->
check_file_result(get_cwd, Drive, request({get_cwd,[Drive]})).
-spec set_primary_archive(File :: string() | 'undefined',
- ArchiveBin :: binary() | 'undefined')
- -> {ok, [string()]} | {error,_}.
+ ArchiveBin :: binary() | 'undefined',
+ FileInfo :: #file_info{} | 'undefined')
+ -> {ok, [string()]} | {error,_}.
-set_primary_archive(undefined, undefined) ->
- request({set_primary_archive, undefined, undefined});
-set_primary_archive(File, ArchiveBin)
- when is_list(File), is_binary(ArchiveBin) ->
- request({set_primary_archive, File, ArchiveBin}).
+set_primary_archive(undefined, undefined, undefined) ->
+ request({set_primary_archive, undefined, undefined, undefined});
+set_primary_archive(File, ArchiveBin, FileInfo)
+ when is_list(File), is_binary(ArchiveBin), is_record(FileInfo, file_info) ->
+ request({set_primary_archive, File, ArchiveBin, FileInfo}).
-spec release_archives() -> 'ok' | {'error', _}.
@@ -315,8 +316,8 @@ loop(State, Parent, Paths) ->
{get_cwd,[_]=Args} ->
{Res,State1} = handle_get_cwd(State, Args),
{Res,State1,Paths};
- {set_primary_archive,File,Bin} ->
- {Res,State1} = handle_set_primary_archive(State, File, Bin),
+ {set_primary_archive,File,Bin,FileInfo} ->
+ {Res,State1} = handle_set_primary_archive(State, File, Bin,FileInfo),
{Res,State1,Paths};
release_archives ->
{Res,State1} = handle_release_archives(State),
@@ -356,8 +357,8 @@ handle_get_file(State = #state{loader = efile}, Paths, File) ->
handle_get_file(State = #state{loader = inet}, Paths, File) ->
?SAFE2(inet_get_file_from_port(State, File, Paths), State).
-handle_set_primary_archive(State= #state{loader = efile}, File, Bin) ->
- ?SAFE2(efile_set_primary_archive(State, File, Bin), State).
+handle_set_primary_archive(State= #state{loader = efile}, File, Bin, FileInfo) ->
+ ?SAFE2(efile_set_primary_archive(State, File, Bin, FileInfo), State).
handle_release_archives(State= #state{loader = efile}) ->
?SAFE2(efile_release_archives(State), State).
@@ -481,8 +482,8 @@ efile_get_file_from_port3(State, File, [P | Paths]) ->
efile_get_file_from_port3(State, _File, []) ->
{{error,enoent},State}.
-efile_set_primary_archive(#state{prim_state = PS} = State, File, Bin) ->
- {Res, PS2} = prim_set_primary_archive(PS, File, Bin),
+efile_set_primary_archive(#state{prim_state = PS} = State, File, Bin, FileInfo) ->
+ {Res, PS2} = prim_set_primary_archive(PS, File, Bin, FileInfo),
{Res,State#state{prim_state = PS2}}.
efile_release_archives(#state{prim_state = PS} = State) ->
@@ -572,13 +573,14 @@ find_loop(U, Retry, AL, ReqDelay, SReSleep, Ignore, Tries, LReSleep) ->
case find_loop(U, Retry, AL, ReqDelay, []) of
[] -> % no response from any server
erlang:display({erl_prim_loader,'no server found'}), % lifesign
- Tries1 = if Tries > 0 ->
- sleep(SReSleep),
- Tries - 1;
- true ->
- sleep(LReSleep),
- 0
- end,
+ Tries1 =
+ if Tries > 0 ->
+ sleep(SReSleep),
+ Tries - 1;
+ true ->
+ sleep(LReSleep),
+ 0
+ end,
find_loop(U, Retry, AL, ReqDelay, SReSleep, Ignore, Tries1, LReSleep);
Servers ->
keysort(1, Servers -- Ignore)
@@ -787,9 +789,9 @@ prim_release_archives(PS) ->
prim_do_release_archives(PS, [{ArchiveFile, DictVal} | KeyVals], Acc) ->
Res =
case DictVal of
- {primary, _PrimZip} ->
+ {primary, _PrimZip, _FI} ->
ok; % Keep primary archive
- {_Mtime, Cache} ->
+ {Cache, _FI} ->
debug(PS, {release, cache, ArchiveFile}),
erase(ArchiveFile),
clear_cache(ArchiveFile, Cache)
@@ -805,7 +807,7 @@ prim_do_release_archives(PS, [], []) ->
prim_do_release_archives(PS, [], Errors) ->
{{error, Errors}, PS#prim_state{primary_archive = undefined}}.
-prim_set_primary_archive(PS, undefined, undefined) ->
+prim_set_primary_archive(PS, undefined, undefined, undefined) ->
debug(PS, {set_primary_archive, clean}),
case PS#prim_state.primary_archive of
undefined ->
@@ -813,15 +815,15 @@ prim_set_primary_archive(PS, undefined, undefined) ->
debug(PS, {return, Res}),
{Res, PS};
ArchiveFile ->
- {primary, PrimZip} = erase(ArchiveFile),
+ {primary, PrimZip, _FI} = erase(ArchiveFile),
ok = prim_zip:close(PrimZip),
PS2 = PS#prim_state{primary_archive = undefined},
Res = {ok, []},
debug(PS2, {return, Res}),
{Res, PS2}
end;
-prim_set_primary_archive(PS, ArchiveFile, ArchiveBin)
- when is_list(ArchiveFile), is_binary(ArchiveBin) ->
+prim_set_primary_archive(PS, ArchiveFile, ArchiveBin, FileInfo)
+ when is_list(ArchiveFile), is_binary(ArchiveBin), is_record(FileInfo, file_info) ->
%% Try the archive file
debug(PS, {set_primary_archive, ArchiveFile, byte_size(ArchiveBin)}),
{Res3, PS3} =
@@ -833,17 +835,17 @@ prim_set_primary_archive(PS, ArchiveFile, ArchiveBin)
["", "nibe", RevApp] -> % Reverse ebin
%% Collect ebin directories in archive
Ebin = reverse(RevApp) ++ "/ebin",
- {true, [Ebin | A]};
+ {true, [Ebin | A]};
_ ->
{true, A}
end
end,
Ebins0 = [ArchiveFile],
- case open_archive({ArchiveFile, ArchiveBin}, Ebins0, Fun) of
- {ok, PrimZip, RevEbins} ->
+ case open_archive({ArchiveFile, ArchiveBin}, FileInfo, Ebins0, Fun) of
+ {ok, PrimZip, {RevEbins, FI, _}} ->
Ebins = reverse(RevEbins),
debug(PS, {set_primary_archive, Ebins}),
- put(ArchiveFile, {primary, PrimZip}),
+ put(ArchiveFile, {primary, PrimZip, FI}),
{{ok, Ebins}, PS#prim_state{primary_archive = ArchiveFile}};
Error ->
debug(PS, {set_primary_archive, Error}),
@@ -851,10 +853,10 @@ prim_set_primary_archive(PS, ArchiveFile, ArchiveBin)
end;
OldArchiveFile ->
debug(PS, {set_primary_archive, clean}),
- PrimZip = erase(OldArchiveFile),
+ {primary, PrimZip, _FI} = erase(OldArchiveFile),
ok = prim_zip:close(PrimZip),
PS2 = PS#prim_state{primary_archive = undefined},
- prim_set_primary_archive(PS2, ArchiveFile, ArchiveBin)
+ prim_set_primary_archive(PS2, ArchiveFile, ArchiveBin, FileInfo)
end,
debug(PS3, {return, Res3}),
{Res3, PS3}.
@@ -956,15 +958,15 @@ prim_read_file_info(PS, File) ->
FunnyFile = funny_split(FileInArchive, $/),
Fun =
fun({Funny, GetInfo, _GetBin}, Acc) ->
- if
- hd(Funny) =:= "",
- tl(Funny) =:= FunnyFile ->
+ case Funny of
+ [H | T] when H =:= "",
+ T =:= FunnyFile ->
%% Directory
{false, {ok, GetInfo()}};
- Funny =:= FunnyFile ->
+ F when F =:= FunnyFile ->
%% Plain file
{false, {ok, GetInfo()}};
- true ->
+ _ ->
%% No match
{true, Acc}
end
@@ -990,33 +992,36 @@ prim_get_cwd(PS, [Drive]) ->
apply_archive(PS, Fun, Acc, Archive) ->
case get(Archive) of
undefined ->
+ case open_archive(Archive, Acc, Fun) of
+ {ok, PrimZip, {Acc2, FI, _}} ->
+ debug(PS, {cache, ok}),
+ put(Archive, {{ok, PrimZip}, FI}),
+ {Acc2, PS};
+ Error ->
+ debug(PS, {cache, Error}),
+ %% put(Archive, {Error, FI}),
+ {Error, PS}
+ end;
+ {primary, PrimZip, FI} ->
+ case prim_file:read_file_info(Archive) of
+ {ok, FI2}
+ when FI#file_info.mtime =:= FI2#file_info.mtime ->
+ case foldl_archive(PrimZip, Acc, Fun) of
+ {ok, _PrimZip2, Acc2} ->
+ {Acc2, PS};
+ Error ->
+ debug(PS, {primary, Error}),
+ {Error, PS}
+ end;
+ Error ->
+ debug(PS, {cache, {clear, Error}}),
+ clear_cache(Archive, {ok, PrimZip}),
+ apply_archive(PS, Fun, Acc, Archive)
+ end;
+ {Cache, FI} ->
case prim_file:read_file_info(Archive) of
- {ok, #file_info{mtime = Mtime}} ->
- case open_archive(Archive, Acc, Fun) of
- {ok, PrimZip, Acc2} ->
- debug(PS, {cache, ok}),
- put(Archive, {Mtime, {ok, PrimZip}}),
- {Acc2, PS};
- Error ->
- debug(PS, {cache, Error}),
- put(Archive, {Mtime, Error}),
- {Error, PS}
- end;
- Error ->
- debug(PS, {cache, Error}),
- {Error, PS}
- end;
- {primary, PrimZip} ->
- case foldl_archive(PrimZip, Acc, Fun) of
- {ok, _PrimZip2, Acc2} ->
- {Acc2, PS};
- Error ->
- debug(PS, {primary, Error}),
- {Error, PS}
- end;
- {Mtime, Cache} ->
- case prim_file:read_file_info(Archive) of
- {ok, #file_info{mtime = Mtime2}} when Mtime2 =:= Mtime ->
+ {ok, FI2}
+ when FI#file_info.mtime =:= FI2#file_info.mtime ->
case Cache of
{ok, PrimZip} ->
case foldl_archive(PrimZip, Acc, Fun) of
@@ -1026,7 +1031,8 @@ apply_archive(PS, Fun, Acc, Archive) ->
debug(PS, {cache, {clear, Error}}),
clear_cache(Archive, Cache),
debug(PS, {cache, Error}),
- put(Archive, {Mtime, Error}),
+ erase(Archive),
+ %% put(Archive, {Error, FI}),
{Error, PS}
end;
Error ->
@@ -1041,20 +1047,57 @@ apply_archive(PS, Fun, Acc, Archive) ->
end.
open_archive(Archive, Acc, Fun) ->
+ case prim_file:read_file_info(Archive) of
+ {ok, FileInfo} ->
+ open_archive(Archive, FileInfo, Acc, Fun);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+open_archive(Archive, FileInfo, Acc, Fun) ->
+ FakeFI = FileInfo#file_info{type = directory},
Wrapper =
- fun({N, GI, GB}, A) ->
- %% Ensure full iteration at open
- Funny = funny_split(N, $/),
- {_Continue, A2} = Fun({Funny, GI, GB}, A),
- {true, {true, Funny}, A2}
- end,
- prim_zip:open(Wrapper, Acc, Archive).
+ fun({N, GI, GB}, {A, I, FunnyDirs}) -> % Full iteration at open
+ Funny = funny_split(N, $/),
+ FunnyDirs2 =
+ case Funny of
+ ["" | FunnyDir] ->
+ [FunnyDir | FunnyDirs];
+ _ ->
+ FunnyDirs
+ end,
+ {Includes, FunnyDirs3, A2} =
+ ensure_virtual_dirs(Funny, Fun, FakeFI, [{true, Funny}], FunnyDirs2, A),
+ {_Continue, A3} = Fun({Funny, GI, GB}, A2),
+ {true, Includes, {A3, I, FunnyDirs3}}
+ end,
+ prim_zip:open(Wrapper, {Acc, FakeFI, []}, Archive).
+
+ensure_virtual_dirs(Funny, Fun, FakeFI, Includes, FunnyDirs, Acc) ->
+ case Funny of
+ [_ | FunnyDir] ->
+ case lists:member(FunnyDir, FunnyDirs) of % BIF
+ false ->
+ GetInfo = fun() -> FakeFI end,
+ GetBin = fun() -> <<>> end,
+ VirtualDir = ["" | FunnyDir],
+ Includes2 = [{true, VirtualDir, GetInfo, GetBin} | Includes],
+ FunnyDirs2 = [FunnyDir | FunnyDirs],
+ {I, F, Acc2} = ensure_virtual_dirs(FunnyDir, Fun, FakeFI, Includes2, FunnyDirs2, Acc),
+ {_Continue, Acc3} = Fun({VirtualDir, GetInfo, GetBin}, Acc2),
+ {I, F, Acc3};
+ true ->
+ {reverse(Includes), FunnyDirs, Acc}
+ end;
+ [] ->
+ {reverse(Includes), FunnyDirs, Acc}
+ end.
foldl_archive(PrimZip, Acc, Fun) ->
Wrapper =
- fun({N, GI, GB}, A) ->
+ fun({Funny, GI, GB}, A) ->
%% Allow partial iteration at foldl
- {Continue, A2} = Fun({N, GI, GB}, A),
+ {Continue, A2} = Fun({Funny, GI, GB}, A),
{Continue, true, A2}
end,
prim_zip:foldl(Wrapper, Acc, PrimZip).
diff --git a/erts/preloaded/src/prim_zip.erl b/erts/preloaded/src/prim_zip.erl
index 17ef8c6c43..3f5a5b9721 100644
--- a/erts/preloaded/src/prim_zip.erl
+++ b/erts/preloaded/src/prim_zip.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -94,12 +94,7 @@ do_foldl(FilterFun, FilterAcc, [PF | Tail], Acc0, PrimZip, PrimZipOrig) ->
#primzip_file{name = F, get_info = GetInfo, get_bin = GetBin} = PF,
case FilterFun({F, GetInfo, GetBin}, FilterAcc) of
{Continue, Include, FilterAcc2} ->
- Acc1 =
- case Include of
- false -> Acc0;
- true -> [PF | Acc0];
- {true, Nick} -> [PF#primzip_file{name = Nick} | Acc0]
- end,
+ Acc1 = include_acc(Include, PF, Acc0),
case Continue of
true ->
do_foldl(FilterFun, FilterAcc2, Tail, Acc1, PrimZip, PrimZipOrig);
@@ -112,6 +107,28 @@ do_foldl(FilterFun, FilterAcc, [PF | Tail], Acc0, PrimZip, PrimZipOrig) ->
do_foldl(_FilterFun, FilterAcc, [], Acc, PrimZip, _PrimZipOrig) ->
{ok, FilterAcc, PrimZip#primzip{files = reverse(Acc)}}.
+include_acc(Include, PF, Acc) ->
+ case Include of
+ false ->
+ Acc;
+ true ->
+ [PF | Acc];
+ {true, Nick} ->
+ [PF#primzip_file{name = Nick} | Acc];
+ {true, Nick, GetInfo, GetBin} ->
+ PF2 = #primzip_file{name = Nick, get_info = GetInfo, get_bin = GetBin},
+ [PF2 | Acc];
+ List when is_list(List) ->
+ %% Add new entries
+ Fun = fun(I, A) -> include_acc(I, PF, A) end,
+ lists_foldl(Fun, Acc, List)
+ end.
+
+lists_foldl(F, Accu, [Hd|Tail]) ->
+ lists_foldl(F, F(Hd, Accu), Tail);
+lists_foldl(F, Accu, []) when is_function(F, 2) ->
+ Accu.
+
%% close a zip archive
close(#primzip{in = In0, input = Input, zlib = Z}) ->
Input(close, In0),
@@ -199,15 +216,25 @@ get_cd_loop(N, BCD, Acc0, PrimZip, FileName, Offset, CFH, EndOffset, FilterFun,
end,
%% erlang:display({FileName, N, Offset, Size, NextPF}),
GetInfo = fun() -> cd_file_header_to_file_info(FileName, CFH, <<>>) end,
- GetBin = fun() -> get_z_file(FileName, Offset, Size, PrimZip) end,
+ GetBin = fun() -> get_z_file(FileName, Offset, Size, PrimZip) end,
PF = #primzip_file{name = FileName, get_info = GetInfo, get_bin = GetBin},
case FilterFun({FileName, GetInfo, GetBin}, FilterAcc) of
{Continue, Include, FilterAcc2} ->
Acc1 =
case Include of
- false -> Acc0;
- true -> [PF | Acc0];
- {true, Nick} -> [PF#primzip_file{name = Nick} | Acc0]
+ false ->
+ Acc0;
+ true ->
+ [PF | Acc0];
+ {true, Nick} ->
+ [PF#primzip_file{name = Nick} | Acc0];
+ {true, Nick, GI, GB} ->
+ PF2 = #primzip_file{name = Nick, get_info = GI, get_bin = GB},
+ [PF2 | Acc0];
+ List when is_list(List) ->
+ %% Add new entries
+ Fun = fun(I, A) -> include_acc(I, PF, A) end,
+ lists_foldl(Fun, Acc0, List)
end,
case Continue of
true when N > 1 ->
diff --git a/erts/test/erl_print_SUITE.erl b/erts/test/erl_print_SUITE.erl
index b1458d84d0..3bb7d4d016 100644
--- a/erts/test/erl_print_SUITE.erl
+++ b/erts/test/erl_print_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -36,7 +36,7 @@
-export([erlang_display/1, integer/1, float/1, string/1, character/1, snprintf/1, quote/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
all(doc) -> [];
all(suite) -> test_cases().
diff --git a/erts/test/erlc_SUITE.erl b/erts/test/erlc_SUITE.erl
index 1d944811aa..437f020f99 100644
--- a/erts/test/erlc_SUITE.erl
+++ b/erts/test/erlc_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(erlc_SUITE).
@@ -23,7 +23,7 @@
-export([all/1, compile_erl/1, compile_yecc/1, compile_script/1,
compile_mib/1, good_citizen/1, deep_cwd/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
all(suite) ->
[compile_erl, compile_yecc, compile_script, compile_mib,
@@ -56,6 +56,13 @@ compile_erl(Config) when is_list(Config) ->
?line run(Config, Cmd, FileName, "-W0", ["_OK_"]),
+ %% Try treating warnings as errors.
+
+ ?line run(Config, Cmd, FileName, "-Werror",
+ ["compile: warnings being treated as errors\$",
+ "Warning: function foo/0 is unused\$",
+ "_ERROR_"]),
+
%% Check a bad file.
?line BadFile = filename:join(SrcDir, "erl_test_bad.erl"),
diff --git a/erts/test/erlexec_SUITE.erl b/erts/test/erlexec_SUITE.erl
index fcf1e67e9e..164ce9faaf 100644
--- a/erts/test/erlexec_SUITE.erl
+++ b/erts/test/erlexec_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -35,7 +35,7 @@
-export([args_file/1, evil_args_file/1, env/1, args_file_env/1, otp_7461/1, otp_7461_remote/1, otp_8209/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(Case, Config) ->
diff --git a/erts/test/ethread_SUITE.erl b/erts/test/ethread_SUITE.erl
index a8f4f5e90c..bbc79e9381 100644
--- a/erts/test/ethread_SUITE.erl
+++ b/erts/test/ethread_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -53,7 +53,7 @@
atomic/1,
gate/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
tests() ->
[create_join_thread,
diff --git a/erts/test/ignore_cores.erl b/erts/test/ignore_cores.erl
index 7ec2cac706..8b1ac0fe6c 100644
--- a/erts/test/ignore_cores.erl
+++ b/erts/test/ignore_cores.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -27,7 +27,7 @@
-module(ignore_cores).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-export([init/1, fini/1, setup/3, setup/4, restore/1, dir/1]).
diff --git a/erts/test/nt_SUITE.erl b/erts/test/nt_SUITE.erl
index 7ff5c908e6..530fb55270 100644
--- a/erts/test/nt_SUITE.erl
+++ b/erts/test/nt_SUITE.erl
@@ -1,24 +1,25 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%% Purpose: Test NT specific utilities
-module(nt_SUITE).
--include("test_server.hrl").
+
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
-export([all/1,init_per_testcase/2,fin_per_testcase/2,nt/1,handle_eventlog/2,
diff --git a/erts/test/otp_SUITE.erl b/erts/test/otp_SUITE.erl
index c6769743dd..425ad31782 100644
--- a/erts/test/otp_SUITE.erl
+++ b/erts/test/otp_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -24,7 +24,8 @@
obsolete_but_not_deprecated/1,call_to_deprecated/1,
call_to_size_1/1,strong_components/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
-import(lists, [filter/2,foldl/3,foreach/2]).
all(suite) ->
diff --git a/erts/test/run_erl_SUITE.erl b/erts/test/run_erl_SUITE.erl
index afff4120d4..efeafbad8c 100644
--- a/erts/test/run_erl_SUITE.erl
+++ b/erts/test/run_erl_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -23,7 +23,7 @@
basic/1,heavy/1,heavier/1,defunct/1]).
-export([ping_me_back/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(_Case, Config) ->
Dog = ?t:timetrap(?t:minutes(2)),
diff --git a/erts/test/z_SUITE.erl b/erts/test/z_SUITE.erl
index 0e37af1ca2..8faddeb0d3 100644
--- a/erts/test/z_SUITE.erl
+++ b/erts/test/z_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -39,7 +39,7 @@
-export([search_for_core_files/1, core_files/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(Case, Config) ->
diff --git a/lib/appmon/doc/src/Makefile b/lib/appmon/doc/src/Makefile
index ece0977810..743f123c06 100644
--- a/lib/appmon/doc/src/Makefile
+++ b/lib/appmon/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
@@ -46,6 +46,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES = \
app_win.gif \
listbox_win.gif \
diff --git a/lib/common_test/doc/src/Makefile b/lib/common_test/doc/src/Makefile
index a6ece5af28..a2c014418d 100644
--- a/lib/common_test/doc/src/Makefile
+++ b/lib/common_test/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2003-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2003-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -112,18 +112,16 @@ DVIPS_FLAGS +=
CT_SRC_DIR = $(ERL_TOP)/../internal_tools/common_test/src
-EDOC_ARGS=[{preprocess,true},{includes,["$(XMERL_DIR)/include","../../../test_server/include","../../include","../../../../erts/lib/kernel/include","../../../../lib/kernel/include","../../../../erts/lib/snmp/include","../../../../lib/snmp/include"]}]
-
-
$(HTMLDIR)/%.gif: %.gif
$(INSTALL_DATA) $< $@
docs: pdf html man
$(CT_XML_FILES):
- erl -boot start_clean -noshell \
- -eval 'docb_gen:module("../../src/$(@:%.xml=%.erl)",$(EDOC_ARGS))' \
- -s erlang halt
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -preprocess true -i $(XMERL_DIR)/include \
+ -i ../../../test_server/include -i ../../include \
+ -i ../../../../erts/lib/kernel/include -i ../../../../lib/kernel/include \
+ -i ../../../../erts/lib/snmp/include -i ../../../../lib/snmp/include ../../src/$(@:%.xml=%.erl)
$(TOP_PDF_FILE): $(XML_FILES)
diff --git a/lib/common_test/doc/src/example_chapter.xml b/lib/common_test/doc/src/example_chapter.xml
index 028cbf7c8d..f269dba2cd 100644
--- a/lib/common_test/doc/src/example_chapter.xml
+++ b/lib/common_test/doc/src/example_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Examples and Templates</title>
@@ -38,7 +38,7 @@
<code>
-module(db_data_type_SUITE).
--include("ct.hrl").
+-include_lib("common_test/include/ct.hrl").
%% Test server callbacks
-export([suite/0, all/0,
@@ -186,7 +186,7 @@ insert_and_lookup(Key, Value, Config) ->
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("ct.hrl").
+-include_lib("common_test/include/ct.hrl").
%%--------------------------------------------------------------------
%% COMMON TEST CALLBACK FUNCTIONS
@@ -394,7 +394,7 @@ my_test_case(_Config) ->
-compile(export_all).
--include("ct.hrl").
+-include_lib("common_test/include/ct.hrl").
%%--------------------------------------------------------------------
%% Function: suite() -> Info
diff --git a/lib/common_test/include/ct.hrl b/lib/common_test/include/ct.hrl
index ad3b3374c4..aa1cc832cf 100644
--- a/lib/common_test/include/ct.hrl
+++ b/lib/common_test/include/ct.hrl
@@ -1,22 +1,22 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-compile({parse_transform,ct_line}).
diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml
index c39c9b25eb..daa686bc56 100644
--- a/lib/compiler/doc/src/compile.xml
+++ b/lib/compiler/doc/src/compile.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>compile</title>
@@ -212,6 +212,12 @@
success.</p>
</item>
+ <tag><c>warnings_as_errors</c></tag>
+ <item>
+ <p>Causes warnings to be treated as errors. This option is supported
+ since R13B04.</p>
+ </item>
+
<tag><c>return</c></tag>
<item>
<p>This is a short form for both <c>return_errors</c> and
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 08ba9c3ee4..1fd61831e0 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(beam_validator).
@@ -604,9 +604,9 @@ valfun_4({gc_bif,Op,{f,Fail},Live,Src,Dst}, #vst{current=St0}=Vst0) ->
St = kill_heap_allocation(St0),
Vst1 = Vst0#vst{current=St},
verify_live(Live, Vst1),
- Vst2 = prune_x_regs(Live, Vst1),
- validate_src(Src, Vst2),
- Vst = branch_state(Fail, Vst2),
+ Vst2 = branch_state(Fail, Vst1),
+ Vst = prune_x_regs(Live, Vst2),
+ validate_src(Src, Vst),
Type = bif_type(Op, Src, Vst),
set_type_reg(Type, Dst, Vst);
valfun_4(return, #vst{current=#st{numy=none}}=Vst) ->
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index e725083a9f..d73c9cd762 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Purpose: Run the Erlang compiler.
@@ -187,9 +187,9 @@ format_error(no_crypto_key) ->
format_error({native, E}) ->
io_lib:fwrite("native-code compilation failed with reason: ~P.",
[E, 25]);
-format_error({native_crash, E}) ->
- io_lib:fwrite("native-code compilation crashed with reason: ~P.",
- [E, 25]);
+format_error({native_crash,E,Stk}) ->
+ io_lib:fwrite("native-code compilation crashed with reason: ~P.\n~P\n",
+ [E,25,Stk,25]);
format_error({open,E}) ->
io_lib:format("open error '~s'", [file:format_error(E)]);
format_error({epp,E}) ->
@@ -302,7 +302,7 @@ os_process_size() ->
list_to_integer(lib:nonl(Size));
_ ->
0
- end.
+ end.
run_tc({Name,Fun}, St) ->
Before0 = statistics(runtime),
@@ -318,17 +318,30 @@ run_tc({Name,Fun}, St) ->
Val.
comp_ret_ok(#compile{code=Code,warnings=Warn0,module=Mod,options=Opts}=St) ->
- Warn = messages_per_file(Warn0),
- report_warnings(St#compile{warnings = Warn}),
- Ret1 = case member(binary, Opts) andalso not member(no_code_generation, Opts) of
- true -> [Code];
- false -> []
- end,
- Ret2 = case member(return_warnings, Opts) of
- true -> Ret1 ++ [Warn];
- false -> Ret1
- end,
- list_to_tuple([ok,Mod|Ret2]).
+ case member(warnings_as_errors, Opts) andalso length(Warn0) > 0 of
+ true ->
+ case member(report_warnings, Opts) of
+ true ->
+ io:format("~p: warnings being treated as errors\n",
+ [?MODULE]);
+ false ->
+ ok
+ end,
+ comp_ret_err(St);
+ false ->
+ Warn = messages_per_file(Warn0),
+ report_warnings(St#compile{warnings = Warn}),
+ Ret1 = case member(binary, Opts) andalso
+ not member(no_code_generation, Opts) of
+ true -> [Code];
+ false -> []
+ end,
+ Ret2 = case member(return_warnings, Opts) of
+ true -> Ret1 ++ [Warn];
+ false -> Ret1
+ end,
+ list_to_tuple([ok,Mod|Ret2])
+ end.
comp_ret_err(#compile{warnings=Warn0,errors=Err0,options=Opts}=St) ->
Warn = messages_per_file(Warn0),
@@ -344,18 +357,18 @@ comp_ret_err(#compile{warnings=Warn0,errors=Err0,options=Opts}=St) ->
messages_per_file(Ms) ->
T = lists:sort([{File,M} || {File,Messages} <- Ms, M <- Messages]),
PrioMs = [erl_scan, epp, erl_parse],
- {Prio0, Rest} =
+ {Prio0, Rest} =
lists:mapfoldl(fun(M, A) ->
lists:partition(fun({_,{_,Mod,_}}) -> Mod =:= M;
(_) -> false
end, A)
end, T, PrioMs),
- Prio = lists:sort(fun({_,{L1,_,_}}, {_,{L2,_,_}}) -> L1 =< L2 end,
+ Prio = lists:sort(fun({_,{L1,_,_}}, {_,{L2,_,_}}) -> L1 =< L2 end,
lists:append(Prio0)),
flatmap(fun mpf/1, [Prio, Rest]).
mpf(Ms) ->
- [{File,[M || {F,M} <- Ms, F =:= File]} ||
+ [{File,[M || {F,M} <- Ms, F =:= File]} ||
File <- lists:usort([F || {F,_} <- Ms])].
%% passes(form|file, [Option]) -> [{Name,PassFun}]
@@ -495,14 +508,14 @@ select_passes([List|Ps], Opts) when is_list(List) ->
select_cond(Flag, ShouldBe, Pass, Ps, Opts) ->
ShouldNotBe = not ShouldBe,
- case member(Flag, Opts) of
+ case member(Flag, Opts) of
ShouldBe -> select_passes([Pass|Ps], Opts);
ShouldNotBe -> select_passes(Ps, Opts)
end.
%% select_list_passes([Pass], Opts) -> {done,[Pass]} | {not_done,[Pass]}
%% Evaluate all conditions having to do with listings in the list of
-%% passes.
+%% passes.
select_list_passes(Ps, Opts) ->
select_list_passes_1(Ps, Opts, []).
@@ -704,7 +717,7 @@ read_beam_file(St) ->
case file:read_file(St#compile.ifile) of
{ok,Beam} ->
Infile = St#compile.ifile,
- case is_too_old(Infile) of
+ case no_native_compilation(Infile, St) of
true ->
{ok,St#compile{module=none,code=none}};
false ->
@@ -717,12 +730,15 @@ read_beam_file(St) ->
{error,St#compile{errors=St#compile.errors ++ Es}}
end.
-is_too_old(BeamFile) ->
+no_native_compilation(BeamFile, #compile{options=Opts0}) ->
case beam_lib:chunks(BeamFile, ["CInf"]) of
{ok,{_,[{"CInf",Term0}]}} ->
Term = binary_to_term(Term0),
- Opts = proplists:get_value(options, Term, []),
- lists:member(no_new_funs, Opts);
+
+ %% Compiler options in the beam file will override
+ %% options passed to the compiler.
+ Opts = proplists:get_value(options, Term, []) ++ Opts0,
+ member(no_new_funs, Opts) orelse not is_native_enabled(Opts);
_ -> false
end.
@@ -782,7 +798,7 @@ clean_parse_transforms_1([F|Fs], Acc) ->
clean_parse_transforms_1(Fs, [F|Acc]);
clean_parse_transforms_1([], Acc) -> reverse(Acc).
-transforms(Os) -> [ M || {parse_transform,M} <- Os ].
+transforms(Os) -> [ M || {parse_transform,M} <- Os ].
transform_module(#compile{options=Opt,code=Code0}=St0) ->
%% Extract compile options from code into options field.
@@ -815,7 +831,7 @@ foldl_transform(St, [T|Ts]) ->
end;
foldl_transform(St, []) -> {ok,St}.
-get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts].
+get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts].
core_transforms(St) ->
%% The options field holds the complete list of options at this
@@ -1033,7 +1049,14 @@ beam_asm(#compile{ifile=File,code=Code0,abstract_code=Abst,options=Opts0}=St) ->
test_native(#compile{options=Opts}) ->
%% This test is done late, in case some other option has turned off native.
- member(native, Opts).
+ %% 'native' given on the command line can be overridden by
+ %% 'no_native' in the module itself.
+ is_native_enabled(Opts).
+
+is_native_enabled([native|_]) -> true;
+is_native_enabled([no_native|_]) -> false;
+is_native_enabled([H|T]) -> is_native_enabled(T);
+is_native_enabled([]) -> false.
native_compile(#compile{code=none}=St) -> {ok,St};
native_compile(St) ->
@@ -1057,25 +1080,27 @@ native_compile_1(St) ->
St#compile.core_code,
St#compile.code,
Opts) of
- {ok, {_Type,Bin} = T} when is_binary(Bin) ->
- {ok, embed_native_code(St, T)};
- {error, R} ->
+ {ok,{_Type,Bin}=T} when is_binary(Bin) ->
+ {ok,embed_native_code(St, T)};
+ {error,R} ->
case IgnoreErrors of
true ->
- Ws = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}],
- {ok, St#compile{warnings=St#compile.warnings ++ Ws}};
+ Ws = [{St#compile.ifile,[{?MODULE,{native,R}}]}],
+ {ok,St#compile{warnings=St#compile.warnings ++ Ws}};
false ->
- Es = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}],
- {error, St#compile{errors=St#compile.errors ++ Es}}
+ Es = [{St#compile.ifile,[{?MODULE,{native,R}}]}],
+ {error,St#compile{errors=St#compile.errors ++ Es}}
end
catch
- error:R ->
+ Class:R ->
+ Stk = erlang:get_stacktrace(),
case IgnoreErrors of
true ->
- Ws = [{St#compile.ifile,[{none,?MODULE,{native_crash,R}}]}],
- {ok, St#compile{warnings=St#compile.warnings ++ Ws}};
+ Ws = [{St#compile.ifile,
+ [{?MODULE,{native_crash,R,Stk}}]}],
+ {ok,St#compile{warnings=St#compile.warnings ++ Ws}};
false ->
- exit(R)
+ erlang:raise(Class, R, Stk)
end
end.
@@ -1264,7 +1289,7 @@ listing(Ext, St) ->
listing(LFun, Ext, St) ->
Lfile = outfile(St#compile.base, Ext, St#compile.options),
case file:open(Lfile, [write,delayed_write]) of
- {ok,Lf} ->
+ {ok,Lf} ->
Code = restore_expanded_types(Ext, St#compile.code),
LFun(Lf, Code),
ok = file:close(Lf),
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index ef8feb8a27..74b5d7c7eb 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(beam_validator_SUITE).
@@ -28,7 +28,7 @@
freg_range/1,freg_uninit/1,freg_state/1,
bin_match/1,bin_aligned/1,bad_dsetel/1,
state_after_fault_in_catch/1,no_exception_in_catch/1,
- undef_label/1,illegal_instruction/1]).
+ undef_label/1,illegal_instruction/1,failing_gc_guard_bif/1]).
-include("test_server.hrl").
@@ -52,13 +52,13 @@ all(suite) ->
freg_range,freg_uninit,freg_state,
bin_match,bin_aligned,
bad_dsetel,state_after_fault_in_catch,no_exception_in_catch,
- undef_label,illegal_instruction].
+ undef_label,illegal_instruction,failing_gc_guard_bif].
beam_files(Config) when is_list(Config) ->
?line {ok,Cwd} = file:get_cwd(),
?line Parent = filename:dirname(Cwd),
?line Wc = filename:join([Parent,"*","*.beam"]),
- %% Must have at least two files here, or there will could be
+ %% Must have at least two files here, or there will be
%% a grammatical error in the output of the io:format/2 call below. ;-)
?line [_,_|_] = Fs = filelib:wildcard(Wc),
?line io:format("~p files\n", [length(Fs)]),
@@ -356,6 +356,36 @@ illegal_instruction(Config) when is_list(Config) ->
{{'_',y,0},{[],0,illegal_instruction}}] = Errors,
ok.
+%% The beam_validator used to assume that a GC guard BIF could
+%% do a garbage collection even if it failed. That assumption
+%% is not correct, and will cause the beam_validator to reject
+%% valid programs such as this test case.
+%%
+%% (Thanks to Kiran Khaladkar.)
+%%
+failing_gc_guard_bif(Config) when is_list(Config) ->
+ ?line ok = process_request(lists:seq(1, 36)),
+ ?line error = process_request([]),
+ ?line error = process_request(not_a_list),
+ ok.
+
+process_request(ConfId) ->
+ case process_request_foo(ConfId) of
+ false ->
+ if
+ length(ConfId) == 36 ->
+ Response = ok;
+ true ->
+ Response = error
+ end
+ end,
+ process_request_bar(self(), [Response]).
+
+process_request_foo(_) ->
+ false.
+
+process_request_bar(Pid, [Response]) when is_pid(Pid) ->
+ Response.
%%%-------------------------------------------------------------------------
diff --git a/lib/compiler/test/error_SUITE.erl b/lib/compiler/test/error_SUITE.erl
index 477730c3ac..cdd2434b25 100644
--- a/lib/compiler/test/error_SUITE.erl
+++ b/lib/compiler/test/error_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(error_SUITE).
@@ -21,11 +21,11 @@
-include("test_server.hrl").
-export([all/1,
- head_mismatch_line/1,r11b_binaries/1]).
+ head_mismatch_line/1,r11b_binaries/1,warnings_as_errors/1]).
all(suite) ->
test_lib:recompile(?MODULE),
- [head_mismatch_line,r11b_binaries].
+ [head_mismatch_line,r11b_binaries,warnings_as_errors].
%% Tests that a head mismatch is reported on the correct line (OTP-2125).
head_mismatch_line(Config) when is_list(Config) ->
@@ -73,6 +73,20 @@ r11b_binaries(Config) when is_list(Config) ->
?line [] = run(Config, Ts),
ok.
+warnings_as_errors(Config) when is_list(Config) ->
+ Ts = [{warnings_as_errors,
+ <<"
+ t() ->
+ A = unused,
+ ok.
+ ">>,
+ [warnings_as_errors],
+ {error,
+ [],
+ [{3,erl_lint,{unused_var,'A'}}]} }],
+ ?line [] = run(Config, Ts),
+ ok.
+
run(Config, Tests) ->
F = fun({N,P,Ws,E}, BadL) ->
@@ -104,6 +118,8 @@ run_test(Conf, Test0, Warnings) ->
%% Test result of compilation.
?line Res = case compile:file(File, Opts) of
{error,[{_File,Es}],Ws} ->
+ {error,Es,Ws};
+ {error,Es,[{_File,Ws}]} ->
{error,Es,Ws}
end,
file:delete(File),
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index 72abcdde10..a5e6de7b5f 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 4.6.4
+COMPILER_VSN = 4.6.5
diff --git a/lib/cosFileTransfer/doc/src/notes.xml b/lib/cosFileTransfer/doc/src/notes.xml
index 5bb2ea68c4..48d0c04236 100644
--- a/lib/cosFileTransfer/doc/src/notes.xml
+++ b/lib/cosFileTransfer/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>cosFileTransfer Release Notes</title>
@@ -34,6 +34,18 @@
<title>cosFileTransfer 1.1.10</title>
<section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Removed obsolete SSL dependency.</p>
+ <p>
+ Own Id: OTP-8374 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
<title>Fixed Bugs and Malfunctions</title>
<list type="bulleted">
<item>
diff --git a/lib/cosFileTransfer/vsn.mk b/lib/cosFileTransfer/vsn.mk
index 88786178fb..2700ecb3e3 100644
--- a/lib/cosFileTransfer/vsn.mk
+++ b/lib/cosFileTransfer/vsn.mk
@@ -1,7 +1,8 @@
COSFILETRANSFER_VSN = 1.1.10
TICKETS = \
- OTP-8355
+ OTP-8355 \
+ OTP-8374
TICKETS_1.1.9 = OTP-8201
diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile
index d2cec9b11b..03aaba939b 100644
--- a/lib/crypto/doc/src/Makefile
+++ b/lib/crypto/doc/src/Makefile
@@ -42,6 +42,9 @@ XML_CHAPTER_FILES = notes.xml licenses.xml
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES =
# ----------------------------------------------------
diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk
index f2a9b4fe24..68eecfe759 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 1.6.3
+CRYPTO_VSN = 1.6.4
diff --git a/lib/debugger/src/dbg_ui_mon.erl b/lib/debugger/src/dbg_ui_mon.erl
index 63cc9b66d1..8888075124 100644
--- a/lib/debugger/src/dbg_ui_mon.erl
+++ b/lib/debugger/src/dbg_ui_mon.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(dbg_ui_mon).
@@ -429,8 +429,7 @@ gui_cmd('Back Trace Size...', State) ->
%% Help Menu
gui_cmd('Debugger', State) ->
- HelpFile = filename:join([code:lib_dir(debugger),
- "doc", "html", "part_frame.html"]),
+ HelpFile = filename:join([code:lib_dir(debugger), "doc", "html", "index.html"]),
Window = dbg_ui_mon_win:get_window(State#state.win),
tool_utils:open_help(Window, HelpFile),
State;
diff --git a/lib/debugger/src/dbg_wx_filedialog_win.erl b/lib/debugger/src/dbg_wx_filedialog_win.erl
index d883438639..9687efa981 100644
--- a/lib/debugger/src/dbg_wx_filedialog_win.erl
+++ b/lib/debugger/src/dbg_wx_filedialog_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(dbg_wx_filedialog_win).
@@ -375,7 +375,8 @@ show_completion(Wanted, State = #state{text=TC, win=Win, list=LC, completion=Com
Start = length(Wanted),
wxTextCtrl:setValue(TC, Path++"/"),
wxTextCtrl:setInsertionPoint(TC, Start),
- wxTextCtrl:setSelection(TC, Start, -1),
+ Last = wxTextCtrl:getLastPosition(TC),
+ wxTextCtrl:setSelection(TC, Start, Last),
destroy_completion(Comp),
wxWindow:setFocus(TC),
State#state{ptext=Path, completion=undefined};
@@ -399,7 +400,7 @@ show_completion(Wanted, State = #state{text=TC, win=Win, list=LC, completion=Com
LB = wxListBox:new(Temp, ?COMPLETION_WIN,
[{style, ?wxLB_SINGLE}, {choices, Files}, {size, Size}]),
- wxListBox:connect(LB, command_listbox_doubleclicked),
+ %% wxListBox:connect(LB, command_listbox_doubleclicked),
wxListBox:connect(LB, command_listbox_selected),
wxWindow:show(Temp),
wxWindow:setFocus(TC),
diff --git a/lib/debugger/src/dbg_wx_mon.erl b/lib/debugger/src/dbg_wx_mon.erl
index d81069ec90..3f55c38d35 100644
--- a/lib/debugger/src/dbg_wx_mon.erl
+++ b/lib/debugger/src/dbg_wx_mon.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -144,7 +144,7 @@ init2(CallingPid, Mode, SFile, GS) ->
win = Win,
focus = undefined,
- coords = {0,0},
+ coords = {20,20},
intdir = element(2, file:get_cwd()),
pinfos = [],
@@ -442,8 +442,7 @@ gui_cmd('Back Trace Size...', State) ->
%% Help Menu
gui_cmd('Debugger', State) ->
- HelpFile = filename:join([code:lib_dir(debugger),
- "doc", "html", "part_frame.html"]),
+ HelpFile = filename:join([code:lib_dir(debugger), "doc", "html", "index.html"]),
Window = dbg_wx_mon_win:get_window(State#state.win),
dbg_wx_win:open_help(Window, HelpFile),
State;
diff --git a/lib/debugger/src/dbg_wx_mon_win.erl b/lib/debugger/src/dbg_wx_mon_win.erl
index dfb327fa6a..8ad4f4213f 100644
--- a/lib/debugger/src/dbg_wx_mon_win.erl
+++ b/lib/debugger/src/dbg_wx_mon_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -104,7 +104,7 @@ create_win_batch(Title, Menus) ->
Hlb = 200,
Listbox = wxListBox:new(Panel, ?wxID_ANY, [{size,{?Wf,Hlb}},
{style,?wxLB_SINGLE}]),
- wxSizer:add(LeftSz,Listbox,[{border, 3}]),
+ wxSizer:add(LeftSz,Listbox,[{proportion,1}, {border,3}]),
wxListBox:connect(Listbox, command_listbox_doubleclicked),
wxListBox:connect(Listbox, right_down),
diff --git a/lib/debugger/src/dbg_wx_trace_win.erl b/lib/debugger/src/dbg_wx_trace_win.erl
index 6e7a291493..3799acdc1b 100755
--- a/lib/debugger/src/dbg_wx_trace_win.erl
+++ b/lib/debugger/src/dbg_wx_trace_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -571,7 +571,7 @@ update_bindings(#winInfo{bind=#sub{out=BA}}, Bs) ->
wx:foldl(fun({Var,Val},Row) ->
wxListCtrl:insertItem(BA, Row, ""),
wxListCtrl:setItem(BA, Row, 0, dbg_wx_win:to_string(Var)),
- wxListCtrl:setItem(BA, Row, 1, dbg_wx_win:to_string("~200p",[Val])),
+ wxListCtrl:setItem(BA, Row, 1, dbg_wx_win:to_string("~500P",[Val, 80])),
Row+1
end, 0, Bs),
put(bindings,Bs),
diff --git a/lib/debugger/src/dbg_wx_win.erl b/lib/debugger/src/dbg_wx_win.erl
index f029990aa4..faf3cc178f 100644
--- a/lib/debugger/src/dbg_wx_win.erl
+++ b/lib/debugger/src/dbg_wx_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -75,7 +75,8 @@ create_menus(MB, [{Title,Items}|Ms], Win, Id0) ->
Id = create_menu_item(Menu, Items, Win, Id0, true),
wxMenuBar:append(MB,Menu,menu_name(Title,ignore)),
create_menus(MB,Ms,Win,Id);
-create_menus(_MB,[], _Win,Id) -> Id.
+create_menus(_MB,[], _Win,Id) ->
+ Id.
create_menu_item(Menu, [separator|Is], Win, Id,Connect) ->
wxMenu:appendSeparator(Menu),
@@ -102,10 +103,14 @@ create_menu_item(Menu, [{Name, _N, cascade, Items}|Is], Win, Id0,Connect) ->
[{id,Id0},{lastId, Id-1},{callback,Filter}]),
create_menu_item(Menu, Is, Win, Id, Connect);
create_menu_item(Menu, [{Name,Pos}|Is], Win, Id, Connect) ->
- Item = wxMenu:append(Menu, Id, menu_name(Name,Pos)),
+ MenuId = case lists:member(Name, ['Debugger']) of
+ true -> ?wxID_HELP;
+ _ -> Id
+ end,
+ Item = wxMenu:append(Menu, MenuId, menu_name(Name,Pos)),
put(Name,Item),
if Connect ->
- wxMenu:connect(Win, command_menu_selected, [{id,Id},{userData, Name}]);
+ wxMenu:connect(Win, command_menu_selected, [{id,MenuId},{userData, Name}]);
true -> ignore
end,
create_menu_item(Menu,Is,Win,Id+1, Connect);
@@ -308,6 +313,8 @@ to_string(Format,Args) ->
menu_name(Atom, N) when is_atom(Atom) ->
menu_name(atom_to_list(Atom),N);
+menu_name("Help", _) -> %% Mac needs this to be exactly this
+ "&Help";
menu_name(Str, Pos) when is_integer(Pos) ->
{S1,S2} = lists:split(Pos,Str),
S1 ++ [$&|S2];
diff --git a/lib/docbuilder/doc/src/inline_tags.xml b/lib/docbuilder/doc/src/inline_tags.xml
index e1d392076a..10afbf143f 100644
--- a/lib/docbuilder/doc/src/inline_tags.xml
+++ b/lib/docbuilder/doc/src/inline_tags.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Inline Tags</title>
@@ -157,7 +157,7 @@
<p>The default behaviour can be modified by using the callback
module option to <c>docb_transform:file/1,2</c> and defining a
callback function
- <seealso marker="docb_transform#Module:seealso/1">Module:seealso/1</seealso>.
+ <seealso marker="docb_transform#Module:seealso-1">Module:seealso/1</seealso>.
This possibility is for example used in OTP to resolve cross
references between applications.</p>
</section>
diff --git a/lib/edoc/Makefile b/lib/edoc/Makefile
index 2b011b55cc..e512e390e3 100644
--- a/lib/edoc/Makefile
+++ b/lib/edoc/Makefile
@@ -86,13 +86,13 @@ SYNTAX_TOOLS_DIR=$(ERL_TOP)/lib/syntax_tools
XMERL_DIR=$(ERL_TOP)/lib/xmerl
INCDIR=$(XMERL_DIR)/include
-docs:
+# The overriding docs target have been removed so the default make rules work properly.
+
+edocs:
erl -noshell -pa $(BINDIR) -pa $(SYNTAX_TOOLS_DIR)/ebin \
-pa $(XMERL_DIR)/ebin -run edoc_run application \
"'$(APPNAME)'" '"."' '$(DOC_OPTS)'
-edocs: docs
-
info:
@echo $(HTML_FILES)
diff --git a/lib/edoc/doc/src/Makefile b/lib/edoc/doc/src/Makefile
index 8d22e1c1da..748691d173 100644
--- a/lib/edoc/doc/src/Makefile
+++ b/lib/edoc/doc/src/Makefile
@@ -103,11 +103,10 @@ html: gifs $(HTML_REF_MAN_FILE)
man: $(MAN3_FILES)
$(XML_REF3_FILES):
- docb_gen -def vsn $(EDOC_VSN) -includes $(INC_DIR) \
- $(SRC_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EDOC_VSN) -i $(ERL_TOP)/lib/edoc/include $(SRC_DIR)/$(@:%.xml=%.erl)
$(XML_CHAPTER_FILES):
- docb_gen -chapter -def vsn $(EDOC_VSN) ../overview.edoc
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EDOC_VSN) -chapter ../overview.edoc
gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
diff --git a/lib/edoc/src/Makefile b/lib/edoc/src/Makefile
index fd0fbac37d..ca95c4cdad 100644
--- a/lib/edoc/src/Makefile
+++ b/lib/edoc/src/Makefile
@@ -55,6 +55,8 @@ all: $(OBJECTS)
$(OBJECTS): $(HRL_FILES) $(XMERL)/include/xmerl.hrl
+docs:
+
clean:
rm -f $(OBJECTS) edoc_parser.erl
rm -f core *~
diff --git a/lib/erl_docgen/priv/bin/Makefile b/lib/erl_docgen/priv/bin/Makefile
index bd59675003..95ad36216a 100644
--- a/lib/erl_docgen/priv/bin/Makefile
+++ b/lib/erl_docgen/priv/bin/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2009-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -38,7 +38,8 @@ RELSYSDIR = $(RELEASE_PATH)/lib/erl_docgen-$(VSN)
ESCRIPT_FILES= \
- codeline_preprocessing.escript
+ codeline_preprocessing.escript \
+ xml_from_edoc.escript
# ----------------------------------------------------
# FLAGS
diff --git a/lib/erl_docgen/priv/bin/codeline_preprocessing.escript b/lib/erl_docgen/priv/bin/codeline_preprocessing.escript
index 33a678d3a4..592b3985e4 100755
--- a/lib/erl_docgen/priv/bin/codeline_preprocessing.escript
+++ b/lib/erl_docgen/priv/bin/codeline_preprocessing.escript
@@ -1,20 +1,20 @@
#!/usr/bin/env escript
%% -*- erlang -*-
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%----------------------------------------------------------------------
%% File : codeline_preprocessing.escript
@@ -54,13 +54,16 @@ main([InFile, OutFile]) ->
main(_) ->
usage().
+%%======================================================================
+%% Internal functions
+%%======================================================================
%%----------------------------------------------------------------------
-%% Function: main/1
+%% Function: usage/0
%% Description:
%%----------------------------------------------------------------------
usage() ->
- io:format("usage: codeline_preprocessing <infile> <outfile>\n"),
+ io:format("usage: codeline_preprocessing.escript <infile> <outfile>\n"),
halt(1).
diff --git a/lib/erl_docgen/priv/bin/xml_from_edoc.escript b/lib/erl_docgen/priv/bin/xml_from_edoc.escript
new file mode 100755
index 0000000000..ee79e82c3a
--- /dev/null
+++ b/lib/erl_docgen/priv/bin/xml_from_edoc.escript
@@ -0,0 +1,149 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%----------------------------------------------------------------------
+%% File : xml_from_edoc.escript
+%%
+%% Created : 12 Dec 2009 by Lars Thorsen
+%%----------------------------------------------------------------------
+
+
+%%======================================================================
+%% Records
+%%======================================================================
+-record(args, {suffix=".xml",
+ layout=docb_edoc_xml_cb,
+ def=[],
+ includes=[],
+ preprocess=false,
+ sort_functions=true}).
+
+
+%%======================================================================
+%% External functions
+%%======================================================================
+%%----------------------------------------------------------------------
+%% Function: main/1
+%% Description:
+%%----------------------------------------------------------------------
+main(RawOpts) ->
+ case catch parse(RawOpts, erlref, #args{}) of
+ {ok, File, Type, Args} ->
+ case Type of
+ erlref ->
+ module(File, Args);
+ chapter ->
+ users_guide(File, Args)
+ end;
+ {error, Msg} ->
+ io:format("~p\n", [Msg]),
+ usage()
+ end;
+main(_) ->
+ usage().
+
+%%======================================================================
+%% Internal functions
+%%======================================================================
+
+%%----------------------------------------------------------------------
+%% Function: usage/0
+%% Description:
+%%----------------------------------------------------------------------
+usage() ->
+ io:format("usage: xml_from_edoc.escript [<options>] <file> \n"),
+ halt(1).
+
+
+%%----------------------------------------------------------------------
+%% Function: module/2
+%% Description:
+%%----------------------------------------------------------------------
+module(File, Args) ->
+ case filelib:is_regular(File) of
+ true ->
+ Opts = [{def, Args#args.def},
+ {includes, Args#args.includes},
+ {preprocess, Args#args.preprocess},
+ {sort_functions, Args#args.sort_functions},
+
+ {app_default, "OTPROOT"},
+ {file_suffix, Args#args.suffix},
+ {dir, "."},
+ {layout, Args#args.layout}],
+ edoc:file(File, Opts);
+ false ->
+ io:format("~s: not a regular file\n", [File]),
+ usage()
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Function: users_guide/2
+%% Description:
+%%----------------------------------------------------------------------
+users_guide(File, Args) ->
+ case filelib:is_regular(File) of
+ true ->
+ Opts = [{def, Args#args.def},
+ {app_default, "OTPROOT"},
+ {file_suffix, Args#args.suffix},
+ {layout, Args#args.layout}],
+
+ Env = edoc_lib:get_doc_env(Opts),
+
+ {ok, Tags} =
+ edoc_extract:file(File, overview, Env, Opts),
+ Data =
+ edoc_data:overview("Overview", Tags, Env, Opts),
+ F = fun(M) -> M:overview(Data, Opts) end,
+ Text = edoc_lib:run_layout(F, Opts),
+
+ OutFile = "chapter" ++ Args#args.suffix,
+ edoc_lib:write_file(Text, ".", OutFile);
+ false ->
+ io:format("~s: not a regular file\n", [File]),
+ usage()
+ end.
+
+
+
+parse(["-xml" |RawOpts], Type, Args) ->
+ parse(RawOpts, Type, Args); % default, no update of record necessary
+parse(["-sgml" |RawOpts], Type, Args) ->
+ parse(RawOpts, Type, Args#args{suffix=".sgml", layout=docb_edoc_sgml_cb});
+parse(["-chapter" |RawOpts], _Type, Args) ->
+ parse(RawOpts, chapter, Args);
+parse(["-def", Key, Val |RawOpts], Type, Args) ->
+ Args2 = Args#args{def=Args#args.def++[{list_to_atom(Key), Val}]},
+ parse(RawOpts, Type, Args2);
+
+parse(["-i", Dir |RawOpts], Type, Args) ->
+ Args2 = Args#args{includes=Args#args.includes++[Dir]},
+ parse(RawOpts, Type, Args2);
+parse(["-preprocess", Bool |RawOpts], Type, Args) when Bool == "true";
+ Bool == "false" ->
+ parse(RawOpts, Type, Args#args{preprocess=list_to_atom(Bool)});
+parse(["-sort_functions", Bool |RawOpts], Type, Args) when Bool == "true";
+ Bool == "false" ->
+ parse(RawOpts, Type, Args#args{sort_functions=list_to_atom(Bool)});
+parse([File], Type, Args) ->
+ {ok, File, Type, Args};
+parse([Opt | _RawOpts], _Type, _Args) ->
+ {error, io_lib:format("Bad option: ~p", [Opt])}.
+
diff --git a/lib/erl_docgen/priv/xsl/db_eix.xsl b/lib/erl_docgen/priv/xsl/db_eix.xsl
index 929272256a..970b85ccb9 100644
--- a/lib/erl_docgen/priv/xsl/db_eix.xsl
+++ b/lib/erl_docgen/priv/xsl/db_eix.xsl
@@ -137,7 +137,20 @@
<xsl:value-of select="substring-before(nametext, '(')"/>
</xsl:when>
<xsl:when test="ancestor::erlref">
- <xsl:value-of select="substring-before(., '(')"/>
+ <xsl:variable name="fname1">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:variable>
+ <xsl:variable name="fname2">
+ <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($fname2) > 0">
+ <xsl:value-of select="$fname2"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fname1"/>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:variable>
@@ -178,26 +191,63 @@
</xsl:template>
<xsl:template name="remove-paren">
- <xsl:param name="string"/>
- <xsl:variable name="bstring">
- <xsl:value-of select="substring-before($string, '(')"/>
+ <xsl:param name="string"/>
+
+ <xsl:variable name="str1">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$string"/>
+ <xsl:with-param name="start">(</xsl:with-param>
+ <xsl:with-param name="end">)</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str2">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str1"/>
+ <xsl:with-param name="start">{</xsl:with-param>
+ <xsl:with-param name="end">}</xsl:with-param>
+ </xsl:call-template>
</xsl:variable>
+
+ <xsl:variable name="str3">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str2"/>
+ <xsl:with-param name="start">[</xsl:with-param>
+ <xsl:with-param name="end">]</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select="$str3"/>
+
+ </xsl:template>
+
+
+ <xsl:template name="remove-paren-1">
+ <xsl:param name="string"/>
+ <xsl:param name="start"/>
+ <xsl:param name="end"/>
+
+ <xsl:variable name="tmp1">
+ <xsl:value-of select="substring-before($string, $start)"/>
+ </xsl:variable>
+
<xsl:choose>
- <xsl:when test="string-length($bstring) > 0">
- <xsl:variable name="astring">
- <xsl:value-of select="substring-after($string, ')')"/>
+ <xsl:when test="string-length($tmp1) > 0 or starts-with($string, $start)">
+ <xsl:variable name="tmp2">
+ <xsl:value-of select="substring-after($string, $end)"/>
</xsl:variable>
<xsl:variable name="retstring">
<xsl:call-template name="remove-paren">
- <xsl:with-param name="string" select="$astring"/>
+ <xsl:with-param name="string" select="$tmp2"/>
</xsl:call-template>
</xsl:variable>
- <xsl:value-of select="concat($bstring, $retstring)"/>
+ <xsl:value-of select="concat(concat($tmp1, 'x'), $retstring)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
+
</xsl:template>
<!-- default content handling -->
diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl
index 984655fc26..5614b02bb7 100644
--- a/lib/erl_docgen/priv/xsl/db_html.xsl
+++ b/lib/erl_docgen/priv/xsl/db_html.xsl
@@ -2,20 +2,20 @@
<!--
#
# %CopyrightBegin%
- #
- # Copyright Ericsson AB 2009. All Rights Reserved.
- #
+ #
+ # Copyright Ericsson AB 2009-2010. All Rights Reserved.
+ #
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
- #
+ #
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
- #
+ #
# %CopyrightEnd%
-->
@@ -40,6 +40,46 @@
<div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="{$topdocdir}/js/flipmenu/flipmenu.js"/>
<script id="js2" type="text/javascript" src="{$topdocdir}/js/erlresolvelinks.js"></script>
+ <script language="JavaScript" type="text/javascript">
+ <xsl:text disable-output-escaping="yes"><![CDATA[
+ <!--
+ function getWinHeight() {
+ var myHeight = 0;
+ if( typeof( window.innerHeight ) == 'number' ) {
+ //Non-IE
+ myHeight = window.innerHeight;
+ } else if( document.documentElement && ( document.documentElement.clientWidth ||
+ document.documentElement.clientHeight ) ) {
+ //IE 6+ in 'standards compliant mode'
+ myHeight = document.documentElement.clientHeight;
+ } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
+ //IE 4 compatible
+ myHeight = document.body.clientHeight;
+ }
+ return myHeight;
+ }
+
+ function setscrollpos() {
+ var objf=document.getElementById('loadscrollpos');
+ document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
+ }
+
+ function addEvent(obj, evType, fn){
+ if (obj.addEventListener){
+ obj.addEventListener(evType, fn, true);
+ return true;
+ } else if (obj.attachEvent){
+ var r = obj.attachEvent("on"+evType, fn);
+ return r;
+ } else {
+ return false;
+ }
+ }
+
+ addEvent(window, 'load', setscrollpos);
+
+ //-->]]></xsl:text>
+ </script>
<!-- Generate menu -->
<xsl:call-template name="menu">
<xsl:with-param name="chapnum" select="$chapnum"/>
@@ -543,7 +583,13 @@
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:variable>
- <li title="{header/title}" expanded="{$expanded}">
+ <xsl:variable name="loadscrollpos">
+ <xsl:choose>
+ <xsl:when test="$chapnum = $curchapnum">loadscrollpos</xsl:when>
+ <xsl:otherwise>no</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <li id="{$loadscrollpos}" title="{header/title}" expanded="{$expanded}">
<xsl:value-of select="header/title"/>
<ul>
<li>
@@ -656,7 +702,7 @@
<!-- Menu.ref -->
<xsl:template name="menu.ref">
- <xsl:param name="$curModule"/>
+ <xsl:param name="curModule"/>
<div id="leftnav">
<div class="innertube">
@@ -731,12 +777,19 @@
</xsl:choose>
</xsl:variable>
+ <xsl:variable name="loadscrollpos">
+ <xsl:choose>
+ <xsl:when test="$curModule = $cval">loadscrollpos</xsl:when>
+ <xsl:otherwise>no</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
<xsl:variable name="link_cval"><xsl:value-of select="translate($cval, '&#173;', '')"/></xsl:variable>
<xsl:choose>
<xsl:when test="$genFuncMenu = 'true'">
- <li title="{$cval} " expanded="{$expanded}">
+ <li id="{$loadscrollpos}" title="{$cval} " expanded="{$expanded}">
<xsl:value-of select="$cval"/>
<ul>
<li>
@@ -788,58 +841,73 @@
<xsl:when test="string-length($fname) > 0">
<li title="{$fname}">
<a href="{$basename}.html#{$fname}">
- <xsl:value-of select="$fname"/>()
- </a>
- </li>
- </xsl:when>
- <xsl:otherwise>
- <li title="{name/nametext}">
- <a href="{$basename}.html#{name/nametext}">
- <xsl:value-of select="nametext"/>()
- </a>
- </li>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
-
- <xsl:when test="ancestor::erlref">
-
- <xsl:variable name="tmpstring">
- <xsl:value-of select="substring-before(substring-after(., '('), '->')"/>
- </xsl:variable>
-
- <xsl:variable name="ustring">
- <xsl:choose>
- <xsl:when test="string-length($tmpstring) > 0">
- <xsl:call-template name="remove-paren">
- <xsl:with-param name="string" select="$tmpstring"/>
- </xsl:call-template>
+ <xsl:value-of select="$fname"/>()
+ </a>
+ </li>
</xsl:when>
<xsl:otherwise>
- <xsl:call-template name="remove-paren">
- <xsl:with-param name="string" select="substring-after(., '(')"/>
- </xsl:call-template>
+ <li title="{name/nametext}">
+ <a href="{$basename}.html#{name/nametext}">
+ <xsl:value-of select="nametext"/>()
+ </a>
+ </li>
</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="arity">
- <xsl:call-template name="calc-arity">
- <xsl:with-param name="string" select="substring-before($ustring, ')')"/>
- <xsl:with-param name="no-of-pars" select="0"/>
- </xsl:call-template>
- </xsl:variable>
- <xsl:variable name="fname">
- <xsl:value-of select="substring-before(., '(')"/>
- </xsl:variable>
- <li title="{$fname}-{$arity}">
- <a href="{$basename}.html#{$fname}-{$arity}">
- <xsl:value-of select="$fname"/>/<xsl:value-of select="$arity"/>
- </a>
- </li>
- </xsl:when>
- </xsl:choose>
-
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:when test="ancestor::erlref">
+
+ <xsl:variable name="tmpstring">
+ <xsl:value-of select="substring-before(substring-after(., '('), '->')"/>
+ </xsl:variable>
+
+ <xsl:variable name="ustring">
+ <xsl:choose>
+ <xsl:when test="string-length($tmpstring) > 0">
+ <xsl:call-template name="remove-paren">
+ <xsl:with-param name="string" select="$tmpstring"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="remove-paren">
+ <xsl:with-param name="string" select="substring-after(., '(')"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="arity">
+ <xsl:call-template name="calc-arity">
+ <xsl:with-param name="string" select="substring-before($ustring, ')')"/>
+ <xsl:with-param name="no-of-pars" select="0"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="fname">
+ <xsl:variable name="fname1">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:variable>
+ <xsl:variable name="fname2">
+ <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($fname2) > 0">
+ <xsl:value-of select="$fname2"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fname1"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <li title="{$fname}-{$arity}">
+ <a href="{$basename}.html#{$fname}-{$arity}">
+ <xsl:value-of select="$fname"/>/<xsl:value-of select="$arity"/>
+ </a>
+ </li>
+ </xsl:when>
+ </xsl:choose>
+
</xsl:for-each>
</xsl:template>
@@ -1065,6 +1133,7 @@
<!-- Funcs -->
<xsl:template match="funcs">
+ <xsl:param name="partnum"/>
<h3>
<xsl:text>EXPORTS</xsl:text>
@@ -1121,11 +1190,26 @@
<a name="{substring-before(nametext, '(')}"><span class="bold_code"><xsl:value-of select="ret"/><xsl:text> </xsl:text><xsl:value-of select="nametext"/></span></a><br/>
</xsl:when>
<xsl:when test="ancestor::erlref">
- <a name="{substring-before(., '(')}-{$arity}"><span class="bold_code"><xsl:value-of select="."/></span></a><br/>
+ <xsl:variable name="fname">
+ <xsl:variable name="fname1">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:variable>
+ <xsl:variable name="fname2">
+ <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($fname2) > 0">
+ <xsl:value-of select="$fname2"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fname1"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <a name="{$fname}-{$arity}"><span class="bold_code"><xsl:value-of select="."/></span></a><br/>
</xsl:when>
</xsl:choose>
-
</xsl:template>
@@ -1167,6 +1251,7 @@
<!-- Desc -->
<xsl:template match="desc">
+ <xsl:param name="partnum"/>
<div class="REFBODY">
<p>
<xsl:apply-templates>
@@ -1458,29 +1543,65 @@
</xsl:choose>
</xsl:template>
+
<xsl:template name="remove-paren">
<xsl:param name="string"/>
+
+ <xsl:variable name="str1">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$string"/>
+ <xsl:with-param name="start">(</xsl:with-param>
+ <xsl:with-param name="end">)</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str2">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str1"/>
+ <xsl:with-param name="start">{</xsl:with-param>
+ <xsl:with-param name="end">}</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str3">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str2"/>
+ <xsl:with-param name="start">[</xsl:with-param>
+ <xsl:with-param name="end">]</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select="$str3"/>
+
+ </xsl:template>
+
+
+ <xsl:template name="remove-paren-1">
+ <xsl:param name="string"/>
+ <xsl:param name="start"/>
+ <xsl:param name="end"/>
- <xsl:variable name="bstring">
- <xsl:value-of select="substring-before($string, '(')"/>
+ <xsl:variable name="tmp1">
+ <xsl:value-of select="substring-before($string, $start)"/>
</xsl:variable>
<xsl:choose>
- <xsl:when test="string-length($bstring) > 0">
- <xsl:variable name="astring">
- <xsl:value-of select="substring-after($string, ')')"/>
+ <xsl:when test="string-length($tmp1) > 0 or starts-with($string, $start)">
+ <xsl:variable name="tmp2">
+ <xsl:value-of select="substring-after($string, $end)"/>
</xsl:variable>
<xsl:variable name="retstring">
<xsl:call-template name="remove-paren">
- <xsl:with-param name="string" select="$astring"/>
+ <xsl:with-param name="string" select="$tmp2"/>
</xsl:call-template>
</xsl:variable>
- <xsl:value-of select="concat($bstring, $retstring)"/>
+ <xsl:value-of select="concat(concat($tmp1, 'x'), $retstring)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
+
</xsl:template>
</xsl:stylesheet>
diff --git a/lib/erl_docgen/priv/xsl/db_man.xsl b/lib/erl_docgen/priv/xsl/db_man.xsl
index c759a77496..a9a2781a8a 100644
--- a/lib/erl_docgen/priv/xsl/db_man.xsl
+++ b/lib/erl_docgen/priv/xsl/db_man.xsl
@@ -2,20 +2,20 @@
<!--
#
# %CopyrightBegin%
- #
- # Copyright Ericsson AB 2009. All Rights Reserved.
- #
+ #
+ # Copyright Ericsson AB 2009-2010. All Rights Reserved.
+ #
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
- #
+ #
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
- #
+ #
# %CopyrightEnd%
-->
@@ -37,14 +37,12 @@
<!-- *ref/Section -->
<xsl:template match="erlref/section|comref/section|cref/section|fileref/section|appref/section">
- <xsl:text>&#10;.RE&#10;</xsl:text>
<xsl:text>&#10;.SH "</xsl:text><xsl:value-of select="translate(title, 'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/><xsl:text>"&#10;</xsl:text>
<xsl:apply-templates/>
</xsl:template>
<!-- *ref/Subsection -->
- <xsl:template match="erlref/section/section|comref/section/section|cref/section/section|fileref/section/section|appref/section/section">
- <xsl:text>&#10;.RE&#10;</xsl:text>
+ <xsl:template match="section/section">
<xsl:text>&#10;.SS "</xsl:text><xsl:value-of select="title"/><xsl:text>"&#10;</xsl:text>
<xsl:apply-templates/>
</xsl:template>
@@ -53,84 +51,76 @@
<!-- Lists -->
<xsl:template match="list">
- <xsl:text>&#10;.RS 2&#10;</xsl:text>
+ <xsl:text>&#10;.RS 2</xsl:text>
<xsl:apply-templates/>
- <xsl:text>&#10;.RE&#10;</xsl:text>
+ <xsl:text>&#10;.RE</xsl:text>
</xsl:template>
<xsl:template match="list/item">
<xsl:text>&#10;.TP 2&#10;</xsl:text>
<xsl:text>*&#10;</xsl:text>
- <xsl:variable name="content">
- <xsl:apply-templates/>
- </xsl:variable>
- <xsl:value-of select="normalize-space($content)"/>
- <xsl:text>&#10;.br&#10;</xsl:text>
- <xsl:text>&#10;.br&#10;</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&#10;.LP&#10;</xsl:text>
</xsl:template>
<xsl:template match="taglist">
- <xsl:text>&#10;.RS 2&#10;</xsl:text>
- <xsl:apply-templates/>
- <xsl:text>&#10;.RE&#10;</xsl:text>
+ <xsl:text>&#10;.RS 2</xsl:text>
+ <xsl:apply-templates select="tag|item"/>
+ <xsl:text>&#10;.RE</xsl:text>
</xsl:template>
<xsl:template match="taglist/tag">
- <xsl:text>&#10;.TP 4&#10;</xsl:text>
+ <xsl:text>&#10;.TP 2&#10;</xsl:text>
<xsl:text>.B&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:apply-templates/><xsl:text>:&#10;</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="taglist/item">
+ <xsl:apply-templates/>
</xsl:template>
<xsl:template match="item/p">
<xsl:variable name="content">
<xsl:apply-templates/>
</xsl:variable>
- <xsl:value-of select="normalize-space($content)"/>
- <xsl:text>&#10;.br&#10;</xsl:text>
- <xsl:text>&#10;.br&#10;</xsl:text>
- </xsl:template>
-
-
- <xsl:template match="taglist/item">
- <xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:choose>
+ <xsl:when test="position() = 1">
+ <xsl:value-of select="$content"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>&#10;.RS 2</xsl:text>
+ <xsl:text>&#10;.LP&#10;&#10;.LP&#10;</xsl:text>
+ <xsl:value-of select="$content"/>
+ <xsl:text>&#10;.RE</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:template>
<!-- Note -->
<xsl:template match="note">
- <xsl:text>&#10;.TP 4&#10;.B&#10;Note:&#10;</xsl:text>
+ <xsl:text>&#10;.SS Note:</xsl:text>
<xsl:apply-templates/>
+ <xsl:text>&#10;</xsl:text>
</xsl:template>
<!-- Warning -->
<xsl:template match="warning">
- <xsl:text>&#10;.TP 4&#10;.B&#10;Warning:&#10;</xsl:text>
+ <xsl:text>&#10;.SS Warning:</xsl:text>
<xsl:apply-templates/>
+ <xsl:text>&#10;</xsl:text>
</xsl:template>
- <xsl:template match="warning/p|note/p">
- <xsl:variable name="content">
- <xsl:apply-templates/>
- </xsl:variable>
- <xsl:value-of select="normalize-space($content)"/>
- <xsl:text>&#10;.LP&#10;</xsl:text>
- </xsl:template>
-
-
<!-- Paragraph -->
<xsl:template match="p">
<xsl:text>&#10;.LP&#10;</xsl:text>
- <xsl:variable name="content">
- <xsl:apply-templates/>
- </xsl:variable>
- <xsl:value-of select="normalize-space($content)"/>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Inline elements -->
<xsl:template match="b">
- <xsl:text> \fB</xsl:text>
+ <xsl:text>\fB</xsl:text>
<xsl:apply-templates/>
- <xsl:text>\fR\&amp;</xsl:text>
+ <xsl:text>\fR\&amp; </xsl:text>
</xsl:template>
<xsl:template match="br">
@@ -138,19 +128,20 @@
</xsl:template>
<xsl:template match="c">
- <xsl:text> \fI</xsl:text><xsl:value-of select="text()"/><xsl:text>\fR\&amp;</xsl:text>
+ <xsl:text>\fI</xsl:text><xsl:apply-templates/><xsl:text>\fR\&amp;</xsl:text>
</xsl:template>
<xsl:template match="em">
- <xsl:text> \fI</xsl:text><xsl:value-of select="text()"/><xsl:text>\fR\&amp;</xsl:text>
+ <xsl:text>\fI</xsl:text> <xsl:apply-templates/><xsl:text>\fR\&amp;</xsl:text>
</xsl:template>
<xsl:template match="seealso">
- <xsl:text> \fB</xsl:text><xsl:apply-templates/><xsl:text>\fR\&amp;</xsl:text>
+ <xsl:text>\fB</xsl:text><xsl:apply-templates/><xsl:text>\fR\&amp;</xsl:text>
</xsl:template>
<!-- Code -->
<xsl:template match="code">
+ <xsl:text>&#10;.LP&#10;</xsl:text>
<xsl:text>&#10;.nf&#10;</xsl:text>
<xsl:apply-templates/>
<xsl:text>&#10;.fi&#10;</xsl:text>
@@ -158,6 +149,7 @@
<!-- Pre -->
<xsl:template match="pre">
+ <xsl:text>&#10;.LP&#10;</xsl:text>
<xsl:text>&#10;.nf&#10;</xsl:text>
<xsl:apply-templates/>
<xsl:text>&#10;.fi&#10;</xsl:text>
@@ -168,16 +160,7 @@
<xsl:template match="table">
</xsl:template>
- <!--xsl:template match="row">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="cell">
- <xsl:apply-templates/>
- </xsl:template -->
-
-
- <!-- Image -->
+ <!-- Image -->
<xsl:template match="image">
</xsl:template>
@@ -191,42 +174,72 @@
<!-- Erlref -->
<xsl:template match="/erlref">
- <xsl:text>.TH </xsl:text><xsl:value-of select="module"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "Ericsson AB" "Erlang Module Definition"&#10;</xsl:text>
- <xsl:text>.SH MODULE&#10;</xsl:text>
- <xsl:value-of select="module"/><xsl:text> \- </xsl:text><xsl:value-of select="modulesummary"/><xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:variable name="companyname">
+ <xsl:choose>
+ <xsl:when test="$company = ''"><xsl:value-of select="header/holder"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$company"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text>.TH </xsl:text><xsl:value-of select="module"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Erlang Module Definition"&#10;</xsl:text>
+ <xsl:text>.SH NAME&#10;</xsl:text>
+ <xsl:value-of select="module"/><xsl:text> \- </xsl:text><xsl:value-of select="modulesummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Comref -->
<xsl:template match="/comref">
- <xsl:text>.TH </xsl:text><xsl:value-of select="com"/><xsl:text> 1 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "Ericsson AB" "User Commands"&#10;</xsl:text>
- <xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="com"/><xsl:text> \- </xsl:text><xsl:value-of select="comsummary"/><xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:variable name="companyname">
+ <xsl:choose>
+ <xsl:when test="$company = ''"><xsl:value-of select="header/holder"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$company"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text>.TH </xsl:text><xsl:value-of select="com"/><xsl:text> 1 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "User Commands"&#10;</xsl:text>
+ <xsl:text>.SH NAME&#10;</xsl:text>
+ <xsl:value-of select="com"/><xsl:text> \- </xsl:text><xsl:value-of select="comsummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Cref -->
<xsl:template match="/cref">
- <xsl:text>.TH </xsl:text><xsl:value-of select="lib"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "Ericsson AB" "C Library Functions"&#10;</xsl:text>
- <xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="lib"/><xsl:text> \- </xsl:text><xsl:value-of select="libsummary"/><xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:variable name="companyname">
+ <xsl:choose>
+ <xsl:when test="$company = ''"><xsl:value-of select="header/holder"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$company"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text>.TH </xsl:text><xsl:value-of select="lib"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "C Library Functions"&#10;</xsl:text>
+ <xsl:text>.SH NAME&#10;</xsl:text>
+ <xsl:value-of select="lib"/><xsl:text> \- </xsl:text><xsl:value-of select="libsummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Fileref -->
<xsl:template match="/fileref">
- <xsl:text>.TH </xsl:text><xsl:value-of select="file"/><xsl:text> 4 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "Ericsson AB" "Files"&#10;</xsl:text>
- <xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="file"/><xsl:text> \- </xsl:text><xsl:value-of select="filesummary"/><xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:variable name="companyname">
+ <xsl:choose>
+ <xsl:when test="$company = ''"><xsl:value-of select="header/holder"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$company"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text>.TH </xsl:text><xsl:value-of select="file"/><xsl:text> 5 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Files"&#10;</xsl:text>
+ <xsl:text>.SH NAME&#10;</xsl:text>
+ <xsl:value-of select="file"/><xsl:text> \- </xsl:text><xsl:value-of select="filesummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Appref -->
<xsl:template match="/appref">
- <xsl:text>.TH </xsl:text><xsl:value-of select="app"/><xsl:text> 6 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "Ericsson AB" "Erlang Application Definition"&#10;</xsl:text>
- <xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="file"/><xsl:text> \- </xsl:text><xsl:value-of select="filesummary"/><xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:variable name="companyname">
+ <xsl:choose>
+ <xsl:when test="$company = ''"><xsl:value-of select="header/holder"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$company"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text>.TH </xsl:text><xsl:value-of select="app"/><xsl:text> 7 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Erlang Application Definition"&#10;</xsl:text>
+ <xsl:text>.SH NAME&#10;</xsl:text>
+ <xsl:value-of select="app"/><xsl:text> \- </xsl:text><xsl:value-of select="appsummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Module|Com|Lib|File|App-->
@@ -297,12 +310,71 @@
<!-- This tag is skipped for now. -->
</xsl:template>
- <!-- xsl:template match="p/text()">
- <xsl:value-of select="normalize-space()"/>
- </xsl:template-->
+
+ <!-- Authors -->
+ <xsl:template match="authors">
+ <xsl:text>&#10;.SH AUTHORS</xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <!-- Aname -->
+ <xsl:template match="authors/aname">
+ <xsl:text>&#10;.LP&#10;</xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
- <xsl:template match="d/text()">
- <xsl:value-of select="normalize-space()"/>
+ <!-- Email -->
+ <xsl:template match="authors/email">
+ <xsl:text>&#10;.I&#10;&lt;</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&gt;</xsl:text>
+ </xsl:template>
+
+ <!-- Replace ' by \&' ans . by \&. -->
+ <xsl:template match="text()">
+ <xsl:variable name="startstring">
+ <xsl:value-of select="normalize-space()"/><xsl:text> </xsl:text>
+ </xsl:variable>
+ <xsl:variable name="rep1">
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="$startstring" />
+ <xsl:with-param name="replace" select="&quot;\&quot;" />
+ <xsl:with-param name="with" select="&quot;\\&quot;" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="rep2">
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="$rep1" />
+ <xsl:with-param name="replace" select="&quot;&apos;&quot;" />
+ <xsl:with-param name="with" select="&quot;\&amp;&apos;&quot;" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="$rep2" />
+ <xsl:with-param name="replace" select="&quot;.&quot;" />
+ <xsl:with-param name="with" select="&quot;\&amp;.&quot;" />
+ </xsl:call-template>
+ </xsl:template>
+
+ <!-- Template replace-string is borrowed at http://www.dpawson.co.uk/xsl/sect2/replace.html -->
+ <xsl:template name="replace-string">
+ <xsl:param name="text"/>
+ <xsl:param name="replace"/>
+ <xsl:param name="with"/>
+ <xsl:choose>
+ <xsl:when test="contains($text,$replace)">
+ <xsl:value-of select="substring-before($text,$replace)"/>
+ <xsl:value-of select="$with"/>
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="substring-after($text,$replace)"/>
+ <xsl:with-param name="replace" select="$replace"/>
+ <xsl:with-param name="with" select="$with"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:template>
</xsl:stylesheet>
diff --git a/lib/erl_docgen/priv/xsl/db_pdf.xsl b/lib/erl_docgen/priv/xsl/db_pdf.xsl
index bef86277ea..e12b4d219a 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl
@@ -2,20 +2,20 @@
<!--
#
# %CopyrightBegin%
- #
- # Copyright Ericsson AB 2009. All Rights Reserved.
- #
+ #
+ # Copyright Ericsson AB 2009-2010. All Rights Reserved.
+ #
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
- #
+ #
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
- #
+ #
# %CopyrightEnd%
-->
@@ -229,7 +229,9 @@
<xsl:value-of select="$companyname"/>
</fo:block>
<fo:block xsl:use-attribute-sets="cover.inner.copyrightnotice">
- The contents of this file are subject to the Erlang Public License,
+ <xsl:value-of select="/book/header/legalnotice"/>
+
+ <!-- The contents of this file are subject to the Erlang Public License,
Version 1.1, (the "License"); you may not use this file except in
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
@@ -241,6 +243,7 @@
under the License.
The Initial Developer of the Original Code is
+-->
<xsl:value-of select="$companyname"/>.
</fo:block>
<fo:block xsl:use-attribute-sets="cover.inner.date">
@@ -382,7 +385,9 @@
<xsl:choose>
<xsl:when test="ancestor::cref">
<fo:bookmark internal-destination="{generate-id(nametext)}" starting-state="hide">
- <xsl:variable name="fname"><xsl:value-of select="substring-before(nametext, '(')"/></xsl:variable>
+ <xsl:variable name="fname">
+ <xsl:value-of select="substring-before(nametext, '(')"/>
+ </xsl:variable>
<fo:bookmark-title>
<xsl:choose>
<xsl:when test="string-length($fname) > 0">
@@ -422,8 +427,26 @@
<xsl:with-param name="no-of-pars" select="0"/>
</xsl:call-template>
</xsl:variable>
+
+ <xsl:variable name="fname">
+ <xsl:variable name="fname1">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:variable>
+ <xsl:variable name="fname2">
+ <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($fname2) > 0">
+ <xsl:value-of select="$fname2"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fname1"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
<fo:bookmark-title>
- <xsl:value-of select="substring-before(., '(')"/>/<xsl:value-of select="$arity"/>
+ <xsl:value-of select="$fname"/>/<xsl:value-of select="$arity"/>
</fo:bookmark-title>
</fo:bookmark>
</xsl:when>
@@ -668,12 +691,12 @@
<xsl:number level="any" from="part" count="code"/>
</xsl:variable>
- <fo:block xsl:use-attribute-sets="code" margin-left="1.5em">
+ <fo:block xsl:use-attribute-sets="code">
<xsl:apply-templates select="text()"/>
</fo:block>
<xsl:if test="@caption">
- <fo:block xsl:use-attribute-sets="caption" margin-left="1.5em">
+ <fo:block xsl:use-attribute-sets="caption">
Code listing <xsl:value-of select="$partnum"/>.<xsl:value-of select="$codenum"/>:&#160;
<xsl:value-of select="@caption"/>
</fo:block>
@@ -687,12 +710,12 @@
<xsl:number level="any" from="part" count="code"/>
</xsl:variable>
- <fo:block xsl:use-attribute-sets="code" margin-left="1.5em">
+ <fo:block xsl:use-attribute-sets="code">
<xsl:apply-templates/>
</fo:block>
<xsl:if test="@caption">
- <fo:block xsl:use-attribute-sets="caption" margin-left="1.5em">
+ <fo:block xsl:use-attribute-sets="caption">
Code listing <xsl:value-of select="$partnum"/>.<xsl:value-of select="$codenum"/>:&#160;
<xsl:value-of select="@caption"/>
</fo:block>
@@ -862,7 +885,7 @@
<!-- Funcs -->
<xsl:template match="funcs">
-
+ <xsl:param name="partnum"/>
<fo:block xsl:use-attribute-sets="h3">
<xsl:text>Exports</xsl:text>
</fo:block>
@@ -958,6 +981,7 @@
<!-- Desc -->
<xsl:template match="desc">
+ <xsl:param name="partnum"/>
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
@@ -1103,27 +1127,62 @@
<xsl:template name="remove-paren">
<xsl:param name="string"/>
+
+ <xsl:variable name="str1">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$string"/>
+ <xsl:with-param name="start">(</xsl:with-param>
+ <xsl:with-param name="end">)</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str2">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str1"/>
+ <xsl:with-param name="start">{</xsl:with-param>
+ <xsl:with-param name="end">}</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str3">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str2"/>
+ <xsl:with-param name="start">[</xsl:with-param>
+ <xsl:with-param name="end">]</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select="$str3"/>
+
+ </xsl:template>
+
+
+ <xsl:template name="remove-paren-1">
+ <xsl:param name="string"/>
+ <xsl:param name="start"/>
+ <xsl:param name="end"/>
- <xsl:variable name="bstring">
- <xsl:value-of select="substring-before($string, '(')"/>
+ <xsl:variable name="tmp1">
+ <xsl:value-of select="substring-before($string, $start)"/>
</xsl:variable>
<xsl:choose>
- <xsl:when test="string-length($bstring) > 0">
- <xsl:variable name="astring">
- <xsl:value-of select="substring-after($string, ')')"/>
+ <xsl:when test="string-length($tmp1) > 0 or starts-with($string, $start)">
+ <xsl:variable name="tmp2">
+ <xsl:value-of select="substring-after($string, $end)"/>
</xsl:variable>
<xsl:variable name="retstring">
<xsl:call-template name="remove-paren">
- <xsl:with-param name="string" select="$astring"/>
+ <xsl:with-param name="string" select="$tmp2"/>
</xsl:call-template>
</xsl:variable>
- <xsl:value-of select="concat($bstring, $retstring)"/>
+ <xsl:value-of select="concat(concat($tmp1, 'x'), $retstring)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
+
</xsl:template>
</xsl:stylesheet>
diff --git a/lib/erl_docgen/priv/xsl/db_pdf_params.xsl b/lib/erl_docgen/priv/xsl/db_pdf_params.xsl
index e2e264b90a..7de20f2092 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf_params.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf_params.xsl
@@ -2,20 +2,20 @@
<!--
#
# %CopyrightBegin%
- #
- # Copyright Ericsson AB 2009. All Rights Reserved.
- #
+ #
+ # Copyright Ericsson AB 2009-2010. All Rights Reserved.
+ #
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
- #
+ #
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
- #
+ #
# %CopyrightEnd%
-->
@@ -110,7 +110,7 @@
<xsl:attribute-set name="cover.inner.copyrightnotice">
<xsl:attribute name="font-size">0.9em</xsl:attribute>
- <xsl:attribute name="font-weight">bold</xsl:attribute>
+ <!-- xsl:attribute name="font-weight">bold</xsl:attribute -->
</xsl:attribute-set>
<xsl:attribute-set name="cover.inner.date">
@@ -248,6 +248,8 @@
<xsl:attribute name="padding-after">1em</xsl:attribute>
<xsl:attribute name="space-after">1em</xsl:attribute>
<xsl:attribute name="space-before">2em</xsl:attribute>
+ <xsl:attribute name="margin-left">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-right">0.5em</xsl:attribute>
<xsl:attribute name="white-space-collapse">false</xsl:attribute>
<xsl:attribute name="white-space-treatment">preserve</xsl:attribute>
<xsl:attribute name="wrap-option">no-wrap</xsl:attribute>
@@ -266,8 +268,10 @@
<xsl:attribute name="text-align">justify</xsl:attribute>
<xsl:attribute name="padding-before">1em</xsl:attribute>
<xsl:attribute name="padding-after">0.3em</xsl:attribute>
- <xsl:attribute name="padding-left">1em</xsl:attribute>
- <xsl:attribute name="padding-right">1em</xsl:attribute>
+ <xsl:attribute name="padding-left">0.5em</xsl:attribute>
+ <xsl:attribute name="padding-right">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-left">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-right">0.5em</xsl:attribute>
<xsl:attribute name="keep-together.within-page">always</xsl:attribute>
</xsl:attribute-set>
@@ -278,8 +282,10 @@
<xsl:attribute name="text-align">justify</xsl:attribute>
<xsl:attribute name="padding-before">1em</xsl:attribute>
<xsl:attribute name="padding-after">0.3em</xsl:attribute>
- <xsl:attribute name="padding-left">1em</xsl:attribute>
- <xsl:attribute name="padding-right">1em</xsl:attribute>
+ <xsl:attribute name="padding-left">0.5em</xsl:attribute>
+ <xsl:attribute name="padding-right">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-left">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-right">0.5em</xsl:attribute>
<xsl:attribute name="keep-together.within-page">always</xsl:attribute>
</xsl:attribute-set>
diff --git a/lib/erl_interface/src/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c
index b685709c02..8d559f0f55 100644
--- a/lib/erl_interface/src/legacy/erl_eterm.c
+++ b/lib/erl_interface/src/legacy/erl_eterm.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/*
@@ -786,6 +786,12 @@ ETERM *erl_copy_term(const ETERM *ep)
case ERL_U_SMALL_BIG:
ERL_INT_UVALUE(cp) = ERL_INT_UVALUE(ep);
break;
+ case ERL_LONGLONG:
+ ERL_LL_VALUE(cp) = ERL_LL_VALUE(ep);
+ break;
+ case ERL_U_LONGLONG:
+ ERL_LL_UVALUE(cp) = ERL_LL_UVALUE(ep);
+ break;
case ERL_FLOAT:
ERL_FLOAT_VALUE(cp) = ERL_FLOAT_VALUE(ep);
break;
diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index c5f4c06037..589b9e2f9c 100644
--- a/lib/erl_interface/vsn.mk
+++ b/lib/erl_interface/vsn.mk
@@ -1 +1 @@
-EI_VSN = 3.6.4
+EI_VSN = 3.6.5
diff --git a/lib/et/doc/src/Makefile b/lib/et/doc/src/Makefile
index bcbde437d1..6bb8164e91 100644
--- a/lib/et/doc/src/Makefile
+++ b/lib/et/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -41,6 +41,9 @@ include files.mk
# ----------------------------------------------------
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
@@ -60,7 +63,7 @@ XML_FLAGS +=
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
-$(HTMLDIR)/%.gif: %.gif
+$(HTMLDIR)/%: %
$(INSTALL_DATA) $< $@
docs: pdf html man
@@ -69,9 +72,14 @@ $(TOP_PDF_FILE): $(XML_FILES)
pdf: $(TOP_PDF_FILE)
-html: gifs $(HTML_REF_MAN_FILE)
+html: images $(HTML_REF_MAN_FILE)
clean clean_docs:
+ for file in $(XML_FILES); do \
+ if [ -f $$file\src ]; then \
+ rm -f $$file; \
+ fi \
+ done
rm -rf $(HTMLDIR)/*
rm -f $(MAN3DIR)/*
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
@@ -79,7 +87,7 @@ clean clean_docs:
man: $(MAN3_FILES)
-gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
+images: $(IMAGE_FILES:%=$(HTMLDIR)/%)
debug opt:
diff --git a/lib/et/doc/src/book.gif b/lib/et/doc/src/book.gif
deleted file mode 100644
index 94b3868792..0000000000
--- a/lib/et/doc/src/book.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/coffee_order.png b/lib/et/doc/src/coffee_order.png
new file mode 100644
index 0000000000..b3f17e7ead
--- /dev/null
+++ b/lib/et/doc/src/coffee_order.png
Binary files differ
diff --git a/lib/et/doc/src/et.xml b/lib/et/doc/src/et.xml
index 27cc47a4b4..9b170dd7d9 100644
--- a/lib/et/doc/src/et.xml
+++ b/lib/et/doc/src/et.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>et</title>
@@ -37,30 +37,28 @@
</description>
<funcs>
<func>
- <name>report_event(DetailLevel, FromTo, Label, Contents) -> hopefully_traced</name>
- <name>report_event(DetailLevel, From, To, Label, Contents) -> hopefully_traced</name>
- <name>phone_home(DetailLevel, FromTo, Label, Contents) -> hopefully_traced</name>
- <name>phone_home(DetailLevel, From, To, Label, Contents) -> hopefully_traced</name>
- <fsummary>Reports an event, such as a message</fsummary>
+ <name>trace_me(DetailLevel, From, To, Label, Contents) -> hopefully_traced</name>
+ <fsummary>A function that is intended to be traced.</fsummary>
<type>
<v>DetailLevel = integer(X) when X =&lt; 0, X >= 100</v>
<v>From = actor()</v>
<v>To = actor()</v>
- <v>FromTo = actor()</v>
<v>Label = atom() | string() | term()</v>
<v>Contents = [{Key, Value}] | term()</v>
- <v>actor() = term()</v>
+ <v>actor() = term()</v>
</type>
<desc>
- <p>Reports an event, such as a message.</p>
- <p>These functions are intended to be invoked at strategic places
- in user applications in order to enable simplified tracing.
- The functions are extremely light weight as they do nothing
- besides returning an atom. These functions are designed for
- being traced. The global tracing mechanism in et_collector
- defaults to set its trace pattern to these functions.</p>
- <p>The label is intended to provide a brief summary of the event.
- A simple tag would do.</p>
+ <p>A function that is intended to be traced.</p>
+ <p>This function is intended to be invoked at strategic places
+ in user applications in order to enable simplified
+ tracing. The functions are extremely light weight as they do
+ nothing besides returning an atom. The functions are designed
+ for being traced. The global tracing mechanism in
+ <c>et_collector</c> defaults to set its trace pattern to these
+ functions.</p>
+ <p>The label is intended to provide a brief summary of the
+ event. It is preferred to use an atom but a string would also
+ do.</p>
<p>The contents can be any term but in order to simplify
post processing of the traced events, a plain list
of {Key, Value} tuples is preferred.</p>
@@ -68,6 +66,37 @@
Other events (termed actions) may be undirected and only have one actor.</p>
</desc>
</func>
+
+ <func>
+ <name>trace_me(DetailLevel, FromTo, Label, Contents) -> hopefully_traced</name>
+ <fsummary>A function that is intended to be traced.</fsummary>
+ <desc>
+ <p>Invokes <c>et:trace_me/5</c> with both <c>From</c> and <c>To</c>
+ set to <c>FromTo</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>phone_home(DetailLevel, FromTo, Label, Contents) -> hopefully_traced</name>
+ <name>phone_home(DetailLevel, From, To, Label, Contents) -> hopefully_traced</name>
+ <fsummary>Send a signal to the outer space</fsummary>
+ <desc>
+ <p>These functions sends a signal to the outer space and the
+ caller hopes that someone is listening. In other words, they
+ invoke <c>et:trace_me/4</c> and <c>et:trace_me/5</c>
+ respectively.</p>
+ </desc>
+ </func>
+ <func>
+ <name>report_event(DetailLevel, FromTo, Label, Contents) -> hopefully_traced</name>
+ <name>report_event(DetailLevel, From, To, Label, Contents) -> hopefully_traced</name>
+ <fsummary>Deprecated functions</fsummary>
+ <desc>
+ <p>Deprecated functions which for the time being are kept for
+ backwards compatibility. Invokes <c>et:trace_me/4</c> and
+ <c>et:trace_me/5</c> respectively.</p>
+ </desc>
+ </func>
</funcs>
</erlref>
diff --git a/lib/et/doc/src/et_architecture.xml b/lib/et/doc/src/et_architecture.xml
deleted file mode 100644
index 44e262db96..0000000000
--- a/lib/et/doc/src/et_architecture.xml
+++ /dev/null
@@ -1,554 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2002</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Usage</title>
- <prepared>H&aring;kan Mattsson</prepared>
- <responsible>H&aring;kan Mattsson</responsible>
- <docno></docno>
- <approved>H&aring;kan Mattsson</approved>
- <checked></checked>
- <date></date>
- <rev>%VSN%</rev>
- <file>et_architecture.xml</file>
- </header>
-
- <section>
- <title>Overview</title>
- <p>The two major components of the Event Tracer (ET)
- tool is a graphical sequence chart viewer (<c>et_viewer</c>)
- and its backing storage (<c>et_collector</c>). One collector
- may be used as backing storage for several simultaneous
- viewers where each one may display a different view of
- the same trace data.</p>
- <p>The interface between the collector and its viewers
- is public in order to enable other types of viewers.
- However in the following text we will focus on usage
- of the <c>et_viewer</c>.</p>
- <p>The main start function is <c>et_viewer:start/1</c>.
- It will by default start both an <c>et_collector</c> and
- an <c>et_viewer</c>:</p>
- <p></p>
- <code type="none"><![CDATA[
- % erl -pa et/examples
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- 1> {ok, Viewer} = et_viewer:start([]).
- {ok,<0.31.0>}
- ]]></code>
- <p>A viewer gets trace events from its collector
- by polling it regularly for more events to display.
- Trace events are for example reported to the collector with
- <c>et_collector:report_event/6</c>:</p>
- <code type="none"><![CDATA[
- 2> Collector = et_viewer:get_collector_pid(Viewer).
- <0.30.0>
- 3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer,
- "Start outer transaction"),
- 3> et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid,
- "New transaction id is 4711"),
- 3> et_collector:report_event(Collector, 20, my_shell, mnesia_locker, try_write_lock,
- "Acquire write lock for {my_tab, key}"),
- 3> et_collector:report_event(Collector, 10, mnesia_locker, my_shell, granted,
- "You got the write lock for {my_tab, key}"),
- 3> et_collector:report_event(Collector, 60, my_shell, do_commit,
- "Perform transaction commit"),
- 3> et_collector:report_event(Collector, 40, my_shell, mnesia_locker, release_tid,
- "Release all locks for transaction 4711"),
- 3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction,
- "End of outer transaction"),
- 3> et_collector:report_event(Collector, 20, my_shell, end_outer,
- "Transaction returned {atomic, ok}").
- {ok,{table_handle,<0.30.0>,11,trace_ts,#Fun<et_collector.0.83904657>}}
- 4>
- ]]></code>
- <p>This is a simulation of the process events caused by a Mnesia
- transaction that writes a record in a local table:</p>
- <code type="none">
- mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).
- </code>
- <p>At this stage when we have a couple of events, it is time to
- show how it looks like in the graphical interface of
- <c>et_viewer</c>:</p>
- <p></p>
- <image file="sim_trans.gif">
- <icaption>A simulated Mnesia transaction which writes one record</icaption>
- </image>
- <p>In the sequence chart, the actors (which symbolically has performed the
- traced event) are shown as named vertical bars. The order of the
- actors may be altered by dragging (hold mouse button 1 pressed during
- the operation) the name tag of an actor and drop it elsewhere:</p>
- <image file="sim_trans_move_actor.gif">
- <icaption>Two actors has switched places</icaption>
- </image>
- <p>An event may be an action performed by one single actor (blue
- text label) or it may involve two actors and is then depicted as an
- arrow directed from one actor to another (red text label). Details of
- an event can be shown by clicking (press and release the mouse button 1)
- on the event label text or on the arrow:</p>
- <p></p>
- <image file="sim_trans_write_lock.gif">
- <icaption>Details of a write lock message</icaption>
- </image>
- </section>
-
- <section>
- <title>Filters and dictionary</title>
- <p>The Event Tracer (ET) uses named filters in various
- contexts. An Event Trace filter is an <c>Erlang fun</c>
- that takes some trace data as input and returns a possibly
- modified version of it:
- </p>
- <p></p>
- <code type="none">
- filter(TraceData) -> true | {true, NewEvent} | false
-
- TraceData = NewEvent | term()
- NewEvent = record(event)
- </code>
- <p>The interface of the filter function is the same as the the
- filter functions for the good old <c>lists:zf/2</c>. If the filter
- returns <c>false</c> it means that the <c>TraceData</c> should be
- dropped. <c>{true, NewEvent}</c> means that the <c>TraceData</c>
- should be replaced with <c>NewEvent</c>. And <c>true</c> means that the
- <c>TraceData</c> data already is an event record and that it
- should be kept as it is.
- </p>
- <p>The first filter that the trace data is exposed for is
- the collector filter. When a trace event is reported with
- <c>et_collector:report/2</c> (or <c>et_collector:report_event/5,6</c>)
- the first thing that
- happens, is that a message is sent to the collector process
- to fetch a handle that contains some useful stuff, such as
- the collector filter fun and an ets table identifier.
- Then the collector filter fun is applied and if it returns
- <c>true</c> (or <c>{true, NewEvent}</c>), the event will
- be stored in an ets table. As an optimization, subsequent
- calls to <c>et_collector:report</c>-functions can use the handle
- directly instead of the collector pid.
- </p>
- <p>The collector filter (that is the filter named
- <c>collector</c>) is a little bit special, as its input
- may be any Erlang term and is not limited to take an event
- record as the other filter functions.
- </p>
- <p>The collector manages a key/value based dictionary, where
- the filters are stored. Updates of the dictionary is
- propagated to all subscribing processes. When a viewer is
- started it is registered as a subscriber of dictionary updates.
- </p>
- <p>In a viewer there is only one filter that is active
- and all trace events that the viewer gets from the
- collector will pass thru that filter. By writing clever
- filters it is possible to customize how the events
- looks like in the viewer. The following filter replaces
- the actor names <c>mnesia_tm</c> and <c>mnesia_locker</c>
- and leaves everything else in the record as it was:
- </p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%mgr_actors" type="erl"></codeinclude>
- <p>If we now add the filter to the running collector:
- </p>
- <p></p>
- <code type="none"><![CDATA[
- 4> Fun = fun(E) -> et_demo:mgr_actors(E) end.
- #Fun<erl_eval.5.123085357>
- 5> et_collector:dict_insert(Collector, {filter, mgr_actors}, Fun).
- ok
- 6>
- ]]></code>
- <p>you will see that the <c>Filter</c> menu in all viewers have
- got a new entry called <c>mgr_actors</c>. Select it, and a new
- viewer window will pop up:</p>
- <p></p>
- <image file="sim_trans_mgr_actors.gif">
- <icaption>The same trace data in a different view</icaption>
- </image>
- <p>In order to see the nitty gritty details of an event
- you may click on the event in order to start a contents
- viewer for that event. In the contents viewer there is
- also a filter menu in order to enable inspection of the
- event from other views than the one selected in the viewer.
- A click on the <c>new_tid</c> event will cause a contents
- viewer window to pop up, showing the event in the
- <c>mgr_actors</c> view:</p>
- <p></p>
- <image file="sim_trans_contents_viewer_mgr_actors.gif">
- <icaption>The trace event in the mgr_actors view</icaption>
- </image>
- <p>Select the <c>collector</c> entry in the <c>Filters</c>
- menu and a new contents viewer window will pop up
- showing the same trace event in the collectors view:</p>
- <p></p>
- <image file="sim_trans_contents_viewer_collector.gif">
- <icaption>The same trace event in the collectors view</icaption>
- </image>
- </section>
-
- <section>
- <title>Trace clients</title>
- <p>As you have seen it is possible to use the
- <c>et_collector:report</c>-functions explicitly. By using those functions
- you can write your own trace client that reads trace data from any
- source stored in any format and just feed the collector with it. You
- may replace the default collector filter with a filter that converts
- new exciting trace data formats to event-records or you may convert it
- to an event-record before you invoke <c>et_collector:report/2</c> and
- then rely on the default collector filter to handle the new
- format.</p>
- <p>There are also existing functions in the API that reads from
- various sources and calls <c>et_collector:report/2</c>:</p>
- <list type="bulleted">
- <item>
- <p>The trace events that are hosted by the collector may be
- stored to file and later be loaded by selecting <c>save</c>
- and <c>load</c> entries in the viewers <c>File</c>-menu or
- via the <c>et_collector</c> API.</p>
- </item>
- <item>
- <p>It is also possible to perform live tracing of a running
- system by making use of the built-in trace support in
- the Erlang emulator. These Erlang traces can be directed
- to files or to ports. See the reference manual for
- <c>erlang:trace/4</c>, <c>erlang:trace_pattern/3</c>,
- <c>dbg</c> and <c>ttb</c> for more info.</p>
- <p>There are also corresponding trace client types that can
- read the Erlang trace data format from such files or ports.
- The <c>et_collector:start_trace_client/3</c> function makes
- use of these Erlang trace clients and redirects the trace
- data to the collector.</p>
- <p>The default collector filter converts the Erlang trace data
- format into event-records.If you want to perform this
- differently you can of course write your own collector
- filter from scratch. But it may probably save you some
- efforts if you first apply the default filter in
- <c>et_selector:parse_event/2</c> before you apply your
- own conversions of its output.</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Global tracing and phone home</title>
- <p>Setting up an Erlang tracer on a set of nodes and connecting
- trace clients to the ports of these tracers is not intuitive. In order
- to make this it easier the Event Tracer as a notion of global
- tracing. When used, the <c>et_collector</c> process will monitor
- Erlang nodes and when one connects, an Erlang tracer will
- automatically be started on the other node. A corresponding trace
- client will also be started on the collector node in order to
- automatically forward the trace events to the collector. Set the
- boolean parameter <c>trace_global</c> to <c>true</c> for either the
- <c>et_collector</c> or <c>et_viewer</c> in order to activate the
- global tracing. There is no restriction on how many concurrent
- (anonymous) collectors you can have, but you can only have one global
- collector as its name is registered in <c>global</c>.</p>
- <p>In order to further simplify the tracing you can make use of the
- <c>et:report_event/4,5</c> (or its equivalents
- <c>et:phone_home/4,5</c> :-). These functions are intended to be
- invoked from other applications when there are interesting events,
- in your application that needs to be highlighted. The functions are
- extremely light weight as they do nothing besides returning an atom.
- These functions are
- specifically designed to be traced for. As the caller explicitly
- provides the values for the event-record fields, the default collector
- filter is able to automatically provide a customized event-record
- without any user defined filter functions.</p>
- <p>In normal operation the <c>et:report_event/4,5</c> calls are
- almost for free. When tracing is needed you can either activate
- tracing on these functions explicitly. Or you can combine the usage of
- <c>trace_global</c> with the usage of <c>trace_pattern</c>. When set,
- the <c>trace_pattern</c> will automatically be activated on all
- connected nodes. </p>
- <p>One nice thing with the <c>trace_pattern</c> is that it provides
- a very simple way of minimizing the amount of generated trace data by
- allowing you to explicitly control the detail level of the tracing. As
- you may have seen the <c>et_viewer</c> have a slider called
- <c>"Detail Level"</c> that allows you to control the detail level of the
- trace events displayed in the viewer. On the other hand if you set a
- low detail level in the <c>trace_pattern</c>, lots of the trace data
- will never be generated and thus not sent over the socket to the trace
- client and stored in the collector.</p>
- </section>
-
- <section>
- <title>Viewer window</title>
- <p>Almost all functionality available in the <c>et_viewer</c> is
- also available via shortcuts. Which key that has the same
- effect as selecting a menu entry is shown enclosed in
- parentheses. For example pressing the key <c>r</c> is
- equivalent to selecting the menu entry
- <c>Viewer->Refresh</c>.
- </p>
- <p>File menu:</p>
- <list type="bulleted">
- <item>
- <p>Close Collector and all Viewers - Close the collector
- and all viewers connected to that collector.</p>
- </item>
- <item>
- <p>Close other Viewers, but keep Collector - Keep this viewer
- and its collector, but close all other viewers connected
- to this collector.</p>
- </item>
- <item>
- <p>Close this Viewer, but keep Collector - Close this viewer,
- but all other viewers and the collector.</p>
- </item>
- <item>
- <p>Save Collector to file - Save all events stored in the
- collector to file.</p>
- </item>
- <item>
- <p>Load Collector from file - Load the collector with
- events from a file.</p>
- </item>
- </list>
- <p>Viewer menu:</p>
- <list type="bulleted">
- <item>
- <p>First - Scroll <c>this</c> viewer to the first collector
- event.</p>
- </item>
- <item>
- <p>Prev - Scroll <c>this</c> viewer one "page" backwards.
- Normally this means that the first event displayed in the
- viewer will be the last one and the previous <c>max_events</c>
- events will be read from the collector.</p>
- </item>
- <item>
- <p>Next - Scroll <c>this</c> viewer one "page" forward.
- Normally this means that the last event displayed in the
- viewer will be the first one and <c>max_events</c> more
- events will be read from the collector.</p>
- </item>
- <item>
- <p>Last - Scroll <c>this</c> viewer to the last collector event.</p>
- </item>
- <item>
- <p>Refresh - Clear <c>this</c> viewer and re-read its events
- from the collector.</p>
- </item>
- <item>
- <p>Up 5 - Scroll 5 events backwards.</p>
- </item>
- <item>
- <p>Down 5 - Scroll 5 events forward.</p>
- </item>
- <item>
- <p>Abort search. Display all. - Switch the display mode to
- show all events regardless of any ongoing searches.
- Abort the searches.</p>
- </item>
- </list>
- <p>Collector menu:</p>
- <list type="bulleted">
- <item>
- <p>First - Scroll <c>all</c> viewers to the first collector
- event.</p>
- </item>
- <item>
- <p>Prev - Scroll <c>all</c> viewers one "page" backwards.
- Normally this means that the first event displayed in the
- viewer will be the last one and the previous <c>max_events</c>
- events will be read from the collector.</p>
- </item>
- <item>
- <p>Next - Scroll <c>all</c> viewers one "page" forward.
- Normally this means that the last event displayed in the
- viewer will be the first one and <c>max_events</c> more
- events will be read from the collector.</p>
- </item>
- <item>
- <p>Last - Scroll <c>all</c> viewers to the last collector event.</p>
- </item>
- <item>
- <p>Refresh - Clear <c>all</c> viewers and re-read their
- events from the collector.</p>
- </item>
- </list>
- <p>Filters menu:</p>
- <list type="bulleted">
- <item>
- <p>ActiveFilter (=) - Start a new viewer window with the
- same active filter and scale as the current one.</p>
- </item>
- <item>
- <p>ActiveFilter (+) - Start a new viewer window with
- the same active filter but a larger scale than the
- current one.</p>
- </item>
- <item>
- <p>ActiveFilter (-) - Start a new viewer window with
- the same active filter but a smaller scale than the
- current one.</p>
- </item>
- <item>
- <p>collector (0) - Start a new viewer with the collector
- filter as active filter.</p>
- </item>
- <item>
- <p>AnotherFilter (2) - If more filters are inserted into
- the dictionary, these will turn up here as entries
- in the <c>Filters</c> menu. The second filter will be
- number 2, the next one number 3 etc. The names are sorted.</p>
- </item>
- </list>
- <p>Slider and radio buttons:</p>
- <list type="bulleted">
- <item>
- <p>Freeze - When true, this means that the viewer
- will not read more events from the collector
- until set to false.</p>
- </item>
- <item>
- <p>Hide From=To - When true, this means that the viewer
- will hide all events where the from-actor equals
- to its to-actor.</p>
- </item>
- <item>
- <p>Hide Unknown - When true, this means that the viewer
- will hide all events where either of the from-actor or
- to-actor is <c>UNKNOWN</c>.</p>
- </item>
- <item>
- <p>Detail level - This slider controls the resolution
- of the viewer. Only events with a detail level <c>smaller</c>
- than the selected one (default=100=max) are displayed.</p>
- </item>
- </list>
- <p>Other features:</p>
- <list type="bulleted">
- <item>
- <p>Display details of an event - Click on the event name
- and a new window will pop up, displaying the contents
- of an event.</p>
- </item>
- <item>
- <p>Toggle actor search - Normally the viewer will be in a
- display mode where all events are shown. By clicking
- on an actor name the tool will switch display mode
- to only show events with selected actors.
- </p>
- <p>Click on an actor and only events with that actor
- will be displayed. Click on another actor to include
- that actor to the selected ones. Clicking on an already
- selected actor will remove it from the collections of
- selected actors. When the collection of selected actors
- becomes empty the normal mode where all actors are shown
- will be entered again.</p>
- <p>Abort actor search with the <c>a</c> key or with the
- <c>Viewer->Abort search</c> menu choice.
- </p>
- </item>
- <item>
- <p>Move actor - Drag and drop an actor by first clicking on
- the actor name, keeping the button pressed while moving
- the cursor to a new location and release the button where
- the actor should be moved to.</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Configuration</title>
- <p>The event-records in the ets-table are ordered by their timestamp.
- Which timestamp that should be used is controlled via the
- <c>event_order</c> parameter. Default is <c>trace_ts</c> which means
- the time when the trace data was generated. <c>event_ts</c> means
- the time when the trace data was parsed (transformed into an
- event-record).</p>
- </section>
-
- <section>
- <title>Contents viewer window</title>
- <p>File menu:</p>
- <list type="bulleted">
- <item>
- <p>Close - Close this window.</p>
- </item>
- <item>
- <p>Save - Save the contents of this window to file.</p>
- </item>
- </list>
- <p>Filters menu:</p>
- <list type="bulleted">
- <item>
- <p>ActiveFilter - Start a new contents viewer window
- with the same active filter.</p>
- </item>
- <item>
- <p>AnotherFilter (2) - If more filters are inserted into
- the dictionary, these will turn up here as entries
- in the <c>Filters</c> menu. The second filter will be
- number 2, the next one number 3 etc. The names are sorted.</p>
- </item>
- </list>
- <p>Hide menu:</p>
- <list type="bulleted">
- <item>
- <p>Hide actor in viewer - Known actors are shown as a
- named vertical bars in the viewer window. By hiding the
- actor, its vertical bar will be removed and the viewer
- will be refreshed.</p>
- <p>Hiding the actor is only useful if the <c>max_actors</c>
- threshold has been reached, as it then will imply that
- the "hidden" actor will be displayed as if it were <c>"UNKNOWN"</c>.
- If the <c>max_actors</c> threshold not have been reached,
- the actor will re-appear as a vertical bar in the viewer.
- </p>
- </item>
- <item>
- <p>Show actor in viewer - This implies that the actor
- will be added as a known actor in the viewer with
- its own vertical bar.</p>
- </item>
- </list>
- <p>Search menu:</p>
- <list type="bulleted">
- <item>
- <p>Forward from this event - Set this event to be the first
- event in the viewer and change its display mode to be
- enter forward search mode. The actor of this event
- (from, to or both) will be added to the list of selected
- actors.
- </p>
- </item>
- <item>
- <p>Reverse from this event - Set this event to be the first
- event in the viewer and change its display mode to be
- enter reverse search mode. The actor of this event
- (from, to or both) will be added to the list of selected
- actors. Observe, that the events will be shown in reverse
- order.
- </p>
- </item>
- <item>
- <p>Abort search. Display all - Switch the display mode
- of the viewer to show all events regardless of any
- ongoing searches. Abort the searches.</p>
- </item>
- </list>
- </section>
-</chapter>
-
diff --git a/lib/et/doc/src/et_collector.xml b/lib/et/doc/src/et_collector.xml
index 01ca7caa5b..88c478c89a 100644
--- a/lib/et/doc/src/et_collector.xml
+++ b/lib/et/doc/src/et_collector.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>et_collector</title>
@@ -84,11 +84,12 @@
dictionary updates will be propagated to the subscriber processes
matching the pattern {{subscriber, '_'}, '_'} where the first '_'
is interpreted as a pid().</p>
- <p>In global trace mode, the collector will automatically start
- tracing on all connected Erlang nodes. When a node connects, a port
- tracer will be started on that node and a corresponding trace
- client on the collector node. By default the global trace pattern
- is 'max'.</p>
+
+ <p>In global trace mode, the collector will automatically
+ start tracing on all connected Erlang nodes. When a node
+ connects, a port tracer will be started on that node and a
+ corresponding trace client on the collector node.</p>
+
<p>Default values:</p>
<list type="bulleted">
<item>parent_pid - self().</item>
@@ -349,7 +350,7 @@
</type>
<desc>
<p>Iterate over the currently stored events.</p>
- <p>Iterates over the currently stored eventsand applies
+ <p>Iterates over the currently stored events and applies
a function for each event. The iteration may be performed
forwards or backwards and may be limited to a maximum
number of events (abs(Limit)).</p>
diff --git a/lib/et/doc/src/et_desc.xmlsrc b/lib/et/doc/src/et_desc.xmlsrc
new file mode 100644
index 0000000000..c02517ae01
--- /dev/null
+++ b/lib/et/doc/src/et_desc.xmlsrc
@@ -0,0 +1,683 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2002</year><year>2010</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Description</title>
+ <prepared>H&aring;kan Mattsson</prepared>
+ <responsible>H&aring;kan Mattsson</responsible>
+ <docno></docno>
+ <approved>H&aring;kan Mattsson</approved>
+ <checked></checked>
+ <date></date>
+ <rev>%VSN%</rev>
+ <file>et_desc.xml</file>
+ </header>
+
+ <section>
+ <title>Overview</title>
+
+ <p>The two major components of the <c>Event Tracer (ET)</c> tool
+ is a graphical sequence chart viewer (<c>et_viewer</c>) and its
+ backing storage (<c>et_collector</c>). One <c>Collector</c> may be
+ used as backing storage for several simultaneous <c>Viewers</c>
+ where each one may display a different view of the same trace
+ data.</p>
+
+ <p>The interface between the <c>Collector</c> and its
+ <c>Viewers</c> is public in order to enable other types of
+ <c>Viewers</c>. However in the following text we will focus on
+ usage of the <c>et_viewer</c>.</p>
+
+ <p>The main start function is <c>et_viewer:start/1</c>. By
+ default it will start both an <c>et_collector</c> and an
+ <c>et_viewer</c>:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ % erl -pa et/examples
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ 1> {ok, Viewer} = et_viewer:start([]).
+ {ok,<0.40.0>}]]></code>
+
+ <p>A <c>Viewer</c> gets trace <c>Events</c> from its
+ <c>Collector</c> by polling it regularly for more <c>Events</c> to
+ display. <c>Events</c> are for example reported to the
+ <c>Collector</c> with <c>et_collector:report_event/6</c>:</p>
+
+ <code type="none"><![CDATA[
+ 2> Collector = et_viewer:get_collector_pid(Viewer).
+ <0.39.0>
+ 3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer,
+ 3> "Start outer transaction"),
+ 3> et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid,
+ 3> "New transaction id is 4711"),
+ 3> et_collector:report_event(Collector, 20, my_shell, mnesia_locker, try_write_lock,
+ 3> "Acquire write lock for {my_tab, key}"),
+ 3> et_collector:report_event(Collector, 10, mnesia_locker, my_shell, granted,
+ 3> "You got the write lock for {my_tab, key}"),
+ 3> et_collector:report_event(Collector, 60, my_shell, do_commit,
+ 3> "Perform transaction commit"),
+ 3> et_collector:report_event(Collector, 40, my_shell, mnesia_locker, release_tid,
+ 3> "Release all locks for transaction 4711"),
+ 3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction,
+ 3> "End of outer transaction"),
+ 3> et_collector:report_event(Collector, 20, my_shell, end_outer,
+ 3> "Transaction returned {atomic, ok}").
+ {ok,{table_handle,<0.39.0>,16402,trace_ts,
+ #Fun<et_collector.0.62831470>}}]]></code>
+
+ <p>This actually is a simulation of the process <c>Events</c>
+ caused by a <c>Mnesia</c> transaction that writes a record in a local
+ table:</p>
+
+ <code type="none"><![CDATA[
+ mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).]]></code>
+
+ <p>At this stage when we have a couple of <c>Events</c>, it is time to
+ show how it looks like in the graphical interface of
+ <c>et_viewer</c>:</p>
+
+ <p></p>
+
+ <image file="sim_trans.png">
+ <icaption>A simulated Mnesia transaction which writes one record</icaption>
+ </image>
+
+ <p>In the sequence chart, the actors (which symbolically has
+ performed the <c>Event</c>) are shown as named vertical bars. The
+ order of the actors may be altered by dragging (hold mouse button
+ 1 pressed during the operation) the name tag of an actor and drop
+ it elsewhere:</p>
+
+ <image file="sim_trans_move_actor.png">
+ <icaption>Two actors has switched places</icaption>
+ </image>
+
+ <p>An <c>Event</c> may be an action performed by one single actor
+ (blue text label) or it may involve two actors and is then
+ depicted as an arrow directed from one actor to another (red text
+ label). Details of an <c>Event</c> can be shown by clicking (press
+ and release the mouse button 1) on the event label text or on the
+ arrow. When doing that a <c>Contents Viewer</c> window pops up. It
+ may look like this:</p>
+
+ <p></p>
+
+ <image file="sim_trans_write_lock.png">
+ <icaption>Details of a write lock message</icaption>
+ </image>
+ </section>
+
+ <section>
+ <title>Filters and dictionary</title>
+
+ <p>The <c>Event Tracer (ET)</c> uses named filters in various
+ contexts. An Event Trace filter is an <c>Erlang fun</c> that takes
+ some trace data as input and returns a possibly modified version
+ of it:
+ </p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ filter(TraceData) -> false | true | {true, NewEvent}
+
+ TraceData = Event | erlang_trace_data()
+ Event = #event{}
+ NewEvent = #event{}]]></code>
+
+ <p>The interface of the filter function is the same as the the
+ filter functions for the good old <c>lists:zf/2</c>. If the filter
+ returns <c>false</c> it means that the trace data should silently
+ be dropped. <c>true</c> means that the trace data data already is
+ an <c>Event Record</c> and that it should be kept as it is.
+ <c>true</c> means that the <c>TraceData</c> already is an <c>Event
+ Record</c> and that it should be kept as it is. <c>{true,
+ NewEvent}</c> means that the original trace data should be
+ replaced with <c>Event</c>. This provides means to get rid of
+ unwanted <c>Events</c> as well as enabling alternate views of an
+ <c>Event</c>.</p>
+
+ <p>The first filter that the trace data is exposed for is the
+ <c>Collector Filter</c>. When a trace <c>Event</c> is reported with
+ <c>et_collector:report/2</c> (or
+ <c>et_collector:report_event/5,6</c>) the first thing that
+ happens, is that a message is sent to the <c>Collector</c> process
+ to fetch a handle that contains some useful stuff, such as the
+ <c>Collector Filter Fun</c> and an Ets table identifier. Then the
+ <c>Collector Filter Fun</c> is applied and if it returns
+ <c>true</c> (or <c>{true, NewEvent}</c>), the <c>Event</c> will be stored
+ in an Ets table. As an optimization, subsequent calls to
+ <c>et_collector:report</c>-functions can use the handle directly
+ instead of the <c>Collector Pid</c>.</p>
+
+ <p>All filters (registered in a <c>Collector</c> or in a
+ <c>Viewer</c>) must be able to handle an <c>Event record</c> as
+ input. The <c>Collector Filter</c> (that is the filter named
+ <c>all</c>) is a little bit special, as its input also may be raw
+ <c>Erlang Trace Data</c></p>
+
+ <p>The <c>Collector</c> manages a key/value based dictionary,
+ where the filters are stored. Updates of the dictionary is
+ propagated to all subscribing processes. When a <c>Viewer</c> is
+ started it is registered as a subscriber of dictionary
+ updates.</p>
+
+ <p>In each <c>Viewer</c> there is only one filter that is active
+ and all trace <c>Events</c> that the <c>Viewer</c> gets from the
+ <c>Collector</c> will pass thru that filter. By writing clever
+ filters it is possible to customize how the <c>Events</c> looks
+ like in the viewer. The following filter in
+ <c>et/examples/et_demo.erl</c> replaces the actor names
+ <c>mnesia_tm</c> and <c>mnesia_locker</c> and leaves everything
+ else in the record as it was:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%mgr_actors" type="erl"></codeinclude>
+ <p>If we now add the filter to the running <c>Collector</c>:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ 4> Fun = fun(E) -> et_demo:mgr_actors(E) end.
+ #Fun<erl_eval.6.13229925>
+ 5> et_collector:dict_insert(Collector, {filter, mgr_actors}, Fun).
+ ok]]></code>
+
+ <p>you will see that the <c>Filter</c> menu in all viewers have
+ got a new entry called <c>mgr_actors</c>. Select it, and a new
+ <c>Viewer</c> window will pop up:</p>
+
+ <p></p>
+
+ <image file="sim_trans_mgr_actors.png">
+ <icaption>The same trace data in a different view</icaption>
+ </image>
+
+ <p>In order to see the nitty gritty details of an <c>Event</c> you
+ may click on the <c>Event</c> in order to start a <c>Contents
+ Viewer</c> for that <c>Event</c>. In the <c>Contents Viewer</c>
+ there also is a filter menu that enables inspection of the
+ <c>Event</c> from other views than the one selected in the
+ viewer. A click on the <c>new_tid</c> <c>Event</c> will cause a
+ <c>Contents Viewer</c> window to pop up, showing the <c>Event</c>
+ in the <c>mgr_actors</c> view:</p>
+
+ <p></p>
+
+ <image file="sim_trans_contents_viewer_mgr_actors.png">
+ <icaption>The trace <c>Event</c> in the mgr_actors view</icaption>
+ </image>
+
+ <p>Select the <c>all</c> entry in the <c>Filters</c> menu
+ and a new <c>Contents Viewer window</c> will pop up showing the
+ same trace <c>Event</c> in the collectors view:</p>
+
+ <p></p>
+
+ <image file="sim_trans_contents_viewer_collector.png">
+ <icaption>The same trace <c>Event</c> in the collectors
+ view</icaption>
+ </image>
+ </section>
+
+ <section>
+ <title>Trace clients</title>
+ <p>As you have seen, it is possible to use the
+ <c>et_collector:report_event/5,6</c> functions explicitly. By
+ using those functions you can write your own trace client that
+ reads trace data from any source stored in any format and just
+ feed the <c>Collector</c> with it. You may replace the default
+ <c>Collector Filter</c> with a filter that converts new exciting
+ trace data formats to <c>Event Records</c> or you may convert it
+ to an <c>Event Record</c> before you invoke
+ <c>et_collector:report/2</c> and then rely on the default
+ <c>Collector Filter</c> to handle the new format.</p>
+
+ <p>There are also existing functions in the API that reads from
+ various sources and calls <c>et_collector:report/2</c>:</p>
+
+ <list type="bulleted">
+ <item>
+ <p>The trace <c>Events</c> that are hosted by the <c>Collector</c> may be
+ stored to file and later be loaded by selecting <c>save</c>
+ and <c>load</c> entries in the <c>Viewers</c> <c>File</c> menu
+ or via the <c>et_collector</c> API.</p>
+ </item>
+
+ <item>
+ <p>It is also possible to perform live tracing of a running
+ system by making use of the built-in trace support in the
+ Erlang emulator. These Erlang traces can be directed to files
+ or to ports. See the reference manual for
+ <c>erlang:trace/4</c>, <c>erlang:trace_pattern/3</c>,
+ <c>dbg</c> and <c>ttb</c> for more info.</p>
+
+ <p>There are also corresponding trace client types that can
+ read the Erlang trace data format from such files or ports.
+ The <c>et_collector:start_trace_client/3</c> function makes
+ use of these Erlang trace clients and redirects the trace data
+ to the <c>Collector</c>.</p>
+
+ <p>The default <c>Collector Filter</c> converts the raw Erlang
+ trace data format into <c>Event Records</c>. If you want to
+ perform this differently you can of course write your own
+ <c>Collector Filter</c> from scratch. But it may probably save
+ you some efforts if you first apply the default filter in
+ <c>et_selector:parse_event/2</c> before you apply your own
+ conversions of its output.</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Global tracing</title>
+
+ <p>Setting up an Erlang tracer on a set of nodes and connecting
+ trace clients to the ports of these tracers is not intuitive. In
+ order to make this it easier the <c>Event Tracer</c> has a notion
+ of global tracing. When used, the <c>et_collector</c> process will
+ monitor Erlang nodes and when one connects, an Erlang tracer will
+ automatically be started on the newly connected node. A
+ corresponding trace client will also be started on the
+ <c>Collector</c> node in order to automatically forward the trace
+ <c>Events</c> to the <c>Collector</c>. Set the boolean parameter
+ <c>trace_global</c> to <c>true</c> for either the
+ <c>et_collector</c> or <c>et_viewer</c> in order to activate the
+ global tracing. There is no restriction on how many concurrent
+ (anonymous) collectors you can have, but you can only have one
+ <b>global</b> <c>Collector</c> as its name is registered in
+ <c>global</c>.</p>
+
+ <p>In order to further simplify the tracing, you can make use of
+ the <c>et:trace_me/4,5</c> functions. These functions are intended
+ to be invoked from other applications when there are interesting
+ <c>Events</c>, in your application that needs to be
+ highlighted. The functions are extremely light weight as they do
+ nothing besides returning an atom. These functions are
+ specifically designed to be traced for. As the caller explicitly
+ provides the values for the <c>Event Record</c> fields, the
+ default <c>Collector Filter</c> is able to automatically provide a
+ customized <c>Event Record</c> without any user defined filter
+ functions.</p>
+
+ <p>In normal operation, the <c>et:trace_me/4,5</c> calls are almost
+ for free. When tracing is needed, you can either activate tracing
+ on these functions explicitly. Or you can combine the usage of
+ <c>trace_global</c> with the usage of <c>trace_pattern</c>. When
+ set, the <c>trace_pattern</c> will automatically be activated on
+ all connected nodes. </p>
+
+ <p>One nice thing with the <c>trace_pattern</c> is that it
+ provides a very simple way of minimizing the amount of generated
+ trace data by allowing you to explicitly control the detail level
+ of the tracing. As you may have seen the <c>et_viewer</c> have a
+ slider called <c>"Detail Level"</c> that allows you to control the
+ detail level of the trace <c>Events</c> displayed in the
+ <c>Viewer</c>. On the other hand if you set a low detail level in
+ the <c>trace_pattern</c>, lots of the trace data will never be
+ generated and thus not sent over the socket to the trace client
+ and stored in the <c>Collector</c>.</p>
+ </section>
+
+ <section>
+ <title>Viewer window</title>
+
+ <p>Almost all functionality available in the <c>et_viewer</c> is
+ also available via shortcuts. Which key that has the same effect
+ as selecting a menu entry is shown enclosed in parentheses. For
+ example pressing the key <c>r</c> is equivalent to selecting the
+ menu entry <c>Viewer->Refresh</c>.</p>
+
+ <p>File menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Clear all events in the Collector</c> - Deletes all
+ <c>Events</c> stored in the <c>Collector</c> and notifies all
+ connected <c>Viewers</c> about this.</p>
+ </item>
+
+ <item>
+ <p><c>Load events to the Collector from file</c> - Loads the
+ <c>Collector</c> with <c>Events</c> from a file and notifies
+ all connected <c>Viewers</c> about this.</p>
+ </item>
+
+ <item>
+ <p><c>Save all events in the Collector to file</c> - Saves all
+ <c>Events</c> stored in the <c>Collector</c> to file.</p>
+ </item>
+
+ <item>
+ <p><c>Print setup</c> - Enables editing of printer setting,
+ such as paper and layout.</p>
+ </item>
+
+ <item>
+ <p><c>Print current page</c> - Prints the events on the
+ current page. The page size is dependent of the selected paper
+ type.</p>
+ </item>
+
+ <item>
+ <p><c>Print all pages</c> - Prints all events. The page size
+ is dependent of the selected paper type.</p>
+ </item>
+
+ <item>
+ <p><c>Close this Viewer</c> - Closes this <c>Viewer</c>
+ window, but keeps all other <c>Viewers</c> windows and the
+ <c>Collector</c> process.</p>
+ </item>
+
+ <item>
+ <p><c>Close other Viewers, but this</c> - Keeps this
+ <c>Viewer</c> window and its <c>Collector</c> process, but
+ closes all other <c>Viewers</c> windowsconnected to the same
+ <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Close all Viewers and the Collector</c> - Closes the
+ <c>Collector</c> and all <c>Viewers</c> connected to it.</p>
+ </item>
+ </list>
+
+ <p>Viewer menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>First</c> - Scrolls <c>this</c> viewer to the first
+ <c>Event</c> in the <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Last</c> - Scrolls <c>this</c> viewer to the last
+ <c>Event</c> in the <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Prev</c> - Scrolls <c>this</c> viewer one page
+ backwards.</p>
+ </item>
+
+ <item>
+ <p><c>Next</c> - Scrolls <c>this</c> viewer one page
+ forward.</p>
+ </item>
+
+ <item>
+ <p><c>Refresh</c> - Clears <c>this</c> viewer and re-read its
+ <c>Events</c> from the <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Up</c> - Scrolls a few <c>Events</c> backwards.</p>
+ </item>
+
+ <item>
+ <p><c>Down</c> - Scrolls a few <c>Events</c> forward.</p>
+ </item>
+
+ <item>
+ <p><c>Display all actors.</c> - Reset the settings for hidden
+ and/or highlighted actors.</p>
+ </item>
+ </list>
+
+ <p>Collector menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>First</c> - Scrolls<c>all</c> viewers to the first
+ <c>Event</c> in the <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Last</c> - Scrolls <c>all</c> viewers to the last
+ <c>Event</c> in the <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Prev</c> - Scrolls <c>all</c> viewers one page
+ backwards.</p>
+ </item>
+
+ <item>
+ <p><c>Next</c> - Scrolls <c>all</c> viewers one page
+ forward.</p>
+ </item>
+
+ <item>
+ <p><c>Refresh</c> - Clears <c>all</c> viewers and re-read
+ their <c>Events</c> from the <c>Collector</c>.</p>
+ </item>
+ </list>
+
+ <p>Filters and scaling menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>ActiveFilter (=)</c> - Starts a new <c>Viewer</c> window
+ with the same active filter and scale as the current one.</p>
+ </item>
+
+ <item>
+ <p><c>ActiveFilter (+)</c> - Starts a new <c>Viewer</c> window
+ with the same active filter but a larger scale than the
+ current one.</p>
+ </item>
+
+ <item>
+ <p><c>ActiveFilter (-)</c> - Starts a new <c>Viewer </c>window
+ with the same active filter but a smaller scale than the
+ current one.</p>
+ </item>
+
+ <item>
+ <p><c>all (0)</c> - Starts a new <c>Viewer</c> with the
+ <c>Collector Filter</c> as active filter. It will cause all
+ events in the collector to be viewed.</p>
+ </item>
+
+ <item>
+ <p><c>AnotherFilter (2)</c> - If more filters are inserted
+ into the dictionary, these will turn up here as entries in the
+ <c>Filters</c> menu. The second filter will get the shortcut
+ number 2, the next one number 3 etc. The names are sorted.</p>
+ </item>
+ </list>
+
+ <p>Slider and radio buttons:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Hide From=To</c> - When true, this means that the
+ <c>Viewer</c> will hide all <c>Events</c> where the from-actor
+ equals to its to-actor. These events are sometimes called
+ actions.</p>
+ </item>
+
+ <item>
+ <p><c>Hide (excluded actors)</c> - When true, this means that
+ the <c>Viewer</c> will hide all <c>Events</c> whose actors are
+ marked as excluded. Excluded actors are normally enclosed in
+ round brackets when they are displayed inthe
+ <c>Viewer</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Detail level</c> - This slider controls the resolution
+ of the <c>Viewer</c>. Only <c>Events</c> with a detail level
+ <c>smaller</c> than the selected one (default=100=max) are
+ displayed.</p>
+ </item>
+ </list>
+
+ <p>Other features:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Vertical scroll</c> - Use mouse wheel and up/down arrows
+ to scroll little. Use page up/down and home/end buttons to
+ scroll more.</p>
+ </item>
+
+ <item>
+ <p><c>Display details of an event</c> - Left mouse click on
+ the event label or the arrowand a new <c>Contents Viewer</c>
+ window will pop up, displaying the contents of an
+ <c>Event</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Highlight actor (toggle)</c> - Left mouse click on the
+ actor name tag. The actor name will be enclosed in square
+ brackets <c>[]</c>. When one or more actors are highlighted,
+ only events related to those actors are displayed. All others
+ are hidden.</p>
+ </item>
+
+ <item>
+ <p><c>Exclude actor (toggle)</c> - Right mouse click on the
+ actor name tag. The actor name will be enclosed in round
+ brackets <c>()</c>. When an actor is excluded, all events
+ related to this actor is hidden. If the checkbox <c>Hide
+ (excluded actors)</c> is checked, even the name tags and
+ corresponding vertical line of excluded actors will be
+ hidden.</p>
+ </item>
+
+ <item>
+ <p><c>Move actor</c> - Left mouse button drag and drop on
+ actor name tag. Move the actor by first clicking on the actor
+ name, keeping the button pressed while moving the cursor to a
+ new location and release the button where the actor should be
+ moved to.</p>
+ </item>
+
+ <item>
+ <p><c>Display all actors</c> - Press the 'a' button. Reset the
+ settings for hidden and/or highlighted actors.</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <p>The <c>Event Records</c> in the Ets table are ordered by their
+ timestamp. Which timestamp that should be used is controlled via
+ the <c>event_order</c> parameter. Default is <c>trace_ts</c> which
+ means the time when the trace data was generated. <c>event_ts</c>
+ means the time when the trace data was parsed (transformed into an
+ <c>Event Record</c>).</p>
+ </section>
+
+ <section>
+ <title>Contents viewer window</title>
+
+ <p>File menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Close</c> - Close this window.</p>
+ </item>
+
+ <item>
+ <p><c>Save</c> - Save the contents of this window to file.</p>
+ </item>
+ </list>
+
+ <p>Filters menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>ActiveFilter</c> - Start a new <c>Contents Viewer
+ window</c> with the same active filter.</p>
+ </item>
+
+ <item>
+ <p><c>AnotherFilter (2)</c> - If more filters are inserted
+ into the dictionary, these will turn up here as entries in the
+ <c>Filters</c> menu. The second filter will be number 2, the
+ next one number 3 etc. The names are sorted.</p>
+ </item>
+ </list>
+
+ <p>Hide menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Hide actor in viewer</c> - Known actors are shown as a
+ named vertical bars in the <c>Viewer</c> window. By hiding the
+ actor, its vertical bar will be removed and the <c>Viewer</c>
+ will be refreshed.</p>
+
+ <p><c>Hiding the actor</c> is only useful if the
+ <c>max_actors</c> threshold has been reached, as it then will
+ imply that the "hidden" actor will be displayed as if it were
+ <c>"UNKNOWN"</c>. If the <c>max_actors</c> threshold not have
+ been reached, the actor will re-appear as a vertical bar in
+ the <c>Viewer</c>.</p>
+ </item>
+ <item>
+ <p><c>Show actor in viewer</c> - This implies that the actor
+ will be added as a known actor in the <c>Viewer</c> with its
+ own vertical bar.</p>
+ </item>
+ </list>
+
+ <p>Search menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Forward from this event</c> - Set this event to be the first
+ event in the viewer and change its display mode to be enter
+ forward search mode. The actor of this event (from, to or
+ both) will be added to the list of selected actors.</p>
+ </item>
+
+ <item>
+ <p><c>Reverse from this event</c> - Set this event to be the
+ first <c>Event</c> in the <c>Viewer</c> and change its display
+ mode to be enter reverse search mode. The actor of this
+ <c>Event</c> (from, to or both) will be added to the list of
+ selected actors. Observe, that the <c>Events</c> will be shown
+ in reverse order.</p>
+ </item>
+
+ <item>
+ <p><c>Abort search. Display all</c> - Switch the display mode
+ of the <c>Viewer</c> to show all <c>Events</c> regardless of
+ any ongoing searches. Abort the searches.</p>
+ </item>
+ </list>
+ </section>
+</chapter>
+
diff --git a/lib/et/doc/src/et_examples.xml b/lib/et/doc/src/et_examples.xml
deleted file mode 100644
index 7627b191a1..0000000000
--- a/lib/et/doc/src/et_examples.xml
+++ /dev/null
@@ -1,311 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2002</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Examples</title>
- <prepared>H&aring;kan Mattsson</prepared>
- <responsible>H&aring;kan Mattsson</responsible>
- <docno></docno>
- <approved>H&aring;kan Mattsson</approved>
- <checked></checked>
- <date></date>
- <rev>%VSN%</rev>
- <file>et_examples.xml</file>
- </header>
-
- <section>
- <title>A simulated Mnesia transaction</title>
- <p>The Erlang code for running the simulated Mnesia transaction example
- in the previous chapter is included in the <c>et/examples/et_demo.erl</c> file:
- </p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%sim_trans" type="erl"></codeinclude>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%mgr_actors" type="erl"></codeinclude>
- <p>If you invoke the <c>et_demo:sim_trans()</c> function a viewer
- window will pop up and the sequence trace will be almost the same as
- if the following Mnesia transaction would have been run:</p>
- <p></p>
- <code type="none">
- mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).
- </code>
- <p>And the viewer window will look like:</p>
- <p></p>
- <code type="none"><![CDATA[
- $ erl -pa ../examples
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- 1> et_demo:sim_trans().
- {ok,{table_handle,<0.30.0>,11,trace_ts,#Fun<et_collector.0.83904657>}}
- 2>
- ]]></code>
- <p></p>
- <image file="sim_trans.gif">
- <icaption>A simulated Mnesia transaction which writes one record</icaption>
- </image>
- </section>
-
- <section>
- <title>Some convenient functions used in the Mnesia transaction example</title>
- <p>The <c>module_as_actor</c> filter converts the event-records so
- the module names becomes actors and the invoked functions becomes
- labels. If the information about who the caller was it will be
- displayed as an arrow directed from the caller to the callee. The
- <c>[{message, {caller}}, {return_trace}]</c> options to <c>dbg:tpl/2</c>
- function will imply the necessary information in the Erlang traces.
- Here follows the <c>module_as_actor</c> filter:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%module_as_actor" type="erl"></codeinclude>
- <p>The <c>plain_process_info</c> filter does not alter the event-records.
- It merely ensures that the event not related to processes are skipped:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%plain_process_info" type="erl"></codeinclude>
- <p>The <c>plain_process_info_nolink</c> filter does not alter the
- event-records. It do makes use of the <c>plain_process_info</c> , but
- do also ensure that the process info related to linking and unlinking
- is skipped:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%plain_process_info_nolink" type="erl"></codeinclude>
- <p>In order to simplify the startup of an <c>et_viewer</c> process
- with the filters mentioned above, plus some others (that also are
- found in <c>et/examples/et_demo.erl</c> src/et_collector.erl the
- <c>et_demo:start/0,1</c> functions can be used:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%start" type="erl"></codeinclude>
- <p>A simple one-liner starts the tool:</p>
- <code type="none">
- erl -pa ../examples -s et_demo
- </code>
- <p>The filters are included by the following parameters:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%filters" type="erl"></codeinclude>
- </section>
-
- <section>
- <title>Erlang trace of a Mnesia transaction</title>
- <p>The following piece of code <c>et_demo:trace_mnesia/0</c>
- activates call tracing of both local and external function calls for
- all modules in the Mnesia application. The call traces are configured
- cover all processes (both existing and those that are spawned in the
- future) and include timestamps for trace data. It do also activate
- tracing of process related events for Mnesia's static processes plus
- the calling process (that is your shell). Please, observe that the
- <c>whereis/1</c> call in the following code requires that both the
- traced Mnesia application and the <c>et_viewer</c>is running on the
- same node:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%trace_mnesia" type="erl"></codeinclude>
- <p>The <c>et_demo:live_trans/0</c> function starts the a global
- controller, starts a viewer, starts Mnesia, creates a local table,
- activates tracing (as described above) and registers the shell
- process is as 'my_shell' for clarity. Finally the a simple Mnesia
- transaction that writes a single record is run:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%live_trans" type="erl"></codeinclude>
- <p>Now we run the <c>et_demo:live_trans/0</c> function:</p>
- <p></p>
- <code type="none">
- erl -pa ../examples -s et_demo live_trans
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- 1>
- </code>
- <p>Please, explore the different filters in order to see how the traced
- transaction can be seen from different point of views:</p>
- <p></p>
- <image file="live_trans.gif">
- <icaption>A real Mnesia transaction which writes one record</icaption>
- </image>
- </section>
-
- <section>
- <title>Erlang trace of Megaco startup</title>
- <p>The Event Tracer (ET) tool was initially written in order to
- demonstrate how messages where sent over the Megaco protocol. This
- were back in the old days before the standard bodies of IETF and ITU
- had approved Megaco (also called H.248) as an international
- standard.</p>
- <p>In the Megaco application of Erlang/OTP, the code is carefully
- instrumented with calls to <c>et:report_event/5</c>. For call a detail
- level is set in order to dynamically control the trace level in a
- simple manner.</p>
- <p>The <c>megaco_filter</c> module implements a customized filter
- for Megaco messages. It does also make use of <c>trace_global</c>
- combined with usage of the <c>trace_pattern</c>:</p>
- <p></p>
- <code type="none">
- -module(megaco_filter).
- -export([start/0]).
-
- start() ->
- Options =
- [{event_order, event_ts},
- {scale, 3},
- {max_actors, infinity},
- {trace_pattern, {megaco, max}},
- {trace_global, true},
- {dict_insert, {filter, megaco_filter}, fun filter/1},
- {active_filter, megaco_filter},
- {title, "Megaco tracer - Erlang/OTP"}],
- et_viewer:start(Options).
- </code>
- <p>First we start an Erlang node with the a global collector and
- its viewer. The <c>et_viewer: search for: [] ++ ["gateway_tt"]</c>
- printout is caused by a click on the "gateway_tt" actor name in the
- viewer. It means that only events with that actor will be displayed
- in the viewer.</p>
- <p></p>
- <code type="none">
- erl -sname observer -s megaco_filter
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- (observer@amrod)1> et_viewer: search for: [] ++ ["gateway_tt"]
- </code>
- <p>Secondly we start another Erlang node which we connect the
- observer node, before we start the application that we want to
- trace. In this case we start a Media Gateway Controller that listens
- for both TCP and UDP on the text and binary ports for Megaco:</p>
- <p></p>
- <code type="none">
- erl -sname mgc -pa ../../megaco/examples/simple
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- (mgc@amrod)1> net:ping(observer@amrod).
- pong
- (mgc@amrod)2> megaco:start().
- ok
- (mgc@amrod)3> megaco_simple_mgc:start().
- {ok,[{ok,2944,
- {megaco_receive_handle,{deviceName,"controller"},
- megaco_pretty_text_encoder,
- [],
- megaco_tcp}},
- {ok,2944,
- {megaco_receive_handle,{deviceName,"controller"},
- megaco_pretty_text_encoder,
- [],
- megaco_udp}},
- {ok,2945,
- {megaco_receive_handle,{deviceName,"controller"},
- megaco_binary_encoder,
- [],
- megaco_tcp}},
- {ok,2945,
- {megaco_receive_handle,{deviceName,"controller"},
- megaco_binary_encoder,
- [],
- megaco_udp}}]}
- (mgc@amrod)4>
- </code>
- <p>And finally we start an Erlang node for the Media Gateways and
- connect to the observer node. Each Media Gateway connects to the
- controller and sends an initial Service Change message. The controller
- accepts the gateways and sends a reply to each one using the same
- transport mechanism and message encoding according to the preference
- of each gateway. That is all combinations of TCP/IP transport, UDP/IP
- transport, text encoding and ASN.1 BER encoding:</p>
- <p></p>
- <code type="none">
- erl -sname mg -pa ../../megaco/examples/simple
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- (mg@amrod)1> net:ping(observer@amrod).
- pong
- (mg@amrod)2> megaco_simple_mg:start().
- [{{deviceName,"gateway_tt"},{error,{start_user,megaco_not_started}}},
- {{deviceName,"gateway_tb"},{error,{start_user,megaco_not_started}}},
- {{deviceName,"gateway_ut"},{error,{start_user,megaco_not_started}}},
- {{deviceName,"gateway_ub"},{error,{start_user,megaco_not_started}}}]
- (mg@amrod)3> megaco:start().
- ok
- (mg@amrod)4> megaco_simple_mg:start().
- [{{deviceName,"gateway_tt"},
- {1,
- {ok,[{'ActionReply',0,
- asn1_NOVALUE,
- asn1_NOVALUE,
- [{serviceChangeReply,
- {'ServiceChangeReply',
- [{megaco_term_id,false,["root"]}],
- {serviceChangeResParms,
- {'ServiceChangeResParm',
- {deviceName|...},
- asn1_NOVALUE|...}}}}]}]}}},
- {{deviceName,"gateway_tb"},
- {1,
- {ok,[{'ActionReply',0,
- asn1_NOVALUE,
- asn1_NOVALUE,
- [{serviceChangeReply,
- {'ServiceChangeReply',
- [{megaco_term_id,false,["root"]}],
- {serviceChangeResParms,
- {'ServiceChangeResParm',
- {...}|...}}}}]}]}}},
- {{deviceName,"gateway_ut"},
- {1,
- {ok,[{'ActionReply',0,
- asn1_NOVALUE,
- asn1_NOVALUE,
- [{serviceChangeReply,
- {'ServiceChangeReply',
- [{megaco_term_id,false,["root"]}],
- {serviceChangeResParms,
- {'ServiceChangeResParm',{...}|...}}}}]}]}}},
- {{deviceName,"gateway_ub"},
- {1,
- {ok,[{'ActionReply',0,
- asn1_NOVALUE,
- asn1_NOVALUE,
- [{serviceChangeReply,
- {'ServiceChangeReply',
- [{megaco_term_id,false,["root"]}],
- {serviceChangeResParms,
- {'ServiceChangeResParm'|...}}}}]}]}}}]
- (mg@amrod)5>
- </code>
- <p>The Megaco adopted viewer looks like this, when we have clicked
- on the "gateway_tt" actor name in order to only display the events
- regarding that actor:</p>
- <p></p>
- <image file="megaco_tracer.gif">
- <icaption>The viewer adopted for Megaco</icaption>
- </image>
- <p>A pretty printed Megaco message looks like this:</p>
- <p></p>
- <image file="megaco_filter.gif">
- <icaption>A textual Megaco message</icaption>
- </image>
- <p>And the corresponding internal form for the same Megaco message
- looks like this:</p>
- <p></p>
- <image file="megaco_collector.gif">
- <icaption>The internal form of a Megaco message</icaption>
- </image>
- </section>
-</chapter>
-
diff --git a/lib/et/doc/src/et_examples.xmlsrc b/lib/et/doc/src/et_examples.xmlsrc
new file mode 100644
index 0000000000..7678184515
--- /dev/null
+++ b/lib/et/doc/src/et_examples.xmlsrc
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2002</year><year>2010</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Advanced examples</title>
+ <prepared>H&aring;kan Mattsson</prepared>
+ <responsible>H&aring;kan Mattsson</responsible>
+ <docno></docno>
+ <approved>H&aring;kan Mattsson</approved>
+ <checked></checked>
+ <date></date>
+ <rev>%VSN%</rev>
+ <file>et_examples.xml</file>
+ </header>
+
+ <section>
+ <title>A simulated Mnesia transaction</title>
+ <p>The Erlang code for running the simulated <c>Mnesia</c> transaction
+ example in the previous chapter is included in the
+ <c>et/examples/et_demo.erl</c> file:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%sim_trans" type="erl"></codeinclude>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%mgr_actors" type="erl"></codeinclude>
+
+ <p>If you invoke the <c>et_demo:sim_trans()</c> function, a
+ <c>Viewer</c> window will pop up and the sequence trace will be
+ almost the same as if the following <c>Mnesia</c> transaction
+ would have been run:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).]]></code>
+
+ <p>And the viewer window will look like:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ 1> {ok, Viewer} = et_viewer:start([]).
+ {ok,<0.40.0>;}
+ 2> et_demo:sim_trans().
+ {ok,{table_handle,<0.45.0>,24596,trace_ts,
+ #Fun<et_collector.0.62831470>}}]]></code>
+
+ <p></p>
+
+ <image file="sim_trans.png">
+ <icaption>A simulated <c>Mnesia</c> transaction which writes one
+ record</icaption>
+ </image>
+
+ </section>
+
+ <section>
+ <title>Some convenient functions used in the <c>Mnesia</c> transaction
+ example</title>
+
+ <p>The <c>module_as_actor</c> filter converts the <c>Event
+ Records</c> so the module names becomes actors and the invoked
+ functions becomes labels. If the information about who the caller
+ was it will be displayed as an arrow directed from the caller to
+ the callee. The <c>[{message, {caller}}, {return_trace}]</c>
+ options to <c>dbg:tpl/2</c> function will imply the necessary
+ information in the Erlang traces. Here follows the
+ <c>module_as_actor</c> filter:</p>
+
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%module_as_actor" type="erl"></codeinclude>
+
+ <p>The <c>plain_process_info</c> filter does not alter the
+ <c>Event Records</c>. It merely ensures that the event not
+ related to processes are skipped:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%plain_process_info" type="erl"></codeinclude>
+
+ <p>The <c>plain_process_info_nolink</c> filter does not alter the
+ <c>Event Records</c>. It do makes use of the
+ <c>plain_process_info</c> , but do also ensure that the process
+ info related to linking and unlinking is skipped:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%plain_process_info_nolink" type="erl"></codeinclude>
+
+ <p>In order to simplify the startup of an <c>et_viewer</c> process
+ with the filters mentioned above, plus some others (that also are
+ found in <c>et/examples/et_demo.erl</c> src/et_collector.erl the
+ <c>et_demo:start/0,1</c> functions can be used:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%start" type="erl"></codeinclude>
+
+ <p>A simple one-liner starts the tool:</p>
+
+ <code type="none"><![CDATA[
+ erl -pa ../examples -s et_demo]]></code>
+
+ <p>The filters are included by the following parameters:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%filters" type="erl"></codeinclude>
+
+ </section>
+
+ <section>
+ <title>Erlang trace of a real Mnesia transaction</title>
+
+ <p>The following piece of code <c>et_demo:trace_mnesia/0</c>
+ activates call tracing of both local and external function calls
+ for all modules in the <c>Mnesia</c> application. The call traces
+ are configured cover all processes (both existing and those that
+ are spawned in the future) and include timestamps for trace
+ data. It do also activate tracing of process related events for
+ <c>Mnesia</c>'s static processes plus the calling process (that is
+ your shell). Please, observe that the <c>whereis/1</c> call in the
+ following code requires that both the traced <c>Mnesia</c>
+ application and the <c>et_viewer</c> is running on the same
+ node:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%trace_mnesia" type="erl"></codeinclude>
+
+ <p>The <c>et_demo:live_trans/0</c> function starts the global
+ <c>Collector</c>, starts a <c>Viewer</c>, starts <c>Mnesia</c>,
+ creates a local table, activates tracing (as described above) and
+ registers the shell process is as 'my_shell' for clarity. Finally
+ a simple <c>Mnesia</c> transaction that writes a single record
+ is run:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%live_trans" type="erl"></codeinclude>
+
+ <p>Now we run the <c>et_demo:live_trans/0</c> function:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ erl -pa ../examples
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ 1> et_demo:live_trans().
+ {atomic,ok}]]></code>
+
+ <p>Please, explore the different filters in order to see how the traced
+ transaction can be seen from different point of views:</p>
+
+ <p></p>
+
+ <image file="live_trans.png">
+ <icaption>A real <c>Mnesia</c> transaction which writes one record</icaption>
+ </image>
+
+ </section>
+
+ <section>
+ <title>Erlang trace of Megaco startup</title>
+
+ <p>The <c>Event Tracer (ET)</c> tool was initially written in
+ order to demonstrate how messages where sent over the
+ <c>Megaco</c> protocol. This were back in the old days before the
+ standard bodies of <c>IETF</c> and <c>ITU</c> had approved
+ <c>Megaco</c> (also called <c>H.248</c>) as an international
+ standard.</p>
+
+ <p>In the <c>Megaco</c> application of Erlang/OTP, the code is
+ carefully instrumented with calls to <c>et:trace_me/5</c>. For
+ each call a detail level is given in order to enable dynamic
+ control of the trace level in a simple manner.</p>
+
+ <p>The <c>megaco_filter</c> module implements a customized filter
+ for <c>Megaco</c> messages. It does also make use of
+ <c>trace_global</c> combined with usage of the
+ <c>trace_pattern</c>:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ -module(megaco_filter).
+ -export([start/0]).
+
+ start() ->
+ Options =
+ [{event_order, event_ts},
+ {scale, 3},
+ {max_actors, infinity},
+ {trace_pattern, {megaco, max}},
+ {trace_global, true},
+ {dict_insert, {filter, megaco_filter}, fun filter/1},
+ {active_filter, megaco_filter},
+ {title, "Megaco tracer - Erlang/OTP"}],
+ et_viewer:start(Options).]]></code>
+
+ <p>First we start an Erlang node with a global <c>Collector</c>
+ and its <c>Viewer</c>.</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ erl -sname observer
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ (observer@falco)1> megaco_filter:start().
+ {ok,<0.48.0>}]]></code>
+
+ <p>Secondly we start another Erlang node which we connect the
+ observer node, before we start the application that we want to
+ trace. In this case we start a Media Gateway Controller that
+ listens for both TCP and UDP on the text and binary ports for
+ Megaco:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ erl -sname mgc -pa ../../megaco/examples/simple
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ (mgc@falco)1> net:ping(observer@falco).
+ pong
+ (mgc@falco)2> megaco:start().
+ ok
+ (mgc@falco)3> megaco_simple_mgc:start().
+ {ok,[{ok,2944,
+ {megaco_receive_handle,{deviceName,"controller"},
+ megaco_pretty_text_encoder,[],megaco_tcp,dynamic}},
+ {ok,2944,
+ {megaco_receive_handle,{deviceName,"controller"},
+ megaco_pretty_text_encoder,[],megaco_udp,dynamic}},
+ {ok,2945,
+ {megaco_receive_handle,{deviceName,"controller"},
+ megaco_binary_encoder,[],megaco_tcp,dynamic}},
+ {ok,2945,
+ {megaco_receive_handle,{deviceName,"controller"},
+ megaco_binary_encoder,[],megaco_udp,dynamic}}]}]]></code>
+
+ <p>And finally we start an Erlang node for the Media Gateways and
+ connect to the observer node. Each Media Gateway connects to the
+ controller and sends an initial Service Change message. The
+ controller accepts the gateways and sends a reply to each one
+ using the same transport mechanism and message encoding according
+ to the preference of each gateway. That is all combinations of
+ TCP/IP transport, UDP/IP transport, text encoding and ASN.1 BER
+ encoding:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ (mg@falco)1> net:ping(observer@falco).
+ pong
+ (mg@falco)2> megaco_simple_mg:start().
+ [{{deviceName,"gateway_tt"},
+ {error,{start_user,megaco_not_started}}},
+ {{deviceName,"gateway_tb"},
+ {error,{start_user,megaco_not_started}}},
+ {{deviceName,"gateway_ut"},
+ {error,{start_user,megaco_not_started}}},
+ {{deviceName,"gateway_ub"},
+ {error,{start_user,megaco_not_started}}}]
+ (mg@falco)3> megaco:start().
+ ok
+ (mg@falco)4> megaco_simple_mg:start().
+ [{{deviceName,"gateway_tt"},
+ {1,
+ {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
+ [{serviceChangeReply,
+ {'ServiceChangeReply',
+ [{megaco_term_id,false,["root"]}],
+ {serviceChangeResParms,
+ {'ServiceChangeResParm',
+ {deviceName,"controller"},
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE}}}}]}]}}},
+ {{deviceName,"gateway_tb"},
+ {1,
+ {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
+ [{serviceChangeReply,
+ {'ServiceChangeReply',
+ [{megaco_term_id,false,["root"]}],
+ {serviceChangeResParms,
+ {'ServiceChangeResParm',
+ {deviceName,"controller"},
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE}}}}]}]}}},
+ {{deviceName,"gateway_ut"},
+ {1,
+ {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
+ [{serviceChangeReply,
+ {'ServiceChangeReply',
+ [{megaco_term_id,false,["root"]}],
+ {serviceChangeResParms,
+ {'ServiceChangeResParm',
+ {deviceName,"controller"},
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE}}}}]}]}}},
+ {{deviceName,"gateway_ub"},
+ {1,
+ {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
+ [{serviceChangeReply,
+ {'ServiceChangeReply',
+ [{megaco_term_id,false,["root"]}],
+ {serviceChangeResParms,
+ {'ServiceChangeResParm',
+ {deviceName,"controller"},
+ asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE,...}}}}]}]}}}]]]></code>
+
+ <p>The <c>Megaco</c> adopted viewer looks like this, when we have clicked
+ on the <b>[gateway_tt]</b> actor name in order to only display the events
+ regarding that actor:</p>
+
+ <p></p>
+
+ <image file="megaco_tracer.png">
+ <icaption>The viewer adopted for Megaco</icaption>
+ </image>
+
+ <p>A pretty printed <c>Megaco</c> message looks like this:</p>
+
+ <p></p>
+
+ <image file="megaco_filter.png">
+ <icaption>A textual <c>Megaco</c> message</icaption>
+ </image>
+
+ <p>And the corresponding internal form for the same <c>Megaco</c> message
+ looks like this:</p>
+
+ <p></p>
+
+ <image file="megaco_collector.png">
+ <icaption>The internal form of a <c>Megaco</c> message</icaption>
+ </image>
+
+ </section>
+
+</chapter>
+
diff --git a/lib/et/doc/src/et_intro.xml b/lib/et/doc/src/et_intro.xml
index 8dfa678b11..0c5fb14d55 100644
--- a/lib/et/doc/src/et_intro.xml
+++ b/lib/et/doc/src/et_intro.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Introduction</title>
@@ -31,65 +31,89 @@
<rev>%VSN%</rev>
<file>et_intro.xml</file>
</header>
- <p>The Event Tracer (ET) uses the built-in trace mechanism in Erlang
- and provides tools for collection and graphical viewing of trace
- data.</p>
- <p>The viewed trace data is normally collected from Erlang trace ports
- or files.</p>
+
+ <p>The <c>Event Tracer (ET)</c> uses the built-in trace mechanism in
+ Erlang and provides tools for collection and graphical viewing of
+ trace data.</p>
+
+ <p>The viewed trace data is normally collected from Erlang trace
+ ports or files.</p>
<section>
- <title>Scope and Purpose</title>
- <p>This manual describes the Event Tracer (ET) application, as a component
- of the Erlang/Open Telecom Platform development environment. It
- is assumed that the reader is familiar with the Erlang
- Development Environment, which is described in a separate User's
- Guide.</p>
+ <title>Scope and Purpose</title>'
+
+ <p>This manual describes the <c>Event Tracer (ET)</c> application,
+ as a component of the Erlang/Open Telecom Platform development
+ environment. It is assumed that the reader is familiar with the
+ Erlang Development Environment, which is described in a separate
+ User's Guide.</p>
</section>
<section>
<title>Prerequisites</title>
+
<p>The following prerequisites is required for understanding the
- material in the Event Tracer (ET) User's Guide:</p>
+ material in the <c>Event Tracer (ET)</c> User's Guide:</p>
+
<list type="bulleted">
<item>
- <p>familiarity with the Erlang system and Erlang programming in
- general and the especially the art of Erlang tracing.</p>
+ <p>familiarity with the Erlang system and Erlang programming
+ in general and the especially the art of Erlang tracing.</p>
</item>
</list>
- <p>The application requires Erlang/OTP release R7B or later.</p>
+
+ <p>The application requires Erlang/OTP release R13BB or later. If
+ you use the old <c>GS</c> based GUI it does suffice with R7B.</p>
+
</section>
<section>
<title>About This Manual</title>
- <p>In addition to this introductory chapter, the Megaco User's
- Guide contains the following chapters:</p>
+
+ <p>In addition to this introductory chapter, the <c>Event
+ Tracers</c> User's Guide contains the following chapters:</p>
+
<list type="bulleted">
<item>
- <p>Chapter 2: "Usage" describes the architecture
- and typical usage of the application.</p>
+ <p>Chapter 2: "Tutorial" provides a walk-through of the
+ various parts of the application. The tutorial is based on
+ <c>Jayson Vantuyl's</c> article
+ <c>http://souja.net/2009/04/making-sense-of-erlangs-event-tracer.html</c>.</p>
+ </item>
+
+ <item>
+ <p>Chapter 3: "Description" describes the architecture and typical
+ usage of the application.</p>
</item>
+
<item>
- <p>Chapter 3: "Examples" gives some usage examples</p>
+ <p>Chapter 4: "Advanced examples" gives some usage examples</p>
</item>
</list>
+
</section>
<section>
<title>Where to Find More Information</title>
+
<p>Refer to the following documentation for more information about
- Event Tracer (ET) and about the Erlang/OTP development system:</p>
+ <c>Event Tracer (ET)</c> and about the Erlang/OTP development system:</p>
+
<list type="bulleted">
<item>
<p>the Reference Manual of the <c>Event Tracer (ET)</c>.</p>
</item>
+
<item>
- <p>documentation of basic tracing in <c>erlang:trace/4</c> and
- <c>erlang:trace_pattern/3</c> and then the utilities derived from
- these: <c>dbg</c>, <c>observer</c> and <c>et</c>.</p>
+ <p>documentation of basic tracing in <c>erlang:trace/4</c> and
+ <c>erlang:trace_pattern/3</c> and then the utilities derived
+ from these: <c>dbg</c>, <c>observer</c>, <c>invisio</c> and
+ <c>et</c>.</p>
</item>
+
<item>
- <p>Concurrent Programming in Erlang, 2nd Edition (1996),
- Prentice-Hall, ISBN 0-13-508301-X.</p>
+ <p>Programming Erlang: Software for a Concurrent World by Joe
+ Armstrong; ISBN: 978-1-93435-600-5</p>
</item>
</list>
</section>
diff --git a/lib/et/doc/src/et_selector.xml b/lib/et/doc/src/et_selector.xml
index 59b1d3dea9..3e5b030e7a 100644
--- a/lib/et/doc/src/et_selector.xml
+++ b/lib/et/doc/src/et_selector.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>et_selector</title>
@@ -35,72 +35,112 @@
<description>
<p></p>
</description>
+
<funcs>
<func>
<name>make_pattern(RawPattern) -> TracePattern</name>
<fsummary>Makes a trace pattern suitable to feed change_pattern/1</fsummary>
+
<type>
<v>RawPattern = detail_level()</v>
<v>TracePattern = erlang_trace_pattern_match_spec()</v>
<v>detail_level() = min | max | integer(X) when X =&lt; 0, X >= 100</v>
</type>
+
<desc>
<p>Makes a trace pattern suitable to feed change_pattern/1</p>
- <p>Min detail level deactivates tracing of calls to phone_home/4,5</p>
- <p>Max detail level activates tracing of all calls to phone_home/4,5</p>
+ <p>Min detail level deactivates tracing of calls to <c>et:trace_me/4,5</c></p>
+ <p>Max detail level activates tracing of all calls to <c>et:trace_me/4,5</c></p>
<p>integer(X) detail level activates tracing of all calls to
- phone_home/4,5 whose detail level argument is lesser than X.</p>
- <p>See also erlang:trace_pattern/2 for more info about its match_spec()</p>
+ <c>et:trace_me/4,5</c> whose detail level argument is lesser than
+ X.</p>
+ <p>See also <c>erlang:trace_pattern/2</c> for more info about its <c>match_spec()</c></p>
</desc>
</func>
+
<func>
<name>change_pattern(Pattern) -> ok</name>
+
<fsummary>Activates/deactivates tracing by changing the current trace pattern</fsummary>
+
<type>
<v>Pattern = detail_level() | empty_match_spec() | erlang_trace_pattern_match_spec()</v>
<v>detail_level() = min | max | integer(X) when X =&lt;0, X >= 100</v>
<v>empty_match_spec() = [] </v>
</type>
+
<desc>
<p>Activates/deactivates tracing by changing the current trace pattern.</p>
- <p>Min detail level deactivates tracing of calls to phone_home/4,5</p>
- <p>Max detail level activates tracing of all calls to phone_home/4,5</p>
- <p>integer(X) detail level activates tracing of all calls to
- phone_home/4,5 whose detail level argument is lesser than X.</p>
- <p>An empty match spec deactivates tracing of calls to phone_home/4,5</p>
- <p>Other match specs activates tracing of calls to phone_home/4,5
- accordingly with erlang:trace_pattern/2.</p>
+ <p><c>min</c> detail level deactivates tracing of calls to <c>et:trace_me/4,5</c></p>
+ <p><c>max</c> detail level activates tracing of all calls to <c>et:trace_me/4,5</c></p>
+ <p><c>integer(X)</c> detail level activates tracing of all
+ calls to <c>et:trace_me/4,5</c> whose detail level argument is
+ lesser than <c>X</c>.</p>
+ <p>An empty match spec deactivates tracing of calls to <c>et:trace_me/4,5</c></p>
+ <p>Other match specs activates tracing of calls to
+ <c>et:trace_me/4,5</c> accordingly with
+ <c>erlang:trace_pattern/2</c>.</p>
</desc>
</func>
<func>
<name>parse_event(Mod, ValidTraceData) -> false | true | {true, Event}</name>
+
<fsummary>Transforms trace data and makes an event record out of it</fsummary>
+
<type>
<v>Mod = module_name() | undefined &lt;v>module_name() = atom() &lt;v>ValidTraceData = erlang_trace_data() | record(event)</v>
<v>erlang_trace_data() = {trace, Pid, Label, Info} | {trace, Pid, Label, Info, Extra} | {trace_ts, Pid, Label, Info, ReportedTS} | {trace_ts, Pid, Label, Info, Extra, ReportedTS} | {seq_trace, Label, Info} | {seq_trace, Label, Info, ReportedTS} | {drop, NumberOfDroppedItems}</v>
</type>
+
<desc>
<p>Transforms trace data and makes an event record out of it.</p>
- <p>See erlang:trace/3 for more info about the semantics of
- the trace data.</p>
- <p>An event record consists of the following fields:
- detail_level - Noise has a high level as opposed to essentials.
- trace_ts - Time when the trace was generated.
- Same as event_ts if omitted in trace data.
- event_ts - Time when the event record was created.
- from - From actor, such as sender of a message.
- to - To actor, such as receiver of message.
- label - Label intended to provide a brief event summary.
- contents - All nitty gritty details of the event.</p>
- <p>See et:phone_home/4 and et:phone_home/5 for details.</p>
- <p>Returns:
- {true, Event} - where Event is an #event{} record representing the
- trace data
- true - means that the trace data already is an event
- record and that it is valid as it is.
- No transformation is needed.
- false - means that the trace data is uninteresting and
- should be dropped</p>
+
+ <p>See <c>erlang:trace/3</c> for more info about the semantics of the
+ trace data.</p>
+
+ <p>An event record consists of the following fields:</p>
+ <taglist>
+ <tag><em>detail_level</em></tag>
+ <item><p>Noise has a high level as opposed to essentials.</p></item>
+
+
+ <tag><em>trace_ts</em></tag>
+ <item><p>Time when the trace was generated. Same as
+ event_ts if omitted in trace data.</p></item>
+
+ <tag><em>event_ts</em></tag>
+ <item><p>Time when the event record was created.</p></item>
+
+ <tag><em>from</em></tag>
+ <item><p>From actor, such as sender of a message.</p></item>
+
+ <tag><em>to</em></tag>
+ <item><p>To actor, such as receiver of message.</p></item>
+
+ <tag><em>label</em></tag>
+ <item><p>Label intended to provide a brief event summary.</p></item>
+
+ <tag><em>contents</em></tag>
+ <item><p>All nitty gritty details of the event.</p></item>
+ </taglist>
+
+ <p>See <c>et:trace_me/4</c>and <c>et:trace_me/5</c> for details.</p>
+
+ <p>Returns:</p>
+ <taglist>
+ <tag><em>{true, Event}</em></tag>
+ <item><p>where Event is an #event{} record representing the
+ trace data</p></item>
+
+ <tag><em>true</em></tag>
+ <item><p>means that the trace data already is an event
+ record and that it is valid as it is. No transformation is
+ needed.</p></item>
+
+ <tag><em>false</em></tag>
+ <item><p>means that the trace data is uninteresting and
+ should be dropped</p></item>
+ </taglist>
</desc>
</func>
</funcs>
diff --git a/lib/et/doc/src/et_tutorial.xmlsrc b/lib/et/doc/src/et_tutorial.xmlsrc
new file mode 100644
index 0000000000..5c2a5a97e4
--- /dev/null
+++ b/lib/et/doc/src/et_tutorial.xmlsrc
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2009</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Tutorial</title>
+ <prepared>H&aring;kan Mattsson</prepared>
+ <responsible>H&aring;kan Mattsson</responsible>
+ <docno></docno>
+ <approved>H&aring;kan Mattsson</approved>
+ <checked></checked>
+ <date></date>
+ <rev>%VSN%</rev>
+ </header>
+
+ <section>
+ <title>Visualizing Message Sequence Charts</title>
+
+ <p>The easiest way of using <c>ET</c>, is to just use it as a
+ graphical tool for displaying message sequence charts. In order to
+ do that you need to first start a <c>Viewer</c> (which by default
+ starts a <c>Collector</c>):</p>
+
+ <code type="none"><![CDATA[
+ {ok, ViewerPid} = et_viewer:start([{title,"Coffee Order"}]),
+ CollectorPid = et_viewer:get_collector_pid(ViewerPid).]]></code>
+
+ <marker id="report_event"></marker>
+ <p>Then you send events to the <c>Collector</c>
+ with the function <c>et_collector:report_event/6</c> like this:</p>
+
+ <code type="none"><![CDATA[
+ et_collector:report_event(CollectorPid,85,from,to,message,extra_stuff).]]></code>
+
+ <p>The <c>Viewer</c> will automatically pull events from the
+ <c>Collector</c> and display them on the screen.</p>
+
+ <p>The number (in this case 85) is an integer from 1 to 100 that
+ specifies the "detail level" of the message. The higher the
+ number, the more important it is. This provides a crude form of
+ priority filtering. Avoid using 100.</p>
+
+ <p>The <c>from</c>, <c>to</c>, and <c>message</c> parameters are
+ exactly what they sound like. <c>from</c> and <c>to</c> are
+ visualized in the <c>Viewer</c> as "lifelines", with the message
+ passing from one to the other. If <c>from</c> and <c>to</c> are
+ the same value, then it is displayed next to the lifeline as an
+ "action". The <c>extra_stuff </c>value is simply data that you can
+ attach that will be displayed when someone actually clicks on the
+ action or message in the <c>Viewer</c> window.</p>
+
+ <p>The module <c>et/examples/et_display_demo.erl</c> illustrates
+ how it can be used:</p>
+
+ <codeinclude file="../../examples/et_display_demo.erl" tag="%module" type="erl"></codeinclude>
+
+ <p>When you run the <c>et_display_demo:test().</c> function in the
+ example above, the <c>Viewer</c> window will look like this:</p>.
+
+ <p></p>
+
+ <image file="coffee_order.png">
+ <icaption>Screenshot of the <c>Viewer</c> window</icaption>
+ </image>
+
+ </section>
+
+ <section>
+ <title>Four Modules</title>
+
+ <p>The event tracer framework is made up of four modules:</p>
+
+ <list type="bulleted">
+ <item><p><c>et</c></p></item>
+ <item><p><c>et_collector</c></p></item>
+ <item><p><c>et_viewer</c></p></item>
+ <item><p><c>et_selector</c></p></item>
+ </list>
+
+ <p>In addition, you'll probably want to familiarize yourself with
+ the <c>dbg</c> module and possibly <c>seq_trace</c> module as
+ well.</p>
+ </section>
+
+ <section>
+ <title>The Event Tracer Interface</title>
+
+ <p>The <c>et</c> module is not like other modules. It contains a
+ function called <c>et:trace_me/5</c>. Which is a function that
+ does not do any useful stuff at all. Its sole purpose is to be a
+ function that is easy to trace. A call to it may be something
+ like:</p>
+
+ <code type="none"><![CDATA[
+ et:trace_me(85,from,to,message,extra_stuff).]]></code>
+
+ <p>The parameters to <c>et:trace_me/5</c> are the same as to
+ <seealso
+ marker="#report_event"><c>et_collector:report_event/6</c></seealso>
+ in the previous chapter. The big difference between the two is in
+ the semantics of the two functions. The second actually reports an
+ <c>Event</c> to the <c>Collector</c> while the first does nothing,
+ it just returns the atom <c>hopefully_traced</c>. In order to make
+ the parameters to <c>et:trace_me/5</c> turn up in the
+ <c>Collector</c>, tracing of that function must be activated and
+ the <c>Collector</c> must be registered as a <c>Tracer</c> of the
+ <c>Raw Trace Data</c>.</p>
+
+ <p>Erlang tracing is a seething pile of pain that involves
+ reasonably complex knowledge of clever ports, tracing return
+ formats, and specialized tracing <c>MatchSpecs</c> (which are
+ really their own special kind of hell). The tracing mechanism is
+ very powerful indeed, but it can be hard to grasp.</p>
+
+ <p>Luckily there is a simplified way to start tracing of
+ <c>et:trace_me/5</c> function calls. The idea is that you should
+ instrument your code with calls to <c>et:trace_me/5</c> in
+ strategic places where you have interesting information available
+ in your program. Then you just start the <c>Collector</c> with
+ global tracing enabled:</p>
+
+ <code type="none"><![CDATA[
+ et_viewer:start([{trace_global, true}, {trace_pattern, {et,max}}]).]]></code>
+
+ <p>This will start a <c>Collector</c>, a <c>Viewer</c> and also
+ start the tracing of <c>et:trace_me/5</c> function calls. The
+ <c>Raw Trace Data</c> is collected by the <c>Collector</c> and a
+ view of it is displayed on the screen by the <c>Viewer</c>. You
+ can define your own "views" of the data by implementing your own
+ <c>Filter</c> functions and register them in the
+ <c>Viewer</c>.</p>
+ </section>
+
+ <section>
+ <title>The Collector and Viewer</title>
+
+ <p>These two pieces work in concert. Basically, the
+ <c>Collector</c> receives <c>Raw Trace Data</c> and processes it
+ into <c>Events</c> in a <c>et</c> specific format (defined in
+ <c>et/include/et.hrl</c>). The <c>Viewer</c> interrogates the
+ <c>Collector</c> and displays an interactive representation of the
+ data.</p>
+
+ <p>You might wonder why these aren't just one module. The
+ <c>Collector</c> is a generic full-fledged framework that allows
+ processes to "subscribe" to the <c>Events</c> that it
+ collects. One <c>Collector</c> can serve several
+ <c>Viewers</c>. The typical case is that you have one
+ <c>Viewer</c> that visualizes <c>Events</c> in one flavor and
+ another <c>Viewer</c> that visualizes them in another flavor. If
+ you for example are tracing a text based protocol like <c>HTML</c>
+ (or <c>Megaco/H.248</c>) it would be useful to be able to display
+ the <c>Events</c> as plain text as well as the internal
+ representation of the message. The architecture does also allow
+ you to implement your own <c>Viewer</c> program as long as it
+ complies to the protocol between the <c>Collector/Viewer</c>
+ protocol. Currently two kinds of <c>Viewers</c> exists. That is
+ the old <c>GS</c> based one and the new based on
+ <c>wxWidgets</c>. But if you feel for it you may implement your
+ own <c>Viewer</c>, which for example could display the
+ <c>Events</c> as ASCII art or whatever you feel useful.</p>
+
+ <p>The <c>Viewer</c> will by default create a <c>Collector</c> for
+ you. With a few options and some configuration settings you can
+ start collecting <c>Events</c>.</p>
+
+ <p>The <c>Collector</c> API does also allow you to save the
+ collected <c>Events</c> to file and later load them in a later
+ session.</p>
+
+ </section>
+
+ <section>
+ <title>The Selector</title>
+
+ <p>This is perhaps the most central module in the entirety of the
+ <c>et</c> suite. The <c>Collector</c> needs "filters" to convert
+ the <c>Raw Trace Data</c> into "events" that it can display. The
+ <c>et_selector</c> module provides the default <c>Filter</c> and
+ some API calls to manage the <c>Trace Pattern</c>. The
+ <c>Selector</c> provides various functions that achieve the
+ following:</p>
+
+ <list type="bulleted">
+ <item><p>Convert <c>Raw Trace Data</c> into an appropriate
+ <c>Event</c></p></item>
+ <item><p>Magically notice traces of the <c>et:trace_me/5</c>
+ function and make appropriate <c>Events</c></p></item>
+ <item><p>Carefully prevent translating the <c>Raw Trace Data</c>
+ twice</p></item>
+ <item><p>Manage a <c>Trace Pattern</c></p></item>
+ </list>
+
+ <p>The <c>Trace Pattern</c> is basically a tuple of a
+ <c>module</c> and a <c>detail level</c> (either an integer or the
+ atom max for full detail). In most cases the <c>Trace Pattern</c>
+ <c>{et,max}</c> does suffice. But if you do not want any runtime
+ dependency of <c>et</c> you can implement your own
+ <c>trace_me/5</c> function in some module and refer to that module
+ in the <c>Trace Pattern</c>.</p>
+
+ <p>The specified module flows from your instantiation of the
+ <c>Viewer</c>, to the <c>Collector</c> that it automatically
+ creates, gets stashed in as the <c>Trace Pattern</c>, and
+ eventually goes down into the bowels of the <c>Selector</c>.</p>
+
+ <p>The module that you specify gets passed down (eventually) into
+ <c>Selector</c>'s default <c>Filter</c>. The format of the
+ <c>et:trace_me/5</c> function call is hardcoded in that
+ <c>Filter</c>.</p>
+
+ </section>
+
+ <section>
+ <title>How To Put It Together</title>
+
+ <p>The <c>Collector</c> automatically registers itself to listen
+ for trace <c>Events</c>, so all you have to do is enable them.</p>
+
+ <p>For those people who want to do general tracing, consult the
+ <c>dbg</c> module on how to trace whatever you're interested in
+ and let it work its magic. If you just want <c>et:trace_me/5</c>
+ to work, do the following:</p>
+
+ <list type="ordered">
+ <item><p>Create a <c>Collector</c></p></item>
+ <item><p>Create a <c>Viewer</c> (this can do step #1 for you)</p></item>
+ <item><p>Turn on and pare down debugging</p></item>
+ </list>
+
+ <p>The module <c>et/examples/et_trace_demo.erl</c> achieves this.</p>
+
+ <codeinclude file="../../examples/et_trace_demo.erl" tag="%module" type="erl"></codeinclude>
+
+ <p>Running through the above, the most important points are:</p>
+
+ <list type="bulleted">
+ <item><p>Turn on global tracing</p></item>
+ <item><p>Set a <c>Trace Pattern</c></p></item>
+ <item><p>Tell <c>dbg</c> to trace function Calls</p></item>
+ <item><p>Tell it specifically to trace the <c>et:trace_me/5</c> function</p></item>
+ </list>
+
+ <p>When you run the <c>et_trace_demo:test()</c> function above, the
+ <c>Viewer</c> window will look like this screenshot:</p>.
+
+ <p></p>
+
+ <image file="coffee_order.png">
+ <icaption>Screenshot of the <c>Viewer</c> window</icaption>
+ </image>
+
+ </section>
+
+</chapter>
diff --git a/lib/et/doc/src/et_viewer.xml b/lib/et/doc/src/et_viewer.xml
index a3e34ac06e..c16e5b8869 100644
--- a/lib/et/doc/src/et_viewer.xml
+++ b/lib/et/doc/src/et_viewer.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>et_viewer</title>
@@ -72,7 +72,7 @@
<fsummary>Start a sequence chart viewer for trace events (messages/actions)</fsummary>
<type>
<v>Options = [option() | collector_option()]</v>
- <v>option() = {parent_pid, extended_pid()} | {title, term()} | {detail_level, detail_level()} | {is_suspended, boolean()} | {scale, integer()} | {width, integer()} | {height, integer()} | {collector_pid, extended_pid()} | {event_order, event_order()} | {active_filter, atom()} | {max_events, extended_integer()} | {max_actors, extended_integer()} | {trace_pattern, et_collector_trace_pattern()} | {trace_port, et_collector_trace_port()} | {trace_global, et_collector_trace_global()} | {trace_client, et_collector_trace_client()} | {dict_insert, {filter, filter_name()}, event_filter_fun()} | {dict_insert, et_collector_dict_key(), et_collector_dict_val()} | {dict_delete, {filter, filter_name()}} | {dict_delete, et_collector_dict_key()} | {actors, actors()} | {first_event, first_key()} | {hide_unknown, boolean()} | {hide_actions, boolean()} | {display_mode, display_mode()}</v>
+ <v>option() = {parent_pid, extended_pid()} | {title, term()} | {detail_level, detail_level()} | {is_suspended, boolean()} | {scale, integer()} | {width, integer()} | {height, integer()} | {collector_pid, extended_pid()} | {event_order, event_order()} | {active_filter, atom()} | {max_actors, extended_integer()} | {trace_pattern, et_collector_trace_pattern()} | {trace_port, et_collector_trace_port()} | {trace_global, et_collector_trace_global()} | {trace_client, et_collector_trace_client()} | {dict_insert, {filter, filter_name()}, event_filter_fun()} | {dict_insert, et_collector_dict_key(), et_collector_dict_val()} | {dict_delete, {filter, filter_name()}} | {dict_delete, et_collector_dict_key()} | {actors, actors()} | {first_event, first_key()} | {hide_unknown, boolean()} | {hide_actions, boolean()} | {display_mode, display_mode()}</v>
<v>extended_pid() = pid() | undefined</v>
<v>detail_level() = min | max | integer(X) when X >=0, X =&lt; 100</v>
<v>event_order() = trace_ts | event_ts</v>
@@ -113,7 +113,6 @@
<item>collector_pid - undefined.</item>
<item>event_order - trace_ts.</item>
<item>active_filter - collector.</item>
- <item>max_events - 100.</item>
<item>max_actors - 5.</item>
<item>actors - ["UNKNOWN"].</item>
<item>first_event - first.</item>
diff --git a/lib/et/doc/src/files.mk b/lib/et/doc/src/files.mk
index 13d6cf4d74..41964de892 100644
--- a/lib/et/doc/src/files.mk
+++ b/lib/et/doc/src/files.mk
@@ -1,19 +1,19 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
XML_APPLICATION_FILES = \
@@ -31,27 +31,23 @@ XML_PART_FILES = \
XML_CHAPTER_FILES = \
et_intro.xml \
- et_architecture.xml \
+ et_tutorial.xml \
+ et_desc.xml \
et_examples.xml \
notes.xml
BOOK_FILES = book.xml
-GIF_FILES = \
- book.gif \
- live_trans.gif \
- megaco_collector.gif \
- megaco_filter.gif \
- megaco_tracer.gif \
- note.gif \
- notes.gif \
- ref_man.gif \
- sim_trans.gif \
- sim_trans_contents_viewer_collector.gif \
- sim_trans_contents_viewer_mgr_actors.gif \
- sim_trans_mgr_actors.gif \
- sim_trans_move_actor.gif \
- sim_trans_write_lock.gif \
- user_guide.gif \
- warning.gif
+IMAGE_FILES = \
+ coffee_order.png \
+ live_trans.png \
+ megaco_collector.png \
+ megaco_filter.png \
+ megaco_tracer.png \
+ sim_trans.png \
+ sim_trans_contents_viewer_collector.png \
+ sim_trans_contents_viewer_mgr_actors.png \
+ sim_trans_mgr_actors.png \
+ sim_trans_move_actor.png \
+ sim_trans_write_lock.png
diff --git a/lib/et/doc/src/live_trans.gif b/lib/et/doc/src/live_trans.gif
deleted file mode 100644
index e2070f89e9..0000000000
--- a/lib/et/doc/src/live_trans.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/live_trans.png b/lib/et/doc/src/live_trans.png
new file mode 100644
index 0000000000..94192697d2
--- /dev/null
+++ b/lib/et/doc/src/live_trans.png
Binary files differ
diff --git a/lib/et/doc/src/live_trans.ps b/lib/et/doc/src/live_trans.ps
deleted file mode 100644
index 8855f2694b..0000000000
--- a/lib/et/doc/src/live_trans.ps
+++ /dev/null
@@ -1,1559 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/live_trans.ps
-%%CreationDate: Mon Oct 14 17:29:47 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 429 326
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 310.991634 translate
-414.655512 -310.991634 scale
-% Image geometry
-496 372 8
-% Transformation matrix
-[ 496 0 0 372 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 496 string def
-/gstr 496 string def
-/bstr 496 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 85402 ASCII Bytes
-colorimage
-!AQV60nB=U!.b->!<4eQ3Ih~>
-r'Z)9JH16$RfN@SJ,~>
-"DW"!C3+q+JH16$RfEJ1CAr:)~>
-r]0uYnc&U&JcC<$JcFp5!56GQrr<*\0faa~>
-r^?bdnc&U'JcC<$JcFp5!5?MRrrE$dJ,~>
-rcA)>nc&U&JcC<$JcFp5!56GQrrE%>J,~>
-s"OQTs8VWG!53s6J^o>%kLBRGa56ja!WY5@J,~>
-s$Qngs8VWC!5=$8J_#D'kLKXIa4gR]!WYVVJ,~>
-s)S5As8VWG!53s6J^o>%kLBRGa56ja!W[:_J,~>
-!]^8\n(n&XJ^o>%J^rr6!56A.!lY-oJ,~>
-!^m%gn(IcUJ_#D'J_'#8!5?G+!l=q*J,~>
-!cnAAn(n&XJ^o>%J^rr6!56A.!lY.\J,~>
-!\j]Tn(n&XT%*h[J^s#8!6'N>jOF7D`SL[8!&9!~>
-!^m%gn(IcUT%3qbdXg!7ecEqAdanHHQIZ&M`S(C1!(;>~>
-!cnAAn(n&XT%*h[J^s#8!6'N>jOF7D`SL[8!-<Y~>
-!<E/fh>k7Cec1lXeHNpfe\-<VrfmH5!J>a8eH(S\^t&ILpXKAZH[D":eHLSPe^]nKpXK:sHi;Iq
-UqN;K!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/fg&Sk@f)LlVedTEhf"Q]`R?<W_eq&Cgf)LTBf)Lm,ecWX;I@9*Gs+14$s,m',s+1."!MR5t
-ec<GIg@q$.gAdT>gAdT=g&\>VJ,~>
-!<E/fh>k7Cec1lXeHNpfe\-<VrfmH5!J>a8eH(S\^t&ILpXKAZH[D":eHLSPe^]nKpXK:sHi;Iq
-UqN;K!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/thZ',ChZ',Eh>k7dec0srMuM6.UjIaYec1m+eH*Y&gsm"UHaM=]Hc=O"Ph"<:He$Zc]uAM&
-K6tDas-39.!fMEEiRJ*aHe$Z2PkW]/K7!RI!jm<nS^d_RkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/tf)M08f)M0:ec<G]df4^qNW.?-Tm_XZdf5I%dK.4ngsQeOJ[X!dIE'QpOj_[/J^Vu`[`-\p
-J\]_6On[9+NIAglimRjXs3gq0pX9(mrR(bUID29#!5@XIpR1a+rL*]:rL*W8!NlEQ~>
-!<E/thZ',ChZ',Eh>k7dec0srMuM6.UjIaYec1m+eH*Y&gsm"UHaM=]Hc=O"Ph"<:He$Zc]uAM&
-K6tDas-39.!fMEEiRJ*aHe$Z2PkW]/K7!RI!jm<nS^d_RkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/uhYiuChYiuDh>k7dec'n!c.1?sH\:&&!J>aSeHLkqe^];!qpbk&He$Z!Hc=M9K6suU!J>aW
-eH(;Lo@3koHi2CpP`)*_!57RPpRLs6pRM3=!NZ9O~>
-!<E/uf);$8f);$9ec<G]df+Xub0n^lI>-D's+/tR"c8MmdXcuHdf4mudf4m;df4m*df4mVdf4mi
-df4mrdK,ViS^IMPkLTBqp=Au+rRM"P!.Y~>
-!<E/uhYiuChYiuDh>k7dec'n!c.1?sH\:&&!J>aSeHLkqe^];!qpbk&He$Z!Hc=M9K6suU!J>aW
-eH(;Lo@3koHi2CpP`)*_!57RPpRLs6pRM3=!NZ9O~>
-!<E/uhY`oDhY`oCh>k7deL>itHaM>BH\6t$eVf@!K6suUe]!GnK='1Z`J](iK>#ffHe$*"H[C[i
-r7(eCrd,^*Mi4Zp`KY^rMoF5sXG_FPMp9ekMgL)`e^]S9XGd&-"MK/qeXZVc#gJ!Ke^];!eYN1k
-s2>D)H\8]UeVf?eMq*H,qpk_)*PI)P[+3-[H[C[ie^]S9]n:[=["E_4e^_WsH\8^)eHDChK6qt?
-ec1O<["F:]e^]S9XGbW1MgLA`rm_pgMgKf/c.0dkH\8]Ue]!GnH\9#^`J](iK>%*2$\NfVeVf@!
-K6suUSGmj=c)chMMlc['s,.5tK6suUeZ=[UMlcp.)2!:deUr5!eVf@!K6suUeUr5!c$QPB]mIGa
-eH!;GhY3Q5hYE]>h>s\XJ,~>
-!<E/uf)1s9f)1s8ec<G]dOBTuIBq;<JUrO'dZ'6tKn6PXd__,pKsK.T_NBCtKsoE\J^VQ#JUNNl
-r6bS=rd>j)NK'co`fYh#NP<ihY).RTM9=8`OaVqhdaF,7V2bH%"M0#md[C)_#g.^LdaE\td\6Yg
-s2#2,I>+uTdZ'6_NREB/qpPM(*P-rUZI6aTJUNNldaF,7[Y9:8[Y9:<daH!pI>,!+dKH+lJUN+E
-df5:;[Xj:TdaF,7V2`p+M1(5`rmD^fM1'f/b0n.hI>+uTd__,tI>,,X_NBCtKspg*s+13us,@2n
-Kn6PXRJqU<b-$SLM6?U$s,@AsKn6PXd]SFTM6?j+s+13us+13us,@Q#Kn6PXdXcttb(6S@[XG`Y
-dK%#Ef(YU*f(ka3ecDoRJ,~>
-!<E/uhY`oDhY`oCh>k7deL>itHaM>BH\6t$eVf@!K6suUe]!GnK='1Z`J](iK>#ffHe$*"H[C[i
-r7(eCrd,^*Mi4Zp`KY^rMoF5sXG_FPMp9ekMgL)`e^]S9XGd&-"MK/qeXZVc#gJ!Ke^];!eYN1k
-s2>D)H\8]UeVf?eMq*H,qpk_)*PI)P[+3-[H[C[ie^]S9]n:[=["E_4e^_WsH\8^)eHDChK6qt?
-ec1O<["F:]e^]S9XGbW1MgLA`rm_pgMgKf/c.0dkH\8]Ue]!GnH\9#^`J](iK>%*2$\NfVeVf@!
-K6suUSGmj=c)chMMlc['s,.5tK6suUeZ=[UMlcp.)2!:deUr5!eVf@!K6suUeUr5!c$QPB]mIGa
-eH!;GhY3Q5hYE]>h>s\XJ,~>
-!<E/teb>U4eH!;[bpe"0H^)dNP_4V5c%CA$S9on5`IifVP^CBoMgMhE[(X_:Hd07*]sN-Er66G)
-H[EHNK6rNP]r\oSH]-.EH],8<UrC<*K>!Lr`Qa$^Mkp<r,+O#!c,G$V^!21Vc-:lfc,G$V]u>VV
-]p*l_c%CA$Us4gMqopL@H]+D@K?_*2]sN-Ec-:lfMk#-@Mk#-Hc,G<f]p*l_c(o]^]mG,$bqF]r
-Pa$NZc-:lfMkmG$PeE<.XNdPfMmTje`PmI^]p*l_c&6qU]sPJtMgMhE[(Z:['n^kXc%CA$S9on5
-`HusFXF$2FP^BM,bpe9lMk#-Hc)c8V]p*lFc-:lfc-:lfc-:lfMk#-Hc-:lfc'4.2c,G%"T$78K
-kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/tdeB1.dK%#Yc7+14I?i*SR>$@?c@LD#Tm_X?b(58XQ$pZtM1)hH[_C%<J^2!4^:&HHr6?M+
-JUPD\JUNBO^952YI>Q7GI>P8<WlE24Kt<Ot`m0-`M5C0r,,'G)cGkE`_Tm^`cH^ulcGkE`_T%.\
-\s7]`c@LD#V9XpSqp$R?I>OYGL!IE8^:&HHcH^uhNM1cKNM1cScH:]l\s7]`cCoZ[^4Ck1c7a`s
-Od1?[cH^uhM5@5#Q+iN3Wm7GhM6aRi`l`jd\s7]`cA?tX^:(c$M1)hH[_DR_s+13q&V5@eTm_X?
-`drQTWdU/HQ$o\-c7+<mM4o?OcDl;X^6O,HcH^ulcH^ulcH^uhM4o?OcH^ulcB4+3cGk:+T$@>M
-kL'?uq9f82o[<W)qpGMJ!.Y~>
-!<E/teb>U4eH!;[bpe"0H^)dNP_4V5c%CA$S9on5`IifVP^CBoMgMhE[(X_:Hd07*]sN-Er66G)
-H[EHNK6rNP]r\oSH]-.EH],8<UrC<*K>!Lr`Qa$^Mkp<r,+O#!c,G$V^!21Vc-:lfc,G$V]u>VV
-]p*l_c%CA$Us4gMqopL@H]+D@K?_*2]sN-Ec-:lfMk#-@Mk#-Hc,G<f]p*l_c(o]^]mG,$bqF]r
-Pa$NZc-:lfMkmG$PeE<.XNdPfMmTje`PmI^]p*l_c&6qU]sPJtMgMhE[(Z:['n^kXc%CA$S9on5
-`HusFXF$2FP^BM,bpe9lMk#-Hc)c8V]p*lFc-:lfc-:lfc-:lfMk#-Hc-:lfc'4.2c,G%"T$78K
-kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/sebPa5eH!;[boM/,P^CZ5["F"Uc%CA^c$Of^XF$J^XF%%nMgLu-rlkIrHiD7l`P$nVqoo:s
-Hd0ffHi;1o`P$nVc%CA^rQPYMH^r?^H`YJEHi)%gP^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%n
-K7!=:"bV0@c$Og:boXj;K7hFnK6tS^H[E`VH[F#=H^r?^H`YJEHc=6^Hhbi$K6tk^H\9SfK6tkf
-K6tS^`I!6^K6tT9bmUV"SB\-^XNcZMSA"pH",hMr^%]bdK6tkfK6tS^H[F#^K6tjqHc=7KH\;+<
-,_LH_c$Of^K6tS^`I!6^c%CAfc%CAfc%CA^c$Of^c%CAEHbKF'!IL'&blGH?eGu-8eGu-3ebbm6
-eH)`OJ,~>
-!<E/sdeT=/dK%#Yc5h>0Ob(Z3ZA""Xc@LD`c@LPlY'm"dY'mIuM1(r3rm(OprltV_^4D"8cMrIq
-c2rQFb5TZk_S1STc@p\`rQYbQIA+fdIBLkHIEMK5!L8*4cMrIqcMrIqcMrIqcMrG'cE;Shb-$/q
-c@LDdpW`qnIE'Q`Jc<q9_S1STcH^uhb0GQdb0GQhcE;Shb-$/qc@p\hc@LQAc5(tZb/Sj\cH^uh
-b0Gil`m2SPM9^g'_YqafY'm"dY'mIuM1(r3rltV&I@\7LcMrIqc4PVU`m0-dcH^ulcA?thcGk9h
-ps(.9IE'Q`J^0+#`m2SPM9aCtJ^2PlJ^2PlIE'Q`J^2PlJZaF<rltOmQ(H8$^?<oERJG82RInr)
-RJYD5XoNt~>
-!<E/sebPa5eH!;[boM/,P^CZ5["F"Uc%CA^c$Of^XF$J^XF%%nMgLu-rlkIrHiD7l`P$nVqoo:s
-Hd0ffHi;1o`P$nVc%CA^rQPYMH^r?^H`YJEHi)%gP^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%n
-K7!=:"bV0@c$Og:boXj;K7hFnK6tS^H[E`VH[F#=H^r?^H`YJEHc=6^Hhbi$K6tk^H\9SfK6tkf
-K6tS^`I!6^K6tT9bmUV"SB\-^XNcZMSA"pH",hMr^%]bdK6tkfK6tS^H[F#^K6tjqHc=7KH\;+<
-,_LH_c$Of^K6tS^`I!6^c%CAfc%CAfc%CA^c$Of^c%CAEHbKF'!IL'&blGH?eGu-8eGu-3ebbm6
-eH)`OJ,~>
-!<E/rebbm6eH!;[bn>B!XF$aic%CYnc%CAfc%CAfV#5QOUs6lCH[C[ac%CAf]n:rqH\;4?&;,>S
-c%CAfc+Sa^MgL*$H[G\8!2TO>"/O1oHi)%gP^EDS%tf5Rc%CAfc%CAfc%CAfV#5QAUs4O=p<=M.
-Hd0ffHd06VK8Y)/c-:lfc-:lfc-:lfc(t8a#GfUkHd0ffHhbhpK6tkfH[F#^K6tkfH[Gb:s*Fgl
-H[G\8!2TO>%]%@gP^@b8^!4N\H[C[aq99J'Hd0ffHd0ffHd0ffHd-narltIiprs(sHd0ffHd-na
-rltIis3271Hd0ffHd0ffHd0ffHd0ffH\6[arlkIjPb-,"^&6C\^%n/u^%TtVSGC\8SFtG.SG^n<
-X8mb~>
-!<E/rdefI0dK%#Yc4YQ%Y'm<ub(YPpc@LPlc@LPlV>P`RV9ZrCI=7*hc@LPl\qP]pI>.RDs+13q
-s+13q#eG_@NI?N+I=;%=!2]UA"/X:oJc!^nQ$rYWs+13qs+13qs+13qs+(3rV>P`DV9XXCp<N\h
-s3CXq'[F:DJW5)3cH^ulcH^ulcH^ulcDCGe#Go^oIEp,hJb[OjJcF$qIK.UmJcF!rJUROCs*Xso
-I=;%=!2]UA%].IfQ$n(?^<XT\I=7*hq9K"ks3CXqs3CXqs3CXq!mZ@Frm(Olps/njs3CXq!mZ@F
-rm(Ols3CXqs3CXqs3CXqs3CXqs3:auI>NNprltOmQ(H8$^AQCZ](q`o](XPPRJG82RJ##(RJbJ6
-XoNt~>
-!<E/rebbm6eH!;[bn>B!XF$aic%CYnc%CAfc%CAfV#5QOUs6lCH[C[ac%CAf]n:rqH\;4?&;,>S
-c%CAfc+Sa^MgL*$H[G\8!2TO>"/O1oHi)%gP^EDS%tf5Rc%CAfc%CAfc%CAfV#5QAUs4O=p<=M.
-Hd0ffHd06VK8Y)/c-:lfc-:lfc-:lfc(t8a#GfUkHd0ffHhbhpK6tkfH[F#^K6tkfH[Gb:s*Fgl
-H[G\8!2TO>%]%@gP^@b8^!4N\H[C[aq99J'Hd0ffHd0ffHd0ffHd-narltIiprs(sHd0ffHd-na
-rltIis3271Hd0ffHd0ffHd0ffHd0ffH\6[arlkIjPb-,"^&6C\^%n/u^%TtVSGC\8SFtG.SG^n<
-X8mb~>
-!<E/qebu$7eH!;[bnPN#`Hurrc%CYnc%CAfc%CAfXF$K6bmhXfH\9RqHd.Iqc-:lnqoo_*Hd0ff
-Hd0fnHd0ffK?]$q^&?1WXF$K8blNHDqoonPHc=7SK6tkfK6tkfK6tkfK6tkEH^t#Y!J>amboD@_
-c-:lfc&6qnc%CYnc%CAfc%CAfc%CAfXF$K8blr`H`Q`aVprsS,Hd0NVK?_YnHd0ffHc=7KH\9Rq
-HbKC&!j$a=qTT,]UjIanblbq\H\;.='n^kXc%CAfc%CAfc%CAfK6tS^`I!74bpe9lc-:lfc%CA^
-c,G$^c-:lfc-:lfc-:lfc-:lfc-:lf[!S%^c,G%"T$78Kr71P3p=0/5q:,J8p=8o-rRCqM!.Y~>
-!<E/qdf#U1dK%#Yc4k]'`dN9#c@pttc@LPlc@LPlY'm#?c4.deI>,stJ^07+b0G]pqp,4ms3CXq
-s3:q1J]c8lL!GC#^AZ=YY'm#AcMrImc5*+%`m2k\J^2PlJ^2PlJ^2PlJ^1EHU&<49JbIChJcF$q
-JJQOjJ]c8lL!ItpJ^2PlJ^2PlJ^1EHU&<1>JUP\`JV!UAs+(m0b'euhc@LPlcA?thcGk9hc@p\\
-rQYJIIA-M_"3.$_L&T@"`h@g7q9K"ks3CXqs3CXqs3CXq#L80S`m2SPM>5BrJcF$qJKrHsIE'RP
-I>Q7pJUu+lJUu+lJUu+lJUu+lJUt7XQ-R[pIA*7X!5ABZpR1a'!1EZ2!1EQ/pR2!.!NlEQ~>
-!<E/qebu$7eH!;[bnPN#`Hurrc%CYnc%CAfc%CAfXF$K6bmhXfH\9RqHd.Iqc-:lnqoo_*Hd0ff
-Hd0fnHd0ffK?]$q^&?1WXF$K8blNHDqoonPHc=7SK6tkfK6tkfK6tkfK6tkEH^t#Y!J>amboD@_
-c-:lfc&6qnc%CYnc%CAfc%CAfc%CAfXF$K8blr`H`Q`aVprsS,Hd0NVK?_YnHd0ffHc=7KH\9Rq
-HbKC&!j$a=qTT,]UjIanblbq\H\;.='n^kXc%CAfc%CAfc%CAfK6tS^`I!74bpe9lc-:lfc%CA^
-c,G$^c-:lfc-:lfc-:lfc-:lfc-:lf[!S%^c,G%"T$78Kr71P3p=0/5q:,J8p=8o-rRCqM!.Y~>
-!<E/pec208eH!;[bpn(9c&6qMc%CYnc%CAfc%CAfc%CA=[&gXZUpRhBH]-.$Hd.IqXK6bq^&6+s
-K6suMK6tkfMgMP,H[EH-H\8E5XMrG:H_e$M[*=5Mqop.pHaM&BK6tkfK6tkfK6tkfK6suEK6sE$
-XL-6)HiD7jMhCoO-\Hcjc%CAfMgMP,H[EHNK6tkfK6tkfK6tkfK6sE$XL-6:H^'bAHhbi=K6t;-
-H_ep2K6tkfXF$2FP^BLVXF#T$]r]2tK6sE$XL-6J[(WhnMp8')]sN-Eq99Y,Hd0ffHd0ffHd0ff
-Hd/X=PeE<.XSC$hK6tkfK6tkEH^)4.H`YK:K6tkfK6tkfK6tkfK6tkfK6tk-HaM&)HbH#q!58<\
-pRLs-!1`l8!1`c5rLEo<rLEi:!NZ9O~>
-!<E/pcMs1*c2bTUasqh5b)(PLb(YPlb(5,db(5,d`eAi;[]ZpYTsDD<I>Q*tJ]`gtWiCJq^AQ+q
-M1)hPJUttdM1)D(I=8i0I>+i4Wkuc0IAOBTZH@`LqoTqjIBL`8JUttdJUttdJUttdM1)hLKmff+
-Y-Q3$Jc<glM>PHqJcEmmJK`0mIB';qID3jTJ]c,dJ]c,dJ]budIAOBTZHAG\Q'$KGpr`Vf/\[p,
-TutN/J]c-8I?hC/IAP)dI>+i4Wkuc0IAOBTZHAlH^9W0Db+Z,[email protected]*b5[%mb5[%mb5[%mb5["t
-b,TlT\s7]?pr`Vfs2t@m,Kd$7Q+E6/V96r3J]c,dJ]c,dJ]c,dJ]c,dJ]a7+Y0*nq[[tVA^AQ:N
-Q1iK'Q2/]*Q1iN%Q2f/.Q2Su/XoNt~>
-!<E/pec208eH!;[bpn(9c&6qMc%CYnc%CAfc%CAfc%CA=[&gXZUpRhBH]-.$Hd.IqXK6bq^&6+s
-K6suMK6tkfMgMP,H[EH-H\8E5XMrG:H_e$M[*=5Mqop.pHaM&BK6tkfK6tkfK6tkfK6suEK6sE$
-XL-6)HiD7jMhCoO-\Hcjc%CAfMgMP,H[EHNK6tkfK6tkfK6tkfK6sE$XL-6:H^'bAHhbi=K6t;-
-H_ep2K6tkfXF$2FP^BLVXF#T$]r]2tK6sE$XL-6J[(WhnMp8')]sN-Eq99Y,Hd0ffHd0ffHd0ff
-Hd/X=PeE<.XSC$hK6tkfK6tkEH^)4.H`YK:K6tkfK6tkfK6tkfK6tkfK6tk-HaM&)HbH#q!58<\
-pRLs-!1`l8!1`c5rLEo<rLEi:!NZ9O~>
-!<E/feH!;[bpn(9c+U4'c%CYnc%CAfc%CAfc,GooH\8EEP_4=0Pf:n"Hd/pMH^pmYSG^VR["E_=
-K6tkf["E^qUjJWVXG_FPMoEr[P^@b0XNcBEqT]%us32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBE
-rlkIrHi)&8K6tkfK6tkMK6s,aH^r?5Hd0ffHd0ffHd0gSP^@b0XNe_BK=$8Xprrekrd+X8rlkIr
-HiD7mXFkkPXT$H_XG_FPMoEr[P^@b0XNcu^H[D!rc'3j-H^)MFbnPeWc-:lfc-:lfc-:lfc-<>B
-H\8Eobm]5Oc-:lfc-<>BH\8F!bnu([c-:lfc-:lfc-:lfc-:lfc,G<f`J]YFblGHTeH!;YS,g7r
-eb>U,ec20<ec20;eH)`OJ,~>
-!<E/fc2bTUasqh5b.=Umb(YPlb(5,db(5,db/0EpI>+iHQ%=@7Q+kClJ]bETI@['[RJb2LZ@RS<
-JUttd[Y9.#Tm`?OWel.PM8%-LQ%=@;Y0)<HqTAhts2t@ms2t@ms2t@ms2kbUJUtDLQ%=@;Y0)<H
-rlY7lqo\qis2t@m+j.6II@['[REC)3b0#9db0#9db0%SdJUN6Tb/0!dY(;0!aom9DI=[gcb5[%l
-aonPpI>+^#ar7::I=6sdb/0EpI>+iHQ%=@7Q+kD+JUN*7^A5qOJcEmmJcEmmJcEmmJcEjqV1j>O
-WqX[9JcEmmJcEjqV1j>OWrC0@JcEmmJcEmmJcEmmJcEmmJHj9:JUth#NLe2l^AQ7V[eZ0g[eA#@
-Q1`H&Q2T#.Q2Jo.XoNt~>
-!<E/feH!;[bpn(9c+U4'c%CYnc%CAfc%CAfc,GooH\8EEP_4=0Pf:n"Hd/pMH^pmYSG^VR["E_=
-K6tkf["E^qUjJWVXG_FPMoEr[P^@b0XNcBEqT]%us32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBE
-rlkIrHi)&8K6tkfK6tkMK6s,aH^r?5Hd0ffHd0ffHd0gSP^@b0XNe_BK=$8Xprrekrd+X8rlkIr
-HiD7mXFkkPXT$H_XG_FPMoEr[P^@b0XNcu^H[D!rc'3j-H^)MFbnPeWc-:lfc-:lfc-:lfc-<>B
-H\8Eobm]5Oc-:lfc-<>BH\8F!bnu([c-:lfc-:lfc-:lfc-:lfc,G<f`J]YFblGHTeH!;YS,g7r
-eb>U,ec20<ec20;eH)`OJ,~>
-!<E/feH!:YblYk:XL$1JHNLm5Hdg79HN:bEc2)be^"^d5XFnK_blGGqeH)`OJ,~>
-!<E/fc2bSSao]G2V6e>@I0.!2J^_d<I/pkDb5-Md]%b@/We&$XaoK/oc2k'JJ,~>
-!<E/feH!:YblYk:XL$1JHNLm5Hdg79HN:bEc2)be^"^d5XFnK_blGGqeH)`OJ,~>
-!<E/fblGGP`<!ZJX2P*lH\TK?UqN;;!56=q!NZ9O~>
-!<E/faoK/N`W<fIX2b0jL;j7f^7<1C^;S.pXoNt~>
-!<E/fblGGP`<!ZJX2P*lH\TK?UqN;;!56=q!NZ9O~>
-!<E/fblGG.`QQ7#XF\?_`;mTiblOmGJ,~>
-!<E/faoK/,`llC%Y(=Tb`W3`kaoSXFJ,~>
-!<E/fblGG.`QQ7#XF\?_`;mTiblOmGJ,~>
-!<E/fblGG.`IZ!Z`TP2?]u8.rX8mb~>
-!<E/faoK/,`du-\`ok>A^;S.pXoNt~>
-!<E/fblGG.`IZ!Z`TP2?]u8.rX8mb~>
-!!%S&JV/N+PCii8J,~>
-!!%S$JUrB'PCW]6J,~>
-!!%S&JV/N+PCii8J,~>
-!<E0!joD3.s+13$s.0/nV#TT>]`<Q~>
-!<E0!joD*+s+13$s.0/nU&X9;\c@6~>
-!<E0!joD3.s+13$s.0/nV#TT>]`<Q~>
-!<E0!joD3.s+13$s.95pK;AP0k.LbF~>
-!<E0!joD*+s+13$s.95pJYE,+k.1PC~>
-!<E0!joD3.s+13$s.95pK;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[OebI\pK*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:AM?!<(XM!7T[#!;Y@K!!:jS!:eeC!9W#2!!_-W!8?-,!9W#8!<1^P
-!;Y@K!.ijTgA'D%JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[OebI\pK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[OebI\pK*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:AM?!<(XO!7KU$!<:dQ!;bFL!!:jS!:eeC!9W#8!;bFL!<:dQ!9W#8
-!<1^P!;Y@K!.ijTgA'D%JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[OebI\pK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9Mec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<:dQ!!M!U!8?0*!<:dQ!<:dQ!<:dQ!<:dO!<:dQ
-!!:jS!;,"F!;kLK!<:dQ!!M!U!8?0*!<1^N!<:dO!<:dO!<:dQ!!:jS!;,"F!<(XO!!CpT!8@AO
-s4[DOs4[JQ!nmVSo\0<Frn@APs4[DOs4[JQ"kiqVg&M,(g4@uWgAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9Mec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[Oec42"K*A(N
-k2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Es4[JQ*81Amg&M-,g&M-,!!(a,!!(a,!!(^Q
-!8?-,!8@>No\0<Fr7_/Ns4[JQ+PHeqg&M-,!!(a,!!(^Q!8?-,!8?-,!8?-,!8?-,!8@>No\0<F
-rS%8O&)%!`g=cN,g=cN,g=cN,gACsCgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTgAfn,JH_bI
-k2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[Oec42"K*A(N
-k2s>WJ,~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%s4..%"f21\k.LbF~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA_0QgA_-mg&M-,!!(a,!!(a,!!(^Q!87DQg=cN,
-g=cN,gAV*CgA_0NgA_0QgA_-`g&M-,!!(^Q!8?-,!87DQqqD&Ms4[JQs4[JQ!8@DPo%O!A'&!<c
-g&M-,g&M-,g&M-,g&M-,rW)NCq>_)\!!(a,!!(^Q!87DQg=cN,J_G\/s4[L("ektYk.1PC~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%s4..%"f21\k.LbF~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^seNs+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo%F?Lg=cP\g&M-,qZ-ZMrr<;X!!(^Q!8?0(!!:jS!:eeC
-!;tRN!<:dQ!!_-W!87DQgA:jOg&M-MgA_0QgA_0QgA_-Sg&M-CgA_0OgA_-Yg&M-,g&M-,gA:jO
-g&M-CgA_0PgA_-QgA:jVg&M-,!!(a,!!%T(J_L.Xs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^seNs+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[Oec42"K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQmb7U>s4[JQ!nmVSqqD&M$/,@Zg&M-,g&M-NgA_0CgA_0N
-gA_0QgA_-Yg&M-,!!(^Q!;tRN!;kLM!<:dQ!<:dQ!!:jS!:eeC!<(XO!".E[!8?-,!8?-,!;tRN
-!:eeC!<1^P!!:jS!;tRN!!_-W!8?-,!.ijTgAfn,JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[Oec42"K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[Oec42"K*A(Nk2s>W
-J,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,n_4!Crn@AP#20%Wg=cN,rn@APs4[JQrn@APs4[JQ
-!nmVSnCmmBs4[DOs4[JQ(tnrig&M-,!!(a,!!(^Q!8?-,!8?-,!8@DPs4[JQ!nmVSn_4!CrS%8O
-#MK.Xg=cN,gAV*PgA_-Sg&M-CgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTgAfn,JH_bIk2s5T
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[Oec42"K*A(Nk2s>W
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%rmh%$"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:\_B!<1^P!<:dO!<(XO!<:dQ!<(XM!<:dQ!:SY?!<:dO
-!<:dQ!!M!U!8?0*!<1^N!<(XO!<:dO!<:dQ!:eeC!<(XO!!:jS!<1^P!<:dO!<:dQ!:eeC!<1^P
-!<:dO!<:dQ!!V'V!87DQJ_G\/rn@C'"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%rmh%$"f21\k.LbF~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uTgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uTgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uTgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+,fRK7SZIK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+,`PJUrBEJH_bIk2s5TJ,~>
-!<E0!joV@Ys+,fRK7SZIK*A(Nk2s>WJ,~>
-!<E0!joM:XJV/N+JV0PH"f21\k.LbF~>
-!<E0!joM1UJUrB'JUsDD"ektYk.1PC~>
-!<E0!joM:XJV/N+JV0PH"f21\k.LbF~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[OeHMcKk2s>WJ,~>
-!<E0!joD*+g>Uc`!;>.H!;P:J!!:jS!;kLM!9`)9!.ijTg'+2Mk2s5TJ,~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[OeHMcKk2s>WJ,~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[OeHMcKk2s>WJ,~>
-!<E0!joD*+g>Ucc!<:dQ!;G4I!;5(G!;kLM!9`)9!.ijTg'+2Mk2s5TJ,~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[OeHMcKk2s>WJ,~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc6SV#TT>]`<Q~>
-!<E0!joD+Hg@kRBgA:l+gA_0PgA_0QgAM$OgAM$OgAM$OgA_-Sg&M-MgA_0NgAM$OgA_0PgA_0Q
-gAM$OgA_/(g4@r]U&X9;\c@6~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc6SV#TT>]`<Q~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD+Hg@tUIJbe%"!/0)+!<1^P!#XDi!8?-,!8?-,!8?-,!8?-,!87DQg&M-MgA_0OgA_0Q
-gA_-Sg&M-PgA_-Zg&M-,g&M-,!!%T(J_C:$s5rIT!.Y~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_-Tg&M-,r;ciNr;clOquHcNr;`_KrrE&Prr<D[!!(a,!!(a,
-!!)oMrr<5V!!(^Q!;kLM!<(XO!<:dQ!<:dQ!"IW^!8?-,!8?-,!87DQJ_G\/"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA1gLgA_-Wg&M-,g&M-OgA_-Wg&M-,g&M,NgA_0PgA_-QgA:mM
-gA_0PgACpSg&M-,!!)oMrrE#OqZ-ZMrr<2U!!(a,qZ$]O!!%T(J_C:$s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^jq"s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gACpNgAV*PgA_0QgA_-Wg&M-,g&M-PgA_0QgA_0QgA_/NgA_0PgA_-S
-g&M-MgA_0QgA_0QgA_-Vg&M-,!!)oMrrE#OrrDoLrW)rOrrDuNrr@W(J_C:$s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^jq"s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA:jMgA:mLg&M-PgA:lJgA_0QgA_0QgA_0QgA_0QgA_-Q
-gAV*PgA_-Vg&M-,!!)oMrrE#OrrE)QrrE&PrW)rOrrE)Qrr<,S!!%T(J_C:$s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc6SV#TT>]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0NgA_0MgA_0PgA_/JgACsLgAM$MgA_0QgAV'PgAM!Q
-g&M-MgA:jMgAM$Lg&M-NgAM$OgA_/(g4@r]U&X9;\c@6~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc6SV#TT>]`<Q~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%j4+=/
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0QgA_-Zg&M-,g&M-,!!)uOrrE)Qrr@W(J_G\/j4X[1
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%j4+=/
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e`,*_V#TT>]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0OgAM$NgAM$OgACsNgAM#&g4@t/g>^fiU&X9;\c@6~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e`,*_V#TT>]`<Q~>
-!<E0!joD4Kec5[EK7VR(eUc8ZeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tdg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8ZeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!eaM#lV#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0OgAM$NgAM#&g@*`!U&X9;\c@6~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!eaM#lV#TT>]`<Q~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD*+g4@tpgAM$NgA_0QgA_-Wg&M-,g&M,(g@3f"U&X9;\c@6~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g@3f"U&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g@3f"U&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g@3f"U&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g@3f"U&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD4Keb4Xkec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\i
-eHMcKk2s>WJ,~>
-!<E0!joD+Hg@g*ngA_0PgA_-Sg&M-NgA_0FgA:m1gA(`"g8is-!<1^P!<:dQ!!_-W!8?-,!.ikn
-g'+2Mk2s5TJ,~>
-!<E0!joD4Keb4Xkec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\i
-eHMcKk2s>WJ,~>
-!<E0!joD4Keb=[rs7t4F!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#eaV)m
-V#TT>]`<Q~>
-!<E0!joD+Hg@p-us7tCK!<1^P!;Y@K!;,"F!8Q<.!.ik&gA_0PgA_0QgA_-Wg&M-,g&M,(g@3f"
-U&X9;\c@6~>
-!<E0!joD4Keb=[rs7t4F!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#eaV)m
-V#TT>]`<Q~>
-!<E0!joD4Kec19uXT/=rec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!n'qT;s5rIW!.Y~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#Orr</T!!(aO!<:aR!8@DP
-!8@DPp"KEGrS%2MJ_I?^rrE#Or;ciNr;_E&n(Ir=s5rIT!.Y~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!n'qT;s5rIW!.Y~>
-!<E0!joD4Kec19uXT/=rec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XJ!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg5akjU&X9;\c@6~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD4Kec19uXT/=rebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%Nn"</s5rIW!.Y~>
-!<E0!joD+HgAca#0`V1KgA1d\g&M-,!!(a,!!(^Q!8?-,!;kLJ!!(aP!<:dQ!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/NnOZ1s5rIT!.Y~>
-!<E0!joD4Kec19u@fQK(ebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%Nn"</s5rIW!.Y~>
-!<E0!joD4Kec19uXT/=rec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<(XO!<1^P!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg5akjU&X9;\c@6~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD4Kec19uXT/=rec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%Nn"</s5rIW!.Y~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<(XO!<1^P!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/NnOZ1s5rIT!.Y~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%Nn"</s5rIW!.Y~>
-!<E0!joD4Kec19uXT/=rec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XO!<1^P!<:dQ!".E[
-!8?-,!8?-,!;>.H!<1^P!<:dQ!.ijTg5akjU&X9;\c@6~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD4Kec19uXT/=rec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^sMF"f21\k.LbF~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#OrrE#Or;clOrrE)QrrE)Q
-rrDcHrrE#Or;bI'JUtXgJ_KkP"ektYk.1PC~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^sMF"f21\k.LbF~>
-!<E0!joD4Kec19ss+/]#eU`@iK)kq&eb@StV#TT>]`<Q~>
-!<E0!joD+HgAca!s+/l(g4=glJH5_$g@s;)U&X9;\c@6~>
-!<E0!joD4Kec19ss+/]#eU`@iK)kq&eb@StV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#B!Beb@StV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_VtNGg@s;)U&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#B!Beb@StV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&eb@StV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_W:^uJcGb$g@s;)U&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&eb@StV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^sMF"f21\k.LbF~>
-!<E0!joD+Hg@kRBgA_0PgA_-Sg&M-NgA_0FgA_0PgA_0KgA_/^gAc_T_W/N5s7P(HJcGDss+14M
-J_KkP"ektYk.1PC~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^sMF"f21\k.LbF~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-pXKGCs5rIW!.Y~>
-!<E0!joD+Hg@tUIJbe%"!<1^P!;Y@K!;,"F!<1^P!;Y@K!4U\^JUt\u_Z0Z/g&Zd)p"KFss8RZ(
-pY#eEs5rIT!.Y~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-pXKGCs5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&eb@StV#TT>
-]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE&Prr<_d!!(^Q!8?-,!8?-,
-!87DQg&M-PgAM$OgA_0QgA_0QgA_-Vg&M-,!!(a,s+,a<j21irp"BFts7P+GJcGb$g@s;)U&X9;
-\c@6~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&eb@StV#TT>
-]`<Q~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#pXKGC
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<1^P!!(aP!".E[!87DQ
-g&M-,gAV'eg&M-,!!(a,!!(^Q!8?-,!8?-,!8@DP!nmVSgY2[YJ\pHas8V_B!<;YAs8RZ(pY#eE
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#pXKGC
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^sMF"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA1d\g&M-,!!(a,!!(^Q!8?-,!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,a<j2(frjFR@2J_KkP"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^sMF"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<pXKGCs5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,b$_uG;ApY#eEs5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<pXKGCs5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^sMF"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<1^P!%ln)!8?-,!87DQg&M-,
-g&M-,g&M-,!!(a,!!(a,!!(^Q!87DQg=cN,g=cN,gY)XYJcEUeJ_KkP"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^sMF"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^on5"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;bFL!$Bnp!8?-,!8?-,!87DQ
-g=cN,g&M-,g&M-,!!(a,!!*#PrrE)QrrE&PrrE)Qrr@W(J_H7?"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^on5"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^on5"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;cZIquHcNrrE)Qrr<,S!!*#Pr;clO
-rrE)Qr;cfMrrE)QrrE&PrrE)Qrr@W(J_H7?"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^on5"f21\k.LbF~>
-!<E0!joD4Kec5[EK7VR(eUc8ZeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tdg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8ZeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F#rKDX1&V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`'Jc".)U&X9;\c@6~>
-!<E0!joD3.eUc8%e[F#rKDX1&V#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F#sK)krKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g:#`(JH5`Ig'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%e[F#sK)krKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%e[F$.KDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jbm4`Jbm7`s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD*+g4@t/g:#`8Jc!:bs+1$`s8VuM"ektYk.1PC~>
-!<E0!joD3.eUc8%e[F$.KDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD3.eUc8%e[F$.KDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g:#`8Jc!:cs+,au_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%e[F$.KDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%e[F$.KD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g:#`8Jc*Cbs8RZI_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%e[F$.KD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%e[F$.KD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jc*CbrrUo*Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jc3Ics8UgQJc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jc3Ics8LaPJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jc<Ods8C[OJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jc<Ods8:UNJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8JcEUes81OMJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8JcEUes8(ILJcEUes81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD3.e`>9\s7OqBs8CLJs.%U>s7+V>s-qO=s7+Y>s7=e@s68)6K*&ads7t4FKE&Xbs81=M
-V#TT>]`<Q~>
-!<E0!joD*+g>puf!;5(G!<(XO!1_aC!:ebC!1V[B!:eeC!;"qE!9r5;JHE^gs7tCKJcEUes81LR
-U&X9;\c@6~>
-!<E0!joD3.e`>9\!;4nB!<(IJ!1_R>!:eS>!1VL=!:eV>!;"b@!9r&6K*&ads7t4FKE&Xbs81=M
-V#TT>]`<Q~>
-!<E0!joD4Lec5[Lec#LJeboFOec5["s8UXKs8UXLs8UXLrrCUIrrCUKs-hI<s7FhAs8:CIs,5D-
-s,#8+s74\?s68)6K*&ads7k.EK*&ads81=MV#TT>]`<Q~>
-!<E0!joD+IgAe#LgARiJgAIcOg81Y"V5;oFV>o9LV>o9LV#]6IV#]6KV4-*<!;+tF!;tON!/oP2
-!/]D0!:nhD!9r5;JHE^gs7k=JJHE^gs81LRU&X9;\c@6~>
-!<E0!joD4Lec,XLeboIJebfCOeGoU"!!(RK!<:UL!<:UL!!(RI!!(RK!1MF<!;+eA!;t@I!/oA-
-!/]5+!:nY?!9r&6K*&ads7k.EK*&ads81=MV#TT>]`<Q~>
-!<E0!joD4KeIMW0ec41Ms4,["e^a]Ms8LOVs4,["e^a]Mec42"rm_5Qe^a]Mec2r*s8NATs4,["
-s4./LpsoBDs4.,KrRLrJr7(fIr7(fI\(1NY#M&k)ec42"s8CLJs8CLIs8LRKs8LRKs7b(BrrgmP
-s4.._ec5XSec41Ms4./LrRLrJrRLoIrmh&Krmh&Kp!j'BrRLrJrRLrJrm_,Nec5[Kec5[KeH,^#
-rr;fEs+C@Oon*=Zs8VuH"f21\k.LbF~>
-!<E0!joD+Hg('t5g83NWV:sY"g=iCWV>f0VV:sY"g=iCWg83N"rn7RQg=iCWg82+/rr<>Y!8?-,
-!87DQptG]Is4[GPrS%8Or7V,Nr7V,N\(^i^#MK13g&Th,!<(XO!<(XN!<1^P!<1^P!;G4G!!M!U
-!87FdgA_-Xg&Tj\!87DQrS%8OrS%5Nrn@APrn@APp"BBGrS%8OrS%8Orn7GSg&M-PgA_0Pg&V3-
-rW)cJs+14Momm1]s8VuM"ektYk.1PC~>
-!<E0!joD4KeIDT0eH".M!7fU"e^XZM!<1LV!7fU"e^XZMeH","rm_2Qe^XZMeGuo*rr<>T!7fU"
-!7_&Lpso?Ds4.)KrRLoJr7(cIr7(cI\(1KY#Lrh)eH","!<(IJ!<(II!<1OK!<1OK!;G%B!!LgP
-!7_(_ec,USeH".M!7_&LrRLoJrRLlIrmh#Krmh#Kp!j$BrRLoJrRLoJrm_)NeGoUKec,XKeH#[#
-rW)cEs+C@Oon*=Zs8VuH"f21\k.LbF~>
-!<E0!joD4KeIDQ/ec41Ms8UXLe^a^"rRLrJ'@m-5ec41Ms4./"s4./"ec5["s0C/^s4./"s4,["
-e^a]qeH#XIeHu9+ec41Ms4,["rRCoJr7(fI\()/lec42"e^a]Mec41Ms4,["e^a]reH#XIeH#XD
-eH#XKeHGp&s4..`eJ%u5s4./"ec41Ms4,["e^a]Mec5Kr!<;uI!<;cC!<<&K%fb)0s4,["e^a]M
-ec42"rm_,Ne^a^!eH#XCec17%s7:mCs81=MV#TT>]`<Q~>
-!<E0!joD+Hg'sn4g83NWV5;nBg=iC"rS%:J'AB;:g83NWV:qd"V:qd"g81Y"V6\e^!87G,!8?-,
-g=cQ&g&M-Ng'Ic5g&Tj\!8?-,rRq5Or7V,N\(VJqg&Th,g=cP\g&Tj\!8?-,g=cQ'g&M-Ng&M-I
-g&M-Pg&qE0!87Feg(OJ?!87G,g&Tj\!8?-,g=cP\g&V!'!!)rN!!)`H!!*#P%KP5:!8?-,g=cP\
-g&Th,rn7GSg=cQ+g&M-HgAc^(s7:gAs81LRU&X9;\c@6~>
-!<E0!joD4KeI;N/eH".M!!(OLe^XX"rRLoJ'@d*5eH".M!7_)"!7_)"eGoU"!4(,^!7_)"!7fU"
-e^XZqeGoUIeHl6+eH".M!7fU"rRClJr7(cI\(),leH","e^XZMeH".M!7fU"e^XZreGoUIeGoUD
-eGoUKeH>m&!7_(`eIqr5!7_)"eH".M!7fU"e^XZMeH#Hr!!)rI!!)`C!!*#K%KP&0!7fU"e^XZM
-eH","rm_)Ne^X[!eGoUCec17%s7:mCs81=MV#TT>]`<Q~>
-!<E0!joD4KeIMW0ec41Ms4./Le^a]Ms8LO`s4./Le^a]Mec42"ec42"e^a]Ms8TCT$NJZVec41M
-s4,["psoEErm_2Pe^a]Mec,UHeH#XIeH#WYeI;K.s4./"ec41Ms4,[!s8CLJs8:CIs8LRJs7b%D
-s8LOOs4./"s1["ls4./"s4,["e^a]Mec,UIec5[IeH#XKec,UBeH#XKeHZ'(ec41Ms8:FIs8CLI
-s8CIJs7Y"CKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+Hg('t5g83NWV:qcBg=iCWV>f0`V:qcBg=iCWg83N"g83N"g=iCWV5:KO$38c[g&Tj\
-!8?-,ptG`Jrn7MUg=cP\gAV*Mg&M-Ng&M,^g'du8!87G,g&Tj\!8?0+!<(XO!;tON!<1^O!;G1I
-!<1[T!87G,[email protected]!87G,!8?-,g=cP\gAV*NgA_0Ng&M-PgAV*Gg&M-Pg'.Q2g&Tj\!;tRN!<(XN
-!<(UO!;>.HJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4KeIDT0eH".M!7_&Le^XZM!<1L`!7_&Le^XZMeH","eH","e^XZM!!'=T$38TVeH".M
-!7fU"psoBErm_/Pe^XZMec#RHeGoUIeGoTYeI2H.!7_)"eH".M!7fX!!<(IJ!;t@I!<1OJ!;G"D
-!<1LO!7_)"!5?tl!7_)"!7fU"e^XZMec#RIec,XIeGoUKec#RBeGoUKeHQ$(eH".M!;tCI!<(II
-!<(FJ!;=tCKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4KeKFnBec41Ms4,["e^a]Mec41Ms4,["e^a]Mec41Ms4./KeH>j%ec2r*$NJZVec41M
-s4,["p=0TOe^a]Mec41Ms4,["rRCoJr7(fI\()&iec42"e^a]Mec41Ms4,["r7(fIrRD,Pe^a]M
-ec5Bo#liH*s8UXLec3A6&HC;\ec41Ms4,["e^a]Mec5Qt!<<#J#636(s4,["p=00Crm_MYe^a]M
-ec41Ms4,["ec5X!"96p%s8LOKs7Y"CKCJp<eHMcKk2s>WJ,~>
-!<E0!joD+Hg*!6Gg83NWV:sY"g=iCWg83NWV:sY"g=iCWg83NWV:qdFg&n2*g82+/$38c[g&Tj\
-!8?-,p=]oTg=cP\g&Tj\!8?-,rRq5Or7V,N\(VAng&Th,g=cP\g&Tj\!8?-,r7V,NrRqGUg=cP\
-g&Um$#QWT4!!(^Qg&Sk@&-1Dag&Tj\!8?-,g=cP\g&V')!!)uO"p!B2!8?-,p=]KHrn7h^g=cP\
-g&Tj\!8?-,g&V-+!s%'/!<1[P!;>.HJai^:g'+2Mk2s5TJ,~>
-!<E0!joD4KeK=kBeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7_)KeH5g%eGuo*$38TVeH".M
-!7fU"p=0QOe^XZMeH".M!7fU"rRClJr7(cI\()#ieH","e^XZMeH".M!7fU"r7(cIrRD)Pe^XZM
-eH#?o#QWE*!!(OLeH!>6&-15\eH".M!7fU"e^XZMeH#Nt!!)uJ"p!3(!7fU"p=0-Crm_JYe^XZM
-eH".M!7fU"eH#U!!s$m%!<1LK!;=tCKCJp<eHMcKk2s>WJ,~>
-!<E0!joD4Jec5[Lec5[LeH,^#rr<#Krr<#K!<<&Ks8W)K$3/QUe^a^"e^a]*eHu9+s4./Le^a^"
-psoBDs4.,K#1`bRe^a^"rmgrH!7h#I\^^f^ec41trs%$Rs4,["s8LRJs8LRHrrgmPs4./Dec5XR
-ec42"ec5ZaeH>j%s4.&I#1`bRe^a^"rmh#JrmgrH"P*PPec5Hqr;ZfIs8W&Js8W,Ls8N/Ns8W)K
-s8W)KrVuZCs+BqC!e^OQqpbkGs5rIW!.Y~>
-!<E0!joD+GgAe#LgAe#Lg&\&(rh]YKrh]YK!2]\Ks/#_K$)Q@Pg=iC"g=iC/g'Ic5!87DQg=cN,
-ptG]Is4[GP#20%Wg=cN,rn@8M!8@>N\_7,cg&Tk)!!_-W!8?-,!<1^O!<1^M!!M!U!87GIgA_-W
-g&Th,g&M,fg&h?/!8@>N#20%Wg=cN,rn@>Orn@8M"PNhUg&Us&quHcNrrE#OrrE)Qrr<,S!!*#P
-rrE&Pr;cWHs+0eA!eLCOqq;4Is5rIT!.Y~>
-!<E0!joD4Jec,XLec,XLeH#[#rW)uKrW)uK!!*#KrrE&K#lrKUe^XX"e^XZ*eHl6+!7_&Le^XX"
-pso?Ds4.)K#1W\Re^XX"rmgoH!7guI\^^c^eH".t!!^sR!7fU"!<1OJ!<1OH!!LgP!7_)Dec,UR
-eH","eGoTaeH5g%!7guI#1W\Re^XX"rmguJrmgoH"P!JPeH#EqquHcIrrE#JrrE)Lrr<,N!!*#K
-rrE&Kr;cWCs+BqC!e^OQqpbkGs5rIW!.Y~>
-!<E0!joD3.eb%Als+/^Oe\p#<KE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g@X)!!.ijTg;M_FJcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eb%Al!.i[Oe\p#<KE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eb7Pns8CLFs+/_pebfB-ebfBsec1:%s7CsDs81=MV#TT>]`<Q~>
-!<E0!joD*+g@j8#!<(XK!.ikugA:l2gA:m#gAca(s7CmBs81LRU&X9;\c@6~>
-!<E0!joD3.eb7Pn!<(IF!.i\peb]?-eb]?sec1:%s7CsDs81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.K)krCKE(uKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g:#`8JH5`AJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%e[F$.K)krCKE(uKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X;eH#X=eH#X7eH#WjeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-@g&M-Bg&M-<g&M,og&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU;eGoU=eGoU7eGoTjeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X;eH#X=eH#X7eH#WjeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-@g&M-Bg&M-<g&M,og&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU;eGoU=eGoU7eGoTjeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec,UKec#OJec5[JeH,^#rr2uKrVuZCs8W,Ls8N5Ps8UX"rVulIs8W)K
-!WU^Ls4>d$s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-FgAV*PgAM$OgA_0Og&V3-rVurPr;cWHrrE)Qrr<2U!!(a,r;ciNrrE&P
-!<CjQ!8#p)!/fJ1!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUAec#RKeboLJec,XJeH#[#rVurKr;cWCrrE)Lrr<2P!!(R"r;ciIrrE&K
-!<C[L!8#a$!/f;,!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeH#XHeH#XHeH#XJeH#XIeH#XDeHu9+ec41Ms4,["rm_#KrRD#Me^a^!
-eH#X!eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg&M-Mg&M-Mg&M-Og&M-Ng&M-Ig'Ic5g&Tj\!8?-,rn7>PrRq>Rg=cQ+
-g&M-&g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeGoUHeGoUHeGoUJeGoUIeGoUDeHl6+eH".M!7fU"rm^uKrRCuMe^X[!
-eGoU!eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec5[JeH#XJec,UIeH#XIeH#XDeHu9+ec41Ms4,["rm_#KrRLoIrRCoJ
-eC=R!MU__,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgA_0Og&M-OgAV*Ng&M-Ng&M-Ig'Ic5g&Tj\!8?-,rn7>PrS%5NrRq5O
-eCjm&MV8%1[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec,XJeGoUJec#RIeGoUIeGoUDeHl6+eH".M!7fU"rm^uKrRLlIrRClJ
-eC=O!MU_\,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X?eH#XKeHc-)ec5["ec5Tu!<;uI"96p%s8(7Ps4,["e^a]Mec5X!#liH*
-s4./"ec5X!!<:R!!<7r,!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Dg&M-Pg'7W3g&M-,g&V**!!)rN!s%'/!;bCU!8?-,g=cP\g&V-+#QWT4
-!87G,g&V-+!!(O&!!%o1!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoU?eGoUKeHZ*)eGoU"eH#Qu!!)rI!s$m%!;b4P!7fU"e^XZMeH#U!#QWE*
-!7_)"eH#U!!!(O!!!%o,!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBec,UHec5[Lec5XOec41MrVuiHs8VlEs8W&Js8N,Ms8LRKs8LRKs8LRI
-s45^#s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-GgAV*MgA_0QgA_-Tg&Tj\r;cfMrrDiJrrE#Orr<)R!<1^P!<1^P!<1^N
-!7oj(!/fJ1!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBec#RHec,XLec,UOeH".Mr;cfHrrDiErrE#Jrr<)M!<1OK!<1OK!<1OI
-!7o[#!/f;,!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X%ebfBWeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-*gA:l\g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU%eb]?WeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gAM$Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gAV*Mg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XHeH#XIec5Z`eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Mg&M-NgA_/eg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUHeGoUIec,W`eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XAeH#W`eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Fg&M,eg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUAeGoT`eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XCeH>j%s8W&Js8W,L"om-Qec5[Gec#OIec5[Jec,T_eH#W,eH#WXec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Hg&h?/!!)uOrrE)Q"T[6Vg&M-LgAM$NgA_0OgAV)dg&M,1g&M,]gAc`p
-_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUCeH5g%!!)uJrrE)L"T['QeGoUGeboLIec,XJec#Q_eGoT,eGoTXec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeIV]1ec41Ms4,["ec42"ec5Ep!<;rH!<<&K"96p%s1["`s,,>,s0gJX
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg(+2;g&Tj\!8?-,g&Th,g&Up%!!)oM!!*#P!s%'/[email protected]!/fJ1!4LV]
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeIMZ1eH".M!7fU"eH","eH#Bp!!)oH!!*#K!s$m%!5?t`!/f;,!4LGX
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeHQ!'ec41Mrr<#K"TR$Pec5Ep!<;rH!<<&K"96p%s1["`s,,>,s0gJX
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg'%K1g&Tj\rW)uP"9@-Ug&Up%!!)oM!!*#P!s%'/[email protected]!/fJ1!4LV]
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeHGs'eH".MrW)uK"9?sPeH#Bp!!)oH!!*#K!s$m%!5?t`!/f;,!4LGX
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeIMW0ec41Ms4,["e^a]Ms7b%Gs4,["rm_#Krm_,Ne^a]6eH#W,eH#WX
-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg(",:g&Tj\!8?-,g=cP\!;G1L!8?-,rn7>Prn7GSg=cP@g&M,1g&M,]
-gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeIDT0eH".M!7fU"e^XZM!;G"G!7fU"rm^uKrm_)Ne^XZ6eGoT,eGoTX
-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XCec,RQec5["ec5[KeH5d$s7Y"Cs8UXIs8UXLrrL[M^XW>aMU__,[akD1
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-HgAV'Vg&M-,g&M-Pg&_9.!;>.H!<:dN!<:dQ!!1dR^Y/YfMV8%1[bCb4
-o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUCec#OQeGoU"eGoUKeH,a$!;=tC!<:UI!<:UL!!1UM^XW;aMU_\,[akD1
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X1ebfBKeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-6gA:lPg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU1eb]?KeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$eb]?0eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gA:l5g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$eb]?0eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$ebfE0eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gACr5g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$ebfE0eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#X*eH#XJeH#X=ec5[@ec5[2eH#W,eH#WXec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-/g&M-Og&M-BgA_0EgA_07g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoT,eGoUAeGoU*eGoUJeGoU=ec,X@ec,X2eGoT,eGoTXec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#W,eH#XAeH#X%eH#X<eH#X?eH#X2eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-*g&M-Ag&M-Dg&M-7g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoU%eGoU<eGoU?eGoU2eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBec#OJeH,^#r;QiKs8VrG#liHTec5["s4.,Ks4./LrmguIrmh&Kp=00C
-rRLrJrRLrJrm_,Nec5[5eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-GgAM$Og&V3-qu?fP!!)lL#QWQYg&M-,!8@DPs4[JQrn@;Nrn@APp=]KH
-rS%8OrS%8Orn7GSg&M-:g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeboLJeH#[#qu?fK!!)lG#QWBTeGoU"!7h&Ks4.,LrmgrIrmh#Kp=0-C
-rRLoJrRLoJrm_)NeGoU5eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XIeH#XJeH>j%ec5Kr"TR$Pec5X!!<;rH!<<#J!<<#J"96p%s7b%D
-s8LOYs4,["e^a]Mec41Ms4./4eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Ng&M-Og&h?/g&V!'"9@-Ug&V-+!!)oM!!)uO!!)uO!s%'/!;G1I
-!<1[^!8?-,g=cP\g&Tj\!87G9g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoUIeGoUJeH5g%eH#Hr"9?sPeH#U!!!)oH!!)uJ!!)uJ!s$m%!;G"D
-!<1LY!7fU"e^XZMeH".M!7_)4eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XIeH#XJeH>j%ec5Kr"TR$Pec5X!!<;rH!<<#J!<<#Jrr;]B!<<&K
-#636(s4,["r71iIk1'J3MU__,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Ng&M-Og&h?/g&V!'"9@-Ug&V-+!!)oM!!)uO!!)uOrW)ZG!!*#P
-"p!B2!8?-,r7_/Nk1Te8MV8%1[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAeGoUIeGoUJeH5g%eH#Hr"9?sPeH#U!!!)oH!!)uJ!!)uJrW)ZB!!*#K
-"p!3(!7fU"r71fIk1'G3MU_\,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XAeHZ'(ec41Ms8CIMs4,["q:,QHec5Tu!<;rH!<<#J#liH*s4./"ec5Bo
-!<<&K%fb)0s4,["e^a]Mec42"kLBS4MU__,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Fg'.Q2g&Tj\!<(UR!8?-,q:YlMg&V**!!)oM!!)uO#QWT4!87G,g&Um$
-!!*#P%KP5:!8?-,g=cP\g&Th,kLon9MV8%1[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAeHQ$(eH".M!<(FM!7fU"q:,NHeH#Qu!!)oH!!)uJ#QWE*!7_)"eH#?o
-!!*#K%KP&0!7fU"e^XZMeH","kLBP4MU_\,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X@ec5[Lec#OIec5[EeH5d$s8LRIs8UXIs8LRKs8LRKs7k.Bs8UXLs8CLJ
-s8UXLrrUaNs6.u5s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-EgA_0QgAM$NgA_0Jg&_9.!<1^N!<:dN!<1^P!<1^P!;P:G!<:dQ!<(XO
-!<:dQ!!:jS!9i,:!/fJ1!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoU@ec,XLeboLIec,XEeH,a$!<1OI!<:UI!<1OK!<1OK!;P+B!<:UL!<(IJ
-!<:UL!!:[N!9hr5!/f;,!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#X5eH#WFeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-:g&M,Kg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU5eGoTFeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X7ec5[JebfC,ebfBoeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-<gA_0OgA:m1gA:ltg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU7ec,XJeb]@,eb]?oeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gAM$Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*&-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gAV*Mg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XBec5Z`eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-GgA_/eg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUBec,W`eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XAeH#W`eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Fg&M,eg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUAeGoT`eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec5XPec42"ec,RMec5[KeH>j%s8W)KrVulIs8W&Jrr9^_!<7r,!<9LX
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-FgA_-Ug&Th,gAV'Rg&M-Pg&h?/!!*#Pr;ciNrrE#OrW'[d!!%o1!!'I]
-s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAec,UPeH","ec#OMeGoUKeH5g%!!*#Kr;ciIrrE#JrW'[_!!%o,!!'IX
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<;rH!<<&K"96p%s8LOKs8CISs4,["e^a]Mec3A6!<7r,
-!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!)oM!!*#P!s%'/!<1[P!<(UX!8?-,g=cP\g&Sk@!!%o1
-!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!)oH!!*#K!s$m%!<1LK!<(FS!7fU"e^XZMeH!>6!!%o,
-!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<<#Jrr;uJ"96p%s8LOKs8CLIs8LONs4,["^=<5`MU__,
-[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!)uOrW)rO!s%'/!<1[P!<(XN!<1[S!8?-,^=iPeMV8%1
-[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!)uJrW)rJ!s$m%!<1LK!<(II!<1LN!7fU"^=<2`MU_\,
-[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<<&K"96p%s8LONs4,["rm_MYe^a]Ms4,["e^a]Mec3A6
-!<7r,!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!*#P!s%'/!<1[S!8?-,rn7h^g=cP\!8?-,g=cP\g&Sk@
-!!%o1!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!*#K!s$m%!<1LN!7fU"rm_JYe^XZM!7fU"e^XZMeH!>6
-!!%o,!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAec,UKec#OJec5XNec42!rrUaNs8LRKs8LRKs8CLJrrL[M^XW>aMU__,
-[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgAV*PgAM$OgA_-Sg&Tk+!!:jS!<1^P!<1^P!<(XO!!1dR^Y/YfMV8%1
-[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec#RKeboLJec,UNeH"/!!!:[N!<1OK!<1OK!<(IJ!!1UM^XW;aMU_\,
-[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X?eH#W<eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Dg&M,Ag&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU?eGoT<eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBec,T:eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-GgAV)?g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBec#Q:eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$eb]?0eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gA:l5g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$eb]?0eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*&-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH5d$ebfE0eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gACr5g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$ebfE0eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X5ec5[,eH#XHeH#XIec5[#eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-:gA_01g&M-Mg&M-NgA_0(g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU5ec,X,eGoUHeGoUIec,X#eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X4eH#X,eH#XAeH#X#eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-9g&M-1g&M-Fg&M-(g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU4eGoU,eGoUAeGoU#eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeH,^#rr<#Ks8W#I!<<#Js8W)Ks8W#Irr;uJs8VlErVulIs8W&Jrr:R"
-!<7r,!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&V3-rW)uPrrDuN!!)uOrrE&PrrDuNrW)rOrrDiJr;ciNrrE#OrW(O'
-!!%o1!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH#[#rW)uKrrDuI!!)uJrrE&KrrDuIrW)rJrrDiEr;ciIrrE#JrW(O"
-!!%o,!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAeH#XJeH>j%ec5Tu!<<&K"96p%s8CIJs8LOKs8:CLs4,["psfBEqpb]H
-rm_,Ne^a]NeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Og&h?/g&V**!!*#P!s%'/!<(UO!<1[P!;tOQ!8?-,pt>]Jqq;#M
-rn7GSg=cPXg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoUJeH5g%eH#Qu!!*#K!s$m%!<(FJ!<1LK!;t@L!7fU"psf?EqpbZH
-rm_)Ne^XZNeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XJec,UHeH#XKec,UJec,UIec5[Kec,UCeH#XHeH#XKeH>j%ec44N
-!<7r,!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Fg&M-OgAV*Mg&M-PgAV*OgAV*NgA_0PgAV*Hg&M-Mg&M-Pg&h?/g&T^X
-!!%o1!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAeGoUJec#RHeGoUKec#RJec#RIec,XKec#RCeGoUHeGoUKeH5g%eH"1N
-!!%o,!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAeH#XJeH>j%ec5Tu!<<&K#liH*s4./"ec5Ns#636(s4,["psfKHe^a^!
-eH#XKeH>j%ec44N!<7r,!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Og&h?/g&V**!!*#P#QWT4!87G,g&V$("p!B2!8?-,pt>fMg=cQ+
-g&M-Pg&h?/g&T^X!!%o1!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAeGoUJeH5g%eH#Qu!!*#K#QWE*!7_)"eH#Ks"p!3(!7fU"psfHHe^X[!
-eGoUKeH5g%eH"1N!!%o,!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBec#OIec5[KeboIIec5[Kec5XOec41Mrr;rIs8VfCs8W,Lr;ZfIs8N,M
-s4>d$s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-GgAM$NgA_0PgACsNgA_0PgA_-Tg&Tj\rW)oNrrDcHrrE)QquHcNrr<)R
-!8#p)!/fJ1!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeboLIec,XKebfFIec,XKec,UOeH".MrW)oIrrDcCrrE)LquHcIrr<)M
-!8#a$!/f;,!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#WnebfBceH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,sgA:lhg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoTneb]?ceGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gAM$Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*&-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gAV*Mg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X@ec5[Eec5[DeH#X=eH#X%eH#XHeH#X@eH#W,eH#WXec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-EgA_0JgA_0Ig&M-Bg&M-*g&M-Mg&M-Eg&M,1g&M,]gAc`p_Z0Z5g'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoT,eGoU@ec,XEec,XDeGoU=eGoU%eGoUHeGoU@eGoT,eGoTXec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#W,eH#X?eH#XDeH#XDeH#X=eH#X%eH#X9eH#W,eH#WXec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&Rt,g&M-Dg&M-Ig&M-Ig&M-Bg&M-*g&M->g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoT,eGoU?eGoUDeGoUDeGoU=eGoU%eGoU9eGoT,eGoTXec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#W,eH#XAec,UJec5[IeH#XJec5[Kec#OIec5[Eec#OJeH,^#rr3&Ms8W)K"96pO
-s8CLIs8UXLs8:FIs8LRIs8LRKs8CLJs8UURs4./Le^a\WeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-FgAV*OgA_0Ng&M-OgA_0PgAM$NgA_0JgAM$Og&V3-rW!#R!!*#P!s%$T
-!<(XN!<:dQ!;tRN!<1^N!<1^P!<(XO!<:aW!87DQg=cOag&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAec#RJec,XIeGoUJec,XKeboLIec,XEeboLJeH#[#rW!#M!!*#K!s$jO
-!<(II!<:UL!;tCI!<1OI!<1OK!<(IJ!<:RR!7_&Le^XYWeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeHu9+ec41Ms4,["rRCoJrm_,Ne^a^!eH#XJeH>j%ec5Ep!<;uI!<;rH
-!<<&K#636(s4,["qUGTGrm_,Ne^a^!eH#XHeH#XKeI2E-ec41Ms4,["ec1NW!<9LXs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ+g&M-Og&h?/g&Up%!!)rN!!)oM
-!!*#P"p!B2!8?-,qUtoLrn7GSg=cQ+g&M-Mg&M-Pg'[o7g&Tj\!8?-,g&R#a!!'I]s+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeHl6+eH".M!7fU"rRClJrm_)Ne^X[!eGoUJeH5g%eH#Bp!!)rI!!)oH
-!!*#K"p!3(!7fU"qUGQGrm_)Ne^X[!eGoUHeGoUKeI)B-eH".M!7fU"eGtKW!!'IXs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeHQ!'ec41Mrr;oH!<<&Krr;rI!<<#Jrr;`C!<;uI!<<#Jrr;uJ"96p%
-s8LRKs8LRJs8LOKs81=Hs81=Hs8LOVs4,["e^a]Mec42"MU__,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Gg'%K1g&Tj\rW)lM!!*#PrW)oN!!)uOrW)]H!!)rN!!)uOrW)rO!s%'/
-!<1^P!<1^O!<1[P!;kIM!;kIM!<1[[!8?-,g=cP\g&Th,MV8%1[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUBeHGs'eH".MrW)lH!!*#KrW)oI!!)uJrW)]C!!)rI!!)uJrW)rJ!s$m%
-!<1OK!<1OJ!<1LK!;k:H!;k:H!<1LV!7fU"e^XZMeH","MU_\,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XBeHu9+ec41Ms4,["rRCoJrm_,Ne^a^!eHl3*ec42"e^a]peHZ'(ec41M
-s8LONs4,["rm_,Ne^a]teHQ!'s4,["rm_,Ne^a^!eH>j%ec5X!!<<&K$iec-s4,["e^a]Ms,,>,
-s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ+g'@]4g&Th,g=cQ%g'.Q2g&Tj\
-!<1[S!8?-,rn7GSg=cQ)g'%K1!8?-,rn7GSg=cQ+g&h?/g&V-+!!*#P$NSo7!8?-,g=cP\!/fJ1
-!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeHl6+eH".M!7fU"rRClJrm_)Ne^X[!eHc0*eH","e^XZpeHQ$(eH".M
-!<1LN!7fU"rm_)Ne^XZteHGs'!7fU"rm_)Ne^X[!eH5g%eH#U!!!*#K$NS`-!7fU"e^XZM!/f;,
-!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XAec5XQec41Ms8W)Kr;ZfIs8W#Is8W)Ks8VfCs8W,LrVuoJs8N/Ns4.,K
-"4dGOec,UJec5XMec5X!s8W#Is8W,Lr;ZfIs8W,Lrr2uKrr7l+!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-FgA_-Vg&Tj\!!*#PquHcNrrDuNrrE&PrrDcHrrE)Qr;clOrr<,S!8@DP
-"53_TgAV*OgA_-Rg&V-+rrDuNrrE)QquHcNrrE)QrVurPrW%i0!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAec,UQeH".M!!*#KquHcIrrDuIrrE&KrrDcCrrE)Lr;clJrr<,N!7h&K
-"4[AOec#RJec,UMeH#U!rrDuIrrE)LquHcIrrE)LrVurKrW%i+!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#WtebfB]eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-$gA:lbg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoTteb]?]eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gAM$Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gAV*Mg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc^(_Y!j0JcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc^*_Z0Z2gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:%^&S-.ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca(_Z0Z3gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:%^&S-.ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca(_Z0Z4gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca'_Z0Z5gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca'_Z0Z6gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca&_Z0Z7gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca&_Z0Z8gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca%_Z0Z9gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca%_Z0W;g4=hQ_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca$_>sW8Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca$_?0agJc!=as81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca#_Z,2a_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca#_>o/`_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXeGt6js81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]g&Q]ms81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXeGt6js81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#W?eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,Dg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoT?eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZhKBC\fV#TT>]`<Q~>
-!<E0!joD+Pg4=g+JUrBdJ`bYiU&X9;\c@6~>
-!<E0!joD4SeU`@(K7SZhKBC\fV#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZiK)kr6eHMcKk2s>WJ,~>
-!<E0!joD+Pg4=g+JUrBeJH5`4g'+2Mk2s5TJ,~>
-!<E0!joD4SeU`@(K7SZiK)kr6eHMcKk2s>WJ,~>
-!<E0!joD4Sec19n]`J/HK)^D8J\C!Ts8V`)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`q_?'\RK)^D=J\p?^s8V`.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19n]`J/HK)^D8J\C!Ts8V`)s8V63"f21\k.LbF~>
-!<E0!joD4Sec19p^&S*5K=up;!/#j9J\C!TrVuT)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`s_Z0W:J\m'>!.f^<J\p?^rVuT.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19p^&S*5K=up;!/#j9J\C!TrVuT)s8V63"f21\k.LbF~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S+eec18Q]n*lT^&.j)^&S,peHMJVS=BQZJ,~>
-!<B_0RJY_<JbR%\s8RWO_Z0XjgAc_T_L]S^_YaB._Z0Yug'*nUR@+$TJ,~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S+eec18Q]n*lT^&.j)^&S,peHMJVS=BQZJ,~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s+])(K7U^e^#6U(s8UXJs8'G/s5qi8SB\a\S,e'~>
-!!)u?!1E`<s+1!_rVm&TJUt]<s+]8-JUt[h_Vi<2s8UgOs8'V4s5r#=REE+PR/ha~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s+])(K7U^e^#6U(s8UXJs8'G/s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S+eec18Q]n*lT^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_YsN6gAc^*_Z0XjgAc_T_L]S^_Z0Z7gAV'L_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S+eec18Q]n*lT^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S+eec18Q]n*lT^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_YsN4gAc^*_Z0XjgAc_T_L]S^_Z0Z5gAV'N_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S+eec18Q]n*lT^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S+eec18Q]n*lT^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_YsN2gAc^*_Z0XjgAc_T_L]S^_Z0Z3gAV$Q_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S+eec18Q]n*lT^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ebb!oec17'^&S+eec18Q]n*lT^&S--ebt.#s5qi8SB\a\S,e'~>
-!<C:A\cA/qgA?HrgAc^*_Z0XjgAc_T_L]S^_Z0Z2gAQU&s5r#=REE+PR/ha~>
-!<CCD]`=T"ebb!oec17'^&S+eec18Q]n*lT^&S--ebt.#s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S+eec18Q]n*lT^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_Yo&^gAc^*_Z0XjgAc_T_L]S^_Z0Z3gAQR(_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S+eec18Q]n*lT^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S+eec18Q]n*lT^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_Yo&`gAc^*_Z0XjgAc_T_L]S^_Z0Z5gAQU%_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S+eec18Q]n*lT^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S+eec18Q]n*lT^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_Yo&bgAc^*_Z0XjgAc_T_L]S^_Z0Z7gAQU#_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S+eec18Q]n*lT^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8Ri(s+>m9J\C!Ts8W,LrIas[s8V63"e<iN]po(Q~>
-!<C:A\cA/qgAca"_Yo#hg4=gls8Ri-s+,a<J\p?^s8W,QrIOg^s8V68"e!NE\sWPK~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8Ri(s+>m9J\C!Ts8W,LrIas[s8V63"e<iN]po(Q~>
-!<CCD]`=T"ec19r^&3Ka^&S+eec18Q]n*lT^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<C:A\cA/qgAc`u_Yerd_Z0XjgAc_T_L]S^_Z0Z7Jb[+^s5r#=REE+PR/ha~>
-!<CCD]`=T"ec19r^&3Ka^&S+eec18Q]n*lT^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec19p^&EWc^&S+cK7U^e^#6U(s8R`F^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAc`s_Z#)f_Z0XhJUt[h_Vi<2s8RZD_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec19p^&EWc^&S+cK7U^e^#6U(s8R`F^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19n]`Ni"s+>rT]n*lT]`J.coY(;)k1'X*c+Uf\!.Y~>
-!<C:A\cA/qgAc`q_?,;*s+>lR_L]S^_?'[foYUY.k1U!,b.>0P!.Y~>
-!<CCD]`=T"ec19n]`Ni"s+>rT]n*lT]`J.coY(;)k1'X*c+Uf\!.Y~>
-!<CCD]`=T"ec18Qs+13$s1nZseHMJf]tKp9J,~>
-!<C:A\cA/qgAc_Ts+13$s1nZsg'*ne]"4:0J,~>
-!<CCD]`=T"ec18Qs+13$s1nZseHMJf]tKp9J,~>
-!<CCD]`=T"eGt5Qs+13$s1eTreHMJf]tKp9J,~>
-!<C:A\cA/qg&Q\Ts+13$s1eTrg'*ne]"4:0J,~>
-!<CCD]`=T"eGt5Qs+13$s1eTreHMJf]tKp9J,~>
-!<CCD]`=RReUc8%eXb4oSB\a\S,e'~>
-!<C:A\cA.Lg4@t/g7?q$REE+PR/ha~>
-!<CCD]`=RReUc8%eXb4oSB\a\S,e'~>
-!<CCC^%%VDUk,=mUqNQ(^%.Znc2PBWS,e'~>
-!<C:@]()2>Tn/ngTtR-"](26hb5SsQR/ha~>
-!<CCC^%%VDUk,=mUqNQ(^%.Znc2PBWS,e'~>
-!\j]"rOqgI!53s`JcC<$^&RWIrk/B'!',Q~>
-!^m%2rOVUC!4ma]JcC<$^&RWFrji0!!(;>~>
-!cn@drOqgI!53s`JcC<$^&RWIrk/B'!-<Y~>
-!]^8*n%A^kJ`_OGJ`aZ.!6suG!h96FJ,~>
-!^m%2n%&LeJ`_OGJ`aZ.!6XcA!gs$VJ,~>
-!cn@dn%A^kJ`_OGJ`aZ.!6suG!h973J,~>
-">Mn:S=K,_!1\W&J`_OG^#f=>n\+sm!WY5@J,~>
-s$QngR@3TV!1AE#J`_OG^#f=;n[eag!WYVVJ,~>
-"DVuXS=K,_!1\W&J`_OG^#f=>n\+sm!W[:_J,~>
-">Mns!!)MYJ\?WJJ\A_0nXTUZ!]_tqJ,~>
-r^?bdn<nj=J\$ED]XmX$rrE$dJ,~>
-rcA)>n=5'CJ\?WJ]Y3j*rr<+AC3+n~>
-!BDn63Iq0]!.b->!!G#:0f^t=~>
-r'Z)9JH16$RfN@SJ,~>
-!HW#TF+F=B!.b->!;png~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/megaco_collector.gif b/lib/et/doc/src/megaco_collector.gif
deleted file mode 100644
index 56a2c5891e..0000000000
--- a/lib/et/doc/src/megaco_collector.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/megaco_collector.png b/lib/et/doc/src/megaco_collector.png
new file mode 100644
index 0000000000..d5c2cde7e4
--- /dev/null
+++ b/lib/et/doc/src/megaco_collector.png
Binary files differ
diff --git a/lib/et/doc/src/megaco_collector.ps b/lib/et/doc/src/megaco_collector.ps
deleted file mode 100644
index bdc603f087..0000000000
--- a/lib/et/doc/src/megaco_collector.ps
+++ /dev/null
@@ -1,3247 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/megaco_collector.ps
-%%CreationDate: Mon Oct 14 18:04:40 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 433 458
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 443.079478 translate
-417.999508 -443.079478 scale
-% Image geometry
-500 530 8
-% Transformation matrix
-[ 500 0 0 530 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 500 string def
-/gstr 500 string def
-/bstr 500 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 194862 ASCII Bytes
-colorimage
-"4bhXB)#L068!gRJNn]M`]jGHoiV;t7J0da:/CXf"%jdo1k5~>
-"5;@eBD>U16Sa3Zq*KWuJO.RI!$q5?!E_b_=TM8npfR\n/42gU~>
-"4bhXB)#L084%l+JQ%+u`_ujnoiV;t7J0da:/CXf"'&!2F+=~>
-"k%V!e`,ckkQ'lHmK'S4JX5tp<L9#;Q^3u(QC!o(QBml'QC!o(QBml'Q^3r(QBml'Q^3r(QC!r(
-Q^3r(QC!o'Q^3u)QC!o'Q^3u)QC!o(Q^3u(QC!o(Q^3u(Q^=#)QBml'Q^=$:QNNP?Q^7T:!1*SM
-J!QFaOckiiP*(oiOckiiP*(oiP*1rjOcbfhP*1rjOckliP*(liOckliP*(liOckihP*(ojOckih
-P*(ojOckiiP*(oiOckiiP*(oiP*1rjOcbfhP*1rjOckliP*(liOckliP*(ojOckihP*(ojOckih
-P*(oiOckiiP"Lk"OcbfhP*1rjOckliP*(liOckliP*(ojOckihP*(ojOckiiP*(oiOckiiP*(oi
-P*1rjOcbfhP*1rjOcbfhP*1rjOc`Z6iVqg:kPjZKlL+*+a6*B\!9=%A"mk[FeD]<aiW/*=kQBYF
--oQS~>
-%bH$2e`5cQk32'qm-_6-MP'sAnXb<&hOOY<qOIVXrLEq[qOIVXrLEq[qOIVXrLF%^SXlANSH,8X
-SH,8[SH,8XSH,8[SH,8XSH,8[SH,8XSH,8[SHGISSY#eN!1s%X!1s.[!1s%X!1s.[!1s%X/=rE'
-?h*%3ioB.^k32'qm-DXRi8EVTjlP[hlKdidiSNMOioK4_kigd*0116~>
-"k%V!e`,ckkQ'lHmK(25J`<$U($"<5j5T+YioB%Yio9"XioB%Yio9"siX"T(ioB%Yio9"si]#oW
-ioB%Yio9"XioB%Yio9"Xj5T(Yio9"Xj5T(YioB%Xj5T(YioB%Xj5T+YioB%Xj5T+YioC!s#ijq(
-j5T+YioC!s2rioWj5T+YioB%Xj5T+YioB%Yio9"XioB%Yio9"Xj5T(Yio9"Xj5T(YioB%Xj5T(Y
-ioB%Xj8IsCj5T(YioB%Xj8IsUj5T(YioB%Xj5T(YioB%Xj5T+YioB%XOn%E0iW/0@kQU8>md%pU
-ro*q<rTFFOmdAT`hu;U8jo+BFh69@gJ,~>
-"H0M7e_C)[#2nV*k3/jIX)J#\d;Nc=EGoi<Df]o;FDu8AE--)>F)Q,?E--&>F)Z8AEcc5BEcH>C
-F*;JGEcQDCF`h\KEH?;AH?=4TDg-DFHZF7SDg?JHIrBOWE.)eLI;aLWF+A4SI<'g]FanFYH?4RX
-G^XR\G]eLVH[A;)Jou9gEI`@WK5uBhF+e^^JoQ?gFbFd_Irg6dG_0sdI!(-aH[p-hG^"d\Isc?k
-FF&IXK6_ZnEdiFYKQMNkEIrL[K5uEiF*!"WH%BseH?Fm]I=H<lG'\a[K6qcqF+/U[Km.fpEe8[]
-L3%cnEeSa`K5uNkFbOpbJT?HiG_C*fI<:0cH\$0iH?Y$_IsuKnG'eg\KR7lrEdiLZKm.ipEeA^^
-Kl_]mF+ng`K5uQkFbXscJ9$?gGS#LJJUMZpFF8X[HqWkWe^iLSh>lL4jorf`e^`:-rn[Y7roO70
-iVq@-f`'_2hrNq^O<oD~>
-%Z[dDf%Jd3hV[>Qk3&pXX*XksJC]'EI"$EjI=-HjI!p?iI!gBiIXQTnI=6TlIXZ]qI"$QmJUMrt
-H[pWoJp`'"H\6itK7/<%I>!'!KRAH(IYE3%K7/H'J:r<(JprN(Jq\W.J:N-(I>*<'MLC,4I>NN*
-M1(,3IYiN+LOG&3JVnl1Kmnu1K8P&6K7Jo/L515:J:`Z+MM-M>I>*K+N.HV>I#<W.NI?M;I>i`/
-Mg^G:IuSo2M1(A9JrP28LOY>6KSt5;KS#54M26YBJ;&r0NJ)kDI>E`/O+;nCI>ir4O+)k1Mgg\=
-K8k><Lk(S:L5UM@KS,;6MMQeDJ;0#3NeN(FIYio2O+E"DI>rr4O+)qCIuf/6NI?e@JWG89MLUY<
-KT1D=LOkM9LPpVAK7f25MhlnEItio2NeE%FIYrr3O+;qCI>(_gdacq%g=tKAioB1_`ST(of@npm
-gtpuKjQ=eHdaQe"g=kB>iSrs\/:[~>
-"H0M7e_C)[#2nV*k30LUX31Iee&m0ab0%rNbKe8Tbfe;Sbg";UbKJ2Rc-4AVb08,QcHFDVb0A/R
-cH=AUb0J2RcH=DWb0\>UccXPXbL"DVcH=JVbg4GYc-4SXcI'k`ccsk]d*U"ac-F_\dEg(bbg4Y[
-dE^%ebgXt`e]cChbgaq`eBH@gbgjtbe'-=fc.'u;dW<X_c-On`eBcCibgFk_e]lFibgXq`e]cFh
-bgk"aeBHCgc.1%be'-=ecIC(edEL.cd*p4gcd(%ada?:hc-Ok_eBcChbgOq`e]lFibgXq`e]cFh
-bgjt`eBHCgc.1%ce'-=ecIC(edEU4cd*p4gcH\i-bgXt`e]lIibgat`[email protected]%d
-d`g7dcd^1fd*:+bdF-7hc-Fh_e'Q@ibgFn`eBZ@hbg)+5e^`7*rn[Y5rT4:(i76B0h>Z72ir8'@
-dc(2U!8.;-"lJD'k)`5d~>
-%VF8Ag=Xj1i8s"NkO#?LqIp"GD//HP!GuWHB`W!co4\8\]P$SF$u19WJCM'BJWe5iCi&BN"cpuB
-\YNp6Bf'aEC2Rg&D/*p'OH"$lD/*p'C2Rd'Chds)DJs90Chn'+E,KE2CMn6/Ec>f=CiXW4GA_;J
-G&)5ACjBr>G&2ABDg6,CFDQ>CF*MMIEGp2@GBReME-$>AIWKFWDL$JCIrTRYCjgACJ8]^XD1?PH
-I;OCSDLcYMHYn7REdqtSG&;hMGC47[F)lkMIX#^`EHltLJol!bDLHeIKQ23dD1ZkKKPu6aD1lqQ
-JSfs\DhN%UG^O@\EclqMJTbpbE-cqLK626lDh<@RMfX5uD23=VM/RroD2NF]L2DZiEf"acIr1$a
-G_^-iH#SX\It2BmFa&UXKmIZqEd`OVLj!rtDM*:RMfO2tD23=WM/RuoD2WI^Kl)TiF,=jeIVjsa
-H%p0jG]AU[It%lDM04&uD2!4,mFBbArn\"?jlY^hlc7r6aD(Tf&o=u<lIFkDe^Au:gt-eLjlX]H
-J,~>
-%VO>Cf[S7'hr<SGk3B-WqK2j_H$8Rt!I8n`FTH]2o5t+r^iSjb%!IJuMq,MXMjr"5G^/Lr"dm\Y
-^8c;PF`2GIG'\CUGBS.RG'S:uQ$7ItG'S:UH$4L[G'nOZI!0j^GCFa_HZsp`H%'scH?XmaI!p3h
-H$XsaJ9uKmG^Y'cJpMcqG_(9eKmA-!GD(?iL3S<#G_^WpKm/<#HAHj!JU!#uItr6'IsQrtK7c71
-M1'l0H&-rqMgL)1G`$ouM0Xl,H&R*%L3ST)I>W?*JpE<&Jr"Z0IXI*#LP'l3I"@-!Mh-58H\R8G
-H&[9'Mg:22H]WW0Lj>&2J;ni4K6iZ-Ko()8J:ET*MM-8:I>!K'NduS>HAR?$OF;b?G`@9&O*c\;
-H&mE+NHpM7I#r]1LM_<tIY!K(N.QD<I"mH&NdlS>HAdE$OaMk?H&dE)Nd?S9H'!H-Mg:;4IZJi4
-KmAc.K8b&7JUNT+Lkg8:IY*Q)N.FsneCN=,gYUiIj6#Of_qrqcB4tsmCMgKAkgA89f$]#7g=LYK
-jQ=NFJ,~>
-%VF8Ag=Xj1i8s"NkO#sXqSWHS`l7>`!QN+Q_u[iso>C^WkJ?N'%)pNDbjOEQbgl$q`l75]"k;qT
-jk7QH`;do.`5op;aMl3>f%%aZa2Q-=`Q6$=`l6$<`lH'>`l6$<a3)BCaMuEBaN;EE`lH9Bb/q]I
-a2lECcH+/P`m)WHc,\#O`m;cKcGn,Oa3VfLbf7rMaj.oNbK%rMbK\&PaiViKbfe&QaNMiJcH=8S
-a3;`IccF8R`m)ZIcH"/QI`B^Ub0J#Ob/hoLbKRuOair,OdE9PYaNi&Md`K\Z`mDoMd`B_Z`mVuO
-dDsVWa3r&RcGn8Sb0e8VbfA2Rc-ODWb/r&OccjDWair)NdE9SYa3W#Md`K\Z`mMuNd`B_Y`mVuP
-d)OGUaO8/ScGn;Tb0e8VbK&&Pc-F>Vs2m:Ja3`&Me&fh[`mMrNdDsSW`mVuQcc4ATajS8Uc,S2R
-bL"8VbK/,QcHXAWaii&Od)q13e^`FRh?r3&k2tmna5GLhC&McZCpiEje`#'/dX[eAf6F7Uk/p)B~>
-%U%fGfQ0d"jlV^nZ0n\eqHj;A]OpS=!arT_pKmueT3V"q!d'MolsC3@ctf]!8!?o@j@,l*?0bi$
-Q0LcbSQ5Jm&n&Cs@UNSQ?XdGNG0tPC?XdDNIpubr@piqV@qB"Z@UWtXAS>Ic@qBIaCM70p@:s=`
-D.R6o?ts@bDdd?t@;ogiE+*U!@rc$lDIIQuAoV6tD.@]uC3!^)C1_ZuEH#E5ASZErG&(];@;p<u
-HY7)=@!?L#Hspr9@X;^%H!ti9AUS-/G[l,<C4'N7F(Tl5DgZh>Hu<\HA9E!*I;!MG@XW61J7NbH
-AUeH3I:@PDBRjW7H";D?Cjol?F(^&8FF%JJD/Fc4HZ`tQAo`6.J8T1Q@sN61JnK(N@Xi?4J7NnK
-Aq=Z8I:@\GC4To=G\)G@Dgc)CF(p5:Fa7MKCi4]3Hus%RATN0.J8K-QIq*eIB7a`9HXhSECOfo?
-G%Q>>EI;5FE,'o6GB[YMBlAE/IWAdcmFBtjh>lL5jp(&;m)S&9b54I:V!II!iRQSL5s^BE5sa/i
-ha2h~>
-%U%iFe8\0oio?7kXm<&jqJ-.Y_/esZ!c>]&pM0i%V.oR;!e?\<lt[&Vd;uS4;4V*hj\`(FC?oX=
-T'K2%U14%9<GZMfDSL^=Ci!s(DJa3>dt2LREGfW6CiFB2Ec,f9CiaQ5FDZ#<D09`8F_l2?DKfr=
-F_uDCEHl;DF)QDCFEqbNEcQMDH$4+TDfpDDIWTUZDL-VMDh2kNIVjUYEe81UI;jg[GCaX_H#eOU
-H[TjcFEW7RJ9l6iDgHnOKQVHjDLd(SLN%QjDhWCXKl;KjEJSU[KPlKhFbamcIrU9cH%^'iH?=s]
-It2KoFEiLWKm[s!Dh!@XMKO0!DM<L[Mf=)sDi&[^Iu%uqIWLKfI"lQsH$>-aK7J!$EdNRZM0a?'
-Dh3L[N,s<$DMW[_Mf4,uEJnsbLi.urFGt-fKQ)flG_p<lIWLKfI>)TsG^#$_KRe*%EI<LZM0X9%
-Dh<O\N,j9#DM`^_Mf4/uEJnpbLi/#rCJjEKg"P3;hr<\YkN_<LhuVHMr]h/a6q!m8lI+M>f9efg
-MJbgMf]h-VJ,~>
-%U%fGfQ0d"jlV^nZ0o;pqRH[Djgslj!kRI0pUL@Tf!k:^!lDd@m(!SAl`&@cMoh:8nrhbQ\Eg[/
-deAjk^oR:AICeLV]=GPe\\5Vd`p(@Q\\5Sd]t(ef]"P\e]Xb_e]>1tj^:M(j]>(nj]Y)(n^VIIt
-]tM=q_83e&]YD@r_nWn']>;=q`4Wh%]>MCr`4Nh%]Z%S"_n3n'^;[b%_S!k$^W*n*_S+%'_Ss1.
-^V@h$`PT=0]YVS!a1oAha1K=.]u[k&`k0:,^;mk(_n=((^rF",_7mt%_o04/]thY"`kf@0]Yh\#
-a1f=/]?%k'ah5R2]ZIq)a1KC/^<+%+`Os=-^rX.._nF1)_oB=1^qaR']>hb%ah>R2]?.n(aLfF0
-]ue"*a1KF/^WF.-`4X4+_8j1/_S4.)`5TC2^VRt&a2>X5]Yh_$ahY^5]>hb%ah>U3]?.k(aLfI1
-]udt)`k0@/^W=(,`4a:,_T0:0_RYBfe_C)[!9!k=#3bLAa5GRlq`tgilgE<^e_$<V6&KJE6.kP]
-6@]~>
-)-Q.ZdS3#*^6hG_K^Pm0<)ckE`PH_hrj5o/<$PYKai/ON^W2XBDT/0rK7X!GEjWoR<4&F>Zt\+W
-KUg-#Ki@tMBS!s2CUef=9mO^pGEJ_;b'/l&DoK_E?,`n#;cK$i>1`"fdrUc7?0:*mUW9H>RC]YP
-cV[Y@A[':qCk9OFLf]Z&5L,g"TuX9AK#Pj,LAfDN]uQUHCrNH&XeA]r<E<:&>$+d1=BILg<Er[,
-?<:<8<af-7@96f@<ao09?WLT=>@^fE>utW@?=R#I>?YW@@U`GU>[V8IBjb.]>%M8p=);/ND-(O^
->B!eZBj#@]?uB+`@p3kWAnkIh?t"%YDIm!n?"[tVEa`?r>A[tUF^8Tt=`RtXFB`Qq=a"4bFBNWr
-?$BRiDHV*kAp7F$B3fjjD/`['@q9ggFD4s+?YjadG[t</>B4I^HXCN1=a+IdH<bH,>'j[lG$0!$
-B4#sjDf8g*@V9pgG%b3/?>a^cH"1E1>'4OaHs^`2>'ORgH!>?)>C9dnFBNj"@X24!Cg)0nC3<['
-Amp!kE,Jj+@;'jfG%Y0/?#OXbH=CN3>'4LaHX:T0>'XUhGZo3'>]E-rg]$%=i8s+`l0[p*`8KIp
-932$n#u[_ima^.Gh9Tj85m9`Bl0dFqJ,~>
-%U%oIcV-W(]U;;YJF9L<rac=ka2Nb2rOQeDAKu'!bK5Ho_oe]fIESM<NK3qaJ[rpsB"P1d\9Qco
-OJBt<O(A6$FcOLcHG59a?AQYAL7PJnc@VLLJ&fZhDTfGOA7_IGB%uU-epa4PB^+N5XN@eaUVXHt
-d:-ZuFh,]9HB6.iQ=u]P:"#bHWl_YeON>YFPl/pl_TJ]kIET!S[&IVPBP2-oC2.?sBPD<qD/!X$
-BP_R!E,',YE+a**B6.a'E+a3,CNF00DJ40-DffZ9D/4B1F)kr=CN+K2G].ADC3=W4HYmbLBmF`7
-Ir':QBmsu?I;4.NCOp>GH>.kJE.<@PI!'1UD0C8?IrTCWCO:5>K5Pj_C4LDEK5>m\C4gJJJSK^W
-DM2kQHtn:RFG"=ZG&;tOH@9O]EcZnLJ9PgbDgHnJKQD0gCk6kIM/R]lC5$bLLM_QgCPZqSK5-'^
-E//:ZHu"LWGD'^aG&E+RI=>seEcm(OK6M0gDL?DQCPHnPKkl9bCl*(WJ80g\Ee\C]H>A=UH%Kdb
-FE*(QIsYseE-R"MKQV3gD16nKLN.KjC4pbJLi.WiCPQqQKkl<bD1>@Gg"P3;hr<\YkN_C!_Vj.h
-8l\qq>#_Ebm*seBg<=7r6UXM2k3CbgJ,~>
-%U%uOdS3#*^6hG_K^QO?rj)jLj5Io)s4F^XZQls5jl*tmiSr4k_!0D8a2\/?^YIksZJjKth7N+H
-`7!]&`NoKLCrbSI^>HiiW5[fU`6m/LkJ5?a^uOIp\*;\iZEr!+S*][WlaG43S+Z3df&PJleDoE(
-lE7J"]A;Q+]#`mjbI#UiNU4H\f&PMoaQ;F/a8b5BiT&Cs_!0Xlg;pS/['[?M\$iWR[^E]R\@?pn
-]!f)Z[CNfU]!]/\[D',\]sYPa\%];_]=#A^\\5D`\[K5\]">Aa\@K;\]XbMc\%[email protected][_TMa
-_RI4m[_]Mb_7%+j[_fPe^UCth\\Y_h]XG\e]YCki]"#Sc^V%"l\@fVc^q.(n\%fVb_R[:p[_]Sc
-_RI7nGIGB!]>:ql]=>ki^qdCt\\#eg_nEP"\A,nh`O`\#\&5qga18q$[`,ki`OE_$[`H(pa0rt$
-\]D:s_m[Ut]uRS"^UV@q^r3\%]Y):n`5&k(\\Q.l`kB"*\&6"iah#7+[`6"laLB%&[`H%o`jWk#
-\]D:t_Bu_4]=l7n`P8t)\\Z1la1T++[`#qjaLT+)[`?%na1'"&\&*d_g]$%=i8s+`l0[p*`8KIp
-932$n#u[_ima^.Gh9Tj85m9`Bl0dFqJ,~>
-)-Q1[hS)lR6:FIikjkW;:/53IQ(tj3pfBl_:*ZFdCL:,tQttW-Fo.?D[SZaEW6'A<>i*DdohE*5
-6gq$\:eL^^FC+']N2Usi:"5N&]781UpQi:(aeFs=@eus"8l!-^8[uW"p25uQ6.M]ZiH<jn[,$"1
-N]g-4[a&>k@H;u]k&$%A4jBOHj*'%<k`8eM9_a(gT5!28DYo\oLsejj;-6Rn<DQ^q;HQas<Dcmr
-='&7(<)cCm:g-pu>u=X+;-m4%?Vk$3;diR+>u4s2=(G39?;tQ<>%CKA>ZPK9?XZoJ='TE9BO=hV
-;dj38C0=hV;JBN?D,XnV;fGuHIrA5"A63eN@;AbZ?!D5FBOt4b=C>uEDdcgh<G,uGF'<!i;fQ;N
-E`Hdf<c_MRE`6si=a!hYD,k[a?ZT.aB39@YAT(Oi?s[nRD/!-t=CuMOG%"^"<,QGQGZeTt;g)YV
-G#`Bp=*IkYE`7*l>^'1`CfYac@WPIhAm0F[Bk2*]G@"^!<,lSSGZJHq<H_bWFB!0m=a4%\E)_!i
-??K7cC05^aA8tOjA6j@YCi!0s>[qeQFCe[#<GHAOG?n[!;fZMSGZI/thVR/LjlYakmdBQ4_r]au
-N8s'_keXChnCQIph>kh"5m:rgmdB($J,~>
-"^0sBhRlhd6k=A%n>]5f>AMl\VnIZU@8[#.,H'@>Bk?.nG2e7+qjG[=>k`cLb^eD]i5hP_=MV^J
-n#g>0<rQ<QCZL;7Y(?(Det&VPM:77PS@imdVO,JEq5I_&>Jle.]u3S;G*qAcf;=8^I,'([gjs%$
-8m>N4dVN];jbeNNH'@Pcd%Z9UIG(+TQ=FT7pP%:sFQ&.'qO(NNdoTm^@U*;K?"@8KA6`YR?=mMQ
-AR/qV?tWbXA7'(X@qT(_s'f,H?"dkYD.$pk?>X7`DI.*n?uTOdDd@?r@[email protected]#CL_Nq
-DK0'/AnZ?pFDYN5?uC$nG\Li8@!$?tHX^f7@!QL"H!k]5@XDX%G@,Z4B7+-/F(Sm0ASZQuHZ!GE
-@<-L"IV3GC?[?[&IpmA@@=N!+I:.>AAV"?1H=;8=C49T:FC]r5E-u)EDJ=W0G]mVLAo<$)IrK(P
-@Wm!+JnT"M@"**.JmrhI@Y&91IUIPEAqFN6H=DD?CM\K/HZWhO@rZj(J8K%O@<m!+Jn8kJ@"3*/
-J73YGA:eH3I:.PDBRsW9G[l;<D15lAEb9o4FEq>HC2AB-HuikO@nc1AgtpuKjQ>[km-j>XinMS5
-i8`n]^8^Mge_Ag4h985S6tbcNmGC3[~>
-)-Q1[hS)lR6:FIikjl6FW2R#g]u\a6s,i`KW$B^RTq.Y?]Vb,,]DoM#e"Zl>akj2aVX`BUqO-<m
-MYY;`R%jSYGd$\Ha3:[^OR'[$f"BtOqnLp[il/XfXoH>)U8[%YT\nCTs.IO*N:"H`m],QTgutf1
-\r3Mcgu"WoU@PFgnZg10M<_mfn#PZfoXC0WT`;"R_kc_5\Gs.&`S[5cWirJ)Y,\Y+WirG)Y,SV*
-Y-4k2XfSh.Ycr2LZ`C77Wj8e/ZDt.5X0\k/ZDt45XgG+6YcG15YdLL>[email protected][BQdB
-X0T(4\?<*HWjo@:];r<IX1GL=\Z30GXh1X?\#R$DYdpdD[]R6EZF['JZELsD\%/WSYd1pB]=+lU
-XgYdA]s4hk]WA]QY.h$G\u`QMZ+R0K\#mBI[(EEPZ`q-E\@A]VYI2!D^9k/ZXh)$F^Tb,YX1l!G
-^9+rVXhV*I]W8`SYeI6L\ui]OZb3BP\$*QL\%8]UZEh0F]=4uYY-tsD^9b,YXLbpE^TY&WXM2'H
-^9+uVY.q3J]W8cSYeI7>\MUG'Z*_0E]sb,ZXgksE^9Y)YXLu$G^TN+RhVR/LjlYakmdBQ4_r]au
-N8s'_keXChnCQIph>kh"5m:rgmdB($J,~>
-)-Q1\j6"3U84n6hp%G:J8kO!_cH!2+p.e3Y8gD'\5Y,&S@nG[>E;)i/[RKn/alC.Y@bZl[p-cBt
-6B0.4M+IS;J%W8&E.7:^jNkiOB&]i0be@B?d_iV(pL-N_9#$?UZarHrDN<d?d?gQp_:!V5\j/eV
-7nQD)Tg;4fqasNUFGT3Dbak3k_9o7[9LVKJp3-:I9\kqLpJ+;2ej2r*9i4e^<)67g9N"\\<)$1f
-9ik.f=%u[m9it.h<D6Ik;-@*u=B&%#:K:Ol>ZFX.:g@4#@T-?9:LI4#@o6H8:M!L-A5Hc<;.id4
-?Vb65=_LWD?;YQ=?tN8N>$,Q<ARJDQ<aKH9C0FYS;e0<6CfanV:ha-6D,b"TIo1#a?>WPU>ublE
-AS+hY=^5fACL:"\<F]]>DH^7^;ef]=EE6O_;/TT@Dc:=Y;fu/ODGbFZ=`dVYAQ*\Q@W54c>uu/K
-C1gIf=^Z5IEF2^h<G6)EFBW!k;fH,DG?/?l;KQ,JF&Qsc<-D>SD,PF[>BEh\A5dYQ@rG4b>uXsL
-<,6)EF]`'k;K?)FG#`6i;fu5NEDgd`<HhJWC/T.W??/t_@8qGO;F'U*hk+1[?=[ZTn+H:ijke4A
-k2tmp`NA\(g>(QAeT!l@7SoiGoAr;h~>
-(g6(ZiSq^Q6pu=[na`VP=BKh1d`Sn>p0%>r,K%5l<bD,C=QG`opJJK4;YG@Yjho;Xh33'V:qX>8
-QHdg?=8l<2=i.bbG_tp$jjM;ZDr[t@cGX>Qf#PF=p1[H-=N6V,\@kZ2G*_5\e=<?(`RTIG]h;C+
-<`iJVVbpK@qGpbnIZ`qec_@'%`RM!e=]JO.p3l^W>Mtuqp/kFVfM,OV>$YE`>%(W@@U!8J>@UoG
-@U!AL?"@/M?s@5J@:WSU?X@GPARo%]?XmeTC11Ib?"dhUD-pgj?#4%YEF3Ep?>s@bE*dHp?ZTUk
-DdINsAoqC"BjZ$mCiNd(An?-nEGJp+@V^$kF_50.?u^$jG[kN3??^'mH!t]2?[?9uG[GW/'k2N!
-E,o?5B5)["GAL]:@rQQtH>$uAH=:u7@=;[)G$fQ/B7"'1E++6-Dg>];C1_p(G&h#?Ao<!(HYd5C
-@ruj$IV<PG@!Z["J7N_F@")g)I:7D>@Y&*2G[Pr7BmsK8EFFB/E-bo>CM/-+G&h#@AoE$'Hu*DE
-@s)m%IqNVG@!c^#J7E\D@")d*I:.A=@Y&'2/U(TOBki')H#I,BARJ0qh;4]0?XR8MZgRDR^u=.o
-NoT9blG9Rjo%2OLhUHTF6j62Um-rt"J,~>
-)-Q1\j6"3U84n6hp%GnTUSG6ehqQ;Ss,NiQUEeXBOJ&QNR%NlV[/Z$;dZsj+j6bFQT^T7ls,,X[
-PJc8=`M*7*Eo57#U:^8gn_i0FVXM[\hV+:`in;\Qs-T@OUZ&MNgXMAcTZ?VZlat71fA`g\e;g2n
-Sti(G^QbCuremKHVo8=akeP11fAagLNLZW=s.oU`U@,V!s,N_dj,^"7V5C2eVl-AjUo1/eWMZYq
-V6$SmGH@X@WMQ_oWN2ksW2?\nWiDntVl6\mXJi&!VQHqrZ)=V*V6HqsZ)4Y*V6Qu!YbeP'VQm&$
-XerD'XL>(6YG\n1YI(49XfJq0Z`p@:Wirh-[B6I<W3W\+\#Z[?VR<S+\#HX<Vmi_/[\pL8W48h2
-Z_t75XF@UU['-C;Wj/q/[]HR>W3ie-\>ld?Vm`_.\#?X<W4T+8\>Qm?X1P@=Z`(L:YdgUAYH#46
-['ZdCXKT14\?DmEWjB+2\ui-GW40"0]W/9GVn0"4\u<'BW4T(8\#6d>XLbC>ZDbC9Z+-^BY,f16
-[BlgDXK]75\Z`$FWW0=lW4K(6\Z!$BWP#7;[AUU<Y.CR@Z)G=8Vge!hhk+1[?=[ZTn+H:ijke4A
-k2tmp`NA\(g>(QAeT!l@7SoiGoAr;h~>
-)-Q1ak2tjI=a0!"p@bCK8kN:7V-RMAoj^\p8gBh^Htd9LR!@S-E:uc0[RKb=XjCKb:YUeIp-c4'
-:ip-]fKoI.(kM2%7YL8&c_auV<6EpCmB0+&Y?k[?p0dkl(7qEqZarKsDN<d?bc$BZF'htQ\Nskq
-r^p>!dWB8FjF`!E?ARl.baj"?G@,IQRV->5nqZ"mGi*RUp.S)NY<boU:f9td:JOk_;Gg.g9i+b^
-=AVgq9NG(e=A;[o9NY.h>>/.!:0^On>>&7&;-m"&>\6cA;H@1"@9?E;:Kq+#@oHK>9k.C*B2;f@
-:M<d3CJSSO;f5K>B2<>J=DL`E@T%)C?"cuL>ZY`<A7JMS<Es65CL1"X;.='5D-("Z:MjN@ED^7[
-;/o`DD,4tW<H:rGBi&bQ><?^uC1C4`;djE:E*QOa:hXB<FB)df:39iHFAQ^c;g;APF&6si=EmbY
-D,YX`?Z]+bB30@WB5UUk?=%u#;/g2LGuS?o;0H;OF]!$j<I%VTEDUge>BWn\CK5U]@WG7e@p+"R
-CMZsp>$uDJFCeR!;e^)IG?eKs:i^2MGuSEp;KlGQF]!*k<d@\VCI%7CjBt8?84lL$p%J!pjl"OH
-k324#`NT"/g>(QDT0Yc%F%T'cp>nVk~>
-)-Q1^ioT=?;g%0koC]%S<E3SZW+K^^okmn2<?n-oK5khbT7Q$HGkOtF\kqsTZI3H#>2><dp.r-9
->^^J+fM2<E(l@\-;iC-Ed]-nm?d7>Zn$Z<@ZY*r\p1XG*(8S$3\%PN0Fd1uXc`N;jH"UKm]M*:8
-r`(GUeU)@_jG\lWB92@Jc_?!QI;"#jTPnjUnrM_*KAq<#p/Y4h[7jh+>$?DV?<C?;=']'5@9?cA
-=(,<:?rpcC=^tQ>@om8K>@puH@9I8J?Y*;O?X.;IAS,+]?!qAKCL^Xe>%MANDdQpi=D_\VF'E9o
->&n(^E`m<p?$0CcDcq0m@WP^jC0bsfAoLmoARTacDf/j*?tXO`F_P6->]"CaG@G-*>'4U:@!Z'p
-EEmd"ATh7!CgVNoCiWa*ARp!gF`(Q6?>F[eHY?r:>B=aiI:6l8>'k$pHsC`6FC'H,C3j'2D.8!#
-EcbT9ASHKpH>d5A?#XslIV*5>>Bk*pJ6m,;>CL6tHs:c6?[uO#G[#T2AURg+EaO<*CO'*3Ch%p!
-F*(`<@qp<nHYm5A?#b!mIV!2>>Bt-qJ6d):>^g<uHs:i7@";U$E_>WRiF;dS+[nnHnal@fj581D
-k3)$q`3&V%g">0>SjYu*DFR1Vo&;rc~>
-)-Q1ak2tjI=a0!"p@c"PS=HG<`LEBorLBJYS0Q2@Z`L:q]smF&YQ'F4dZFC/e)?gfQ0tu^s+f7Z
-RC&gFk)oV4(q]M!NP51Iji3d[S)ib7oZr]ZbaY,ms-N_T(<aU`f[Pr]T>U5RkJk1&VOX%'duLKM
-rg[TPiioPkn?KXoQ,*-IkJ4@kW19pZ_5aW2r35S)\F$&ks,<Jkb);p_T:VRGSXuUJTqS$PT:_sO
-VP0Z[Str-QVOsQYSu/6TVOjTZSu/-RV4FKXTrO]]VOsl]USs`_UnOf[VP\R0WhH2eSuJNYWh-2k
-T<P2hYb/%tTsCAjY+MqrUp-MnX.cemVllYrW2$VjX/r#"USb5eYGe5$TW5)dZ)"8#T<G5gZ(\/!
-TWt>iYb/(uU9^JnYb8A$VR)r"XJ3+sWj/2'W2?qpYH=P,UT(Mj[&Kn/TWYGCTs^\qZCeJ'UpZkt
-YG&A#W3W&$X/!(rXKS;(VPgbmZ)j_/TrYDj[&9e-TWkMl[A'\+T<tPn[%OV)U:$bqZ(JD&V6lnu
-Y+`8!W3W&%Whd%rXfnG+V5U\lZE'b.TrbJk[&0b-T<YJm[\9b(I-f_N?pR+M8kL1Pp%J!pjl"OH
-k324#`NT"/g>(QDT0Yc%F%T'cp>nVk~>
-%U&2]k3)+!h<">'p@kFKr^mE2[(r&2Y-`QTE[,.c^q4H!Zb1rSB[&o9R7!^^@@Y0<>e,&lbsHEk
-IBgMoE+o5k).?peM`l:)4))(;R893V6HFC>@^3_@>g?CL8q1Kq>b%<Nc=)4:4G:anMS?`@R@?Kf
-_ECL`>,&jE@!&rlF?Oug40O?2N4llGEOruP9VT4DZ+PoVABdYJb%XF>:f9td:/4b^;G^(e9i+b^
-=&2Xo9ib.d=ADdp9ik+e>>A=#:0^Rp=AE+#:gQt&>>J^+=("g3<`*@'>[1l:@T-B=:h*U*B2MuB
-:hE[.BMrJL;f,KAB2NGI=DLfH?rCiA?YE;O=]T?;ARSJQ<aBE:C0FVS;e'<8CfanY;Jf]=EE$L]
-;K#ZBD,P.U<,klJBMrbO>AdAS?rV,G@VSbY=]mh);e]]>E)pLe;KH&FFB!$e<-;ARF&R-f=*Rb]
-CK,I]@!#@f@TI_TBl-dk>[DPPE+Dsn=(lMNF^89UF]E?l<HhPWEDgmb>BX"`BN97ZA9(Uj?WhSR
-Chcpm>%2POF(&-p<bcGMG$A?r<,lDKGZSTs;fu>OF]<<k<HqVYE(rU^jQ<CQD/O60_=mTq^uXV/
-DghV;&q@akp=n3Yk1tKWlJm;ro_.B5J,~>
-%U&)VjlYgmguS"sp%P@Sr_Wo?\AF\@YI8u\G9^mu_n0o0[_[ejDU2"MSkGimCSSeQ@_@/,cV&E%
-K<i>(GB!P*)/!NrO@Xc@6u]WQS5u/f9uqiYBXPaO@aAE\;0$NsA"TGectS-K7>Jp-PJFnRSY/T(
-`C<^%@&V#TAUD)+H:NJ)7'VYKOhe\VHG.4`<2I<W[)%eoC<oacb]-Q[<`W+#<)m.$>$"X-<*<F(
->uk!3<*`X+?WC98<+/p2@T?`?<Ff09@T6i?=(YKA@7XF3=^5Q>B3eVS=(5Z?CKb%Y<bYrDDcpXb
-=)D5LD-1R`=`IVVCKGF\?#Wq^Am'1ZAT(Xi?sRhVCM6jl?"@nVEFE'n>&%ea=`n%\E`d<k>'=+c
-Cfkdd@WP[kAQj7]C2[3t?X\.^EG8U%?"n@^G%+j(>B"@]G[>*,=a4F`H<Y?*>'aOgG$0$#?$fgp
-Dd%EoATq=#B3]ghDK/g)@:XUdFD+m*?#4RbG[b-#H!59(>C0[kFBEct@!Z$sCg)-lBQ[I&A6sUe
-E,Jj*?Y=ObG%Fp*>]4RaH!k3->'4I_HX(E-=a=FcGZo3'>C0XlF&PZoiSpbKBk_C#^@V'j^>n5&
-EIE:cJpk?)p=e*UinJsQk2CZgnFYd-J,~>
-%U&2]k3)+!h<">'p@l%Jrf[Sbcdodsc-EWoXWsXXf@-CgcIT(JV;d-J]nseYT>T7)RFe:1ie+;c
-XjGVHTq_Og)5<eTY_TF=J>UWC^6?FXLYS_bU!;0*RcBJ.PA[2QS]/@"j-?t'J[X7/\^]0)_nLr2
-gOk]RSAj+.RAnWcTn9Q(JC1Q^\^T*,VUX5/O2o_Kc.94PU>gs#i1#jmQ^3l(QBdo(R$a2.QC=;.
-SX>b7QCF>/SX5b7Q(=;/SX,b6QCXA3SsH%:Qm&/hSt)+?Q^aV5TUD.?Q_0h8U6qIDQDC+>W0j9S
-Q_p:CJ#A[0TU;[HTV\!PS=?FEUnO3TR\6LEVOa3SRA6IDVjj<UR&6FDX-of[R&c^LWL0ZWR]MpQ
-V3n<RT;e3VTUDmLUo'N[SXujLVkKN[R\QgKWh#Z\RAZdJXIGu`R&cgLX-ol]R]N!QWL0]XS?/-U
-V4"BSTrFH[TUW$OV/)rrX.5i_RAlmKXI>u`RB)mNWgTf[R]MsRW0jWVSZA0VURJ9RU8XH[St)mM
-Vkf`^S"ZgLWh5c^R\lpLX.5i_RAljKXI>u_RB)jMWgTi[R]MsRVj)JkjQ<CQD/O60_=mTq^uXV/
-DghV;&q@akp=n3Yk1tKWlJm;ro_.B5J,~>
-%U&5^k3VO(n+?>Ip\pjJrC$oT4$#Yp:QGF3,@Neu3]f\n3]fVr5<VFr5smat5s.1l697M!4[hRr
-5W_"sO8b"SBL>'I6:F(%76ipq5Xde#697M'5W_"l5Wes6(Irk)6T[S"4%2:s6p<[u4ZY\m4$c:u
-55mu>5s%+i6TmIl6:F%$6om\&4ZY\m4ZY\m6U*^u4Zc&&5='UE4[i"77o2fL:Ie/R85MiM:.A,R
-92e>X:.S>U9i4AY9MBq87oW;V=@uCk7T`M\>"Map8mY7i>=_st9OC@l=@lps;dW(&<_['r=Be@-
-;H.1!@U)ZB:0M*uBNJ,F8mkq!Bi%oA8S;.&BM2]=9l!U0A4^K<;JJj4?VG66=Ck';>Z#?3?Xl`F
-<EEm,B3e>N9jV@&CfXPN8nD=*Dbj^rAP$fB<c:WD@SUr@?#3)P>Z>c;An=\X;d=35DdZLc:1S$4
-F')Ua95S-9FAH@\9QO?>C2cj^@o7>E?u&DU>?>f<Bk1%^;I403Ea;[c9kS'6F&ZF^8oS-:F%p4Y
-:30H?DG+kU;fkcEBh`YN>&R&M@T%;D@;8GV>$,`;C1C(^;.+03?U!f<k3)+!mdKiBpA"O#kiV$k
-mI'E4rq6Ehi7Itj!:'RO!;$3`!U)k#~>
-%U&,Zk3;0umd]oAp\CXTrD3\l84Q?K>aGAN,ABkD7n?EK7n?BO91i#O9i">Q:.RlI:.J)Q8l//O
-9LqZOR/W0bE)02!:/FPU:eXDM9Me;S:.J,W9h7cI9M#.Z(K,pA:.S)R85MoO:eF;S8Ol?J852oQ
-9E%a):.RlH:J+,J:/FPU:Ie/U8kDTM:.RoN:]=%291Vl[9MU7r92S\i;-6ar=]&=(;d31&>>ea-
-<ErF,>#\j.=^4g5>#o*2?!UE><a0!1@p<#F;da!4B3AGM;eKH>C/n\P<,5]DBN&SR=Dh2MBN/kU
-?#3MUAQWqS@qnt^?sR\NBkUUi>@VPMEar?q<bcB!=*._WDcC^f>BEq[CKGXb@W>CfB3TO\BPgdm
-?t"(UE+iEu=_DVPG@Fs(<cDkYH!G!&<Hr(^G?8^"=a=:cFB*Qu?@#[jDch?nAT_!sBjH'fD/`R&
-@:XO^F_Y0/=_i"XH=LE.<c`%\HWt3*<I/1aGZSm%>'jLfFB!QuA7'U`E,Jg*?=n=[G\CE0=Di%Z
-HXLE.<H`(^HWY*(=*e=cG?/g$>^T[hE`RKr@X(ppCg26jBld9g8a56rk3;0un+$#Bp\2D`j6#Oi
-lgF64oChq6f&GcQkj%O&nFH8Gj["C~>
-%U&5^k3VO(n+?>Ip\qLIrJLl9JUrT5O1"tj,F+%:JV8r:JV&`:KnPA8Ll-h<M1^A4Lk1G;KStP8
-L4Xu6\,NQKRYZ`NM2R%@Mhlq8LPpb=Lk1GAM1U;5LP#M`(QGT$M1LG;JW#/7MhH\=KRnc5JVT/:
-L&R!2M1U;4MhZe8MMm.AMLgVBKn4i5L4Ou7MM?e>K7]&BKnlk5Jr>YMN099^P)YQcNg>]fQ&V)l
-O-YchPE(riOd1lkOcPffPEV#qOHZ&kR?N`$NL#l5Ngc&nR#RMtOID/rRZF,,Pb3u,R?=2)R%981
-QB\#&S=5P5OdDW!TU(e7O.Ml(V3@=?Nh`#,UlV(;OJJ,.ToPk8PGF;1Srfb5Q_KM6RZaM/S"Gb;
-QBlTdNhDl)V3.4=Nhi#,UQ;%;Oen5/TT5h8PbX;2S<Bk8S>2+CR['h4Tq@IHQ("M/VONgLOJ&8.
-WKrsKNhr81WK<^FO/\J5VN7ODPGs\8U5l4?Q`#n>Ss$(:S>2+CR?jb3U7[RIPaeJ/Vj`mLO.`.1
-OK"M6UlM=APc9b:Toc7>RAGq?S<Kq7StV4EQ^FY2Un*^KP+A>-STjD^k3)+!mdKiBpA"O#kiV$k
-mI'E4rq6Ehi7Itj!:'RO!;$3`!U)k#~>
-%U&5`m-a<2p%J.Trr8ZQp-\dFhF%6.j?iu;7mYWls$ZlV1.+Q"6q9X86qBO.77KX;84?6A8P2BE
-7n66@91_QK7S?EC:e+&P6r$<A<(9SW6rQWIIoSp7:./,R:/jV_9Lr8T;boea8PN2Q>"hIk7o`DS
->tRjo6s<DX@S'U%6t&eb?U\6t7Ueti=[ZXm9j^@o;FP(g;d)Rs:JG=h>uX4)9N5:d@Sf^-86f1`
-AkZ*07:B%bA4]s,6tK(i?q"I#87b@p=[Zpu;.N+*;FbLr=asgJBMqW>7q,RhCe[u>7;#OnBLlN6
-6u5Uu@mt!/95-t(>=<7&<+SL0<(^mt>[9d5:f:moA5u0993PXjBi.]>7UoIgCeRr=7;,RoBLcK5
-7;P\"@RXp.9kd1+>"!1%<FeO1<(gpt?!Kg6:K(gnAQ;<:93Y[jBi%Z>7V!uK53q@pm-a<2p%J.T
-rqsRqkNVF&n+$,Fp\OpJfB2;^mdBT9p@e:ZlU$+~>
-%U&2^l0Ia*nalJKqYR'XpJ:icrD)6H!)NPg!)M]Qs%rbjfhc9X:f1%c;G^4h:fL=i<)HRm<)6:g
-<DZ^o;-6[q<_upt<*E+$<Dcsu='/:(<)d(!>ZXd1;cm7#?rg97;-d:#@T6K;:gmI*@o?Z=:hEa2
-@8UQ<<+]'9?VtN=>%UWD>?#B;@:;i,CKObR;.j-4CK4eS;/BE=CJneP;K#WDAl3>J=DUoL?r:oG
-?YE;Q>ZYfBAn"VV=^Gi?CgC%Z<G#c=E`uad;/KW<EE-L\:iKTAIVr"u?W(rG@q\\Y>?PoCCLL%]
-=(,i?E*QLc;eol>G$&-g:iTcBF&Zja:j#oJDGY:Y<HM5RAl*SQ?#NPX?W2&IAS=n]>?c&DDI?=a
-=(>r@Ea2df;J]c<G$&3h:iTcCE`6^_:j,uLD,>1W<c_5RAPdMP?>`SX?;u#Hs(3u^FBVpg;/T]2
-l/h*mlgF64oChqTq7c"RkN_C$nFH5Gq"rjsjQGamm-jH8p%S:F6%A~>
-%U&5`m-a<2p%J.Trr9<RpP]*1rJKHjrJKZp!f`4te;XEes,LBDOH#6\NK9'[M2[IUN0'-\P)b]g
-NKoTeQ&V#jNL#TfPDtihO-P]hOc>ZfPE_&oOH>iiQBI5rO->igR$!GsNg>lgT95A.NLZ8qSrf>,
-NLl>tSW0,(O.MH%RTYWDPE_]"SsGG3OdV\uTp1b6Nh)MsUQLq6NM)N!TT>V1NMDZ'SW0;-OeIi*
-R>mr(QCa).Q&q]$R[T54PEqo%U6^n;OIVf"V3@1=NhMc"V3.7<NMMf'GG^FoRuOA1R\Ge;Q]n;.
-T:Cn>PaJ5*UmR=COIi#&Vj3UENMDo(VidOBNM_u,V2_4<O/J/2TT,h7Q)0M7RZ=>1R\>_;Q^"A.
-TUUq>PF8/)UmR=BOIr)'W0E[ENMDl'VidRBNMi&.UlD.;OJe52T8f_6Q7\qnU7$8lk321"mdToC
-p\=ac_!'tGmdBQ6p@e7Ws5;Mkkj%U(nFQAIq#'GEJ,~>
-!(-Umrji*Ark/>d,_7+i+b:fV+TaC+[/IK5\cBAA]`P7B[JmW8\Gj&D]Y2"dZ*^t=[fEu<])TGE
-[Q/j~>
-%RIM/['d<M\%&rZ]"<\JJL?!rfdD=tmNsACZa-pE[C*HP\@B,]];W$@Za@-K[^WcW]">8NZEpmF
-[C3NR\@K2W3.L~>
-!(-Umrji*Ark/>u:4Yfa7"IbG6ipc([/IK5\cBAA]`P7B[JmW8\Gj&D]Y2"dZ*^t=[fEu<])TGE
-[Q/j~>
-"'=dJ]_M@(qLS?kp4;qVp&OjCqZQ#pm+4OR~>
-"'=dJ](l.&qLS?kp4;qVp&OjCqZQ#nm++FP~>
-"'=dJ]_M@)qY,R7JbFZg`qBE-h>7?:^?jH;J,~>
-"^19U^&R>Jj+66Aj-ep2fTs);g-U;~>
-"^19U]Dq5KkCMfIkF(K:g6B)9fg1,~>
-"^19U^&R>Jj+66Aj-ep2fTs);g-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&QsgeH""p_#_iuo[O>p_U[,OcG@rZe]Gi&eH<\)_9_W$!R/ITeH!km_$.d#`RVlNJ^o>%
-J^sPG"iGu'nCg3Z~>
-"^19U]Dpmig&T\$`<"H-o\']%a4f1be&Bqmg<Rn5g&oC7`RF>1!R]!^g&TS"`<FB0b1anaJ_G\/
-J_KnQ"il2'nC^*X~>
-"^19U^&QsgeH""p_#_iuo[O>p_U[,OcG@rZe]Gi&eH<\)_9_W$!R/ITeH!km_$.d#`RVlNJ^o>%
-J^sPG"iGu'nCg3Z~>
-"^19U^&QsgeH_rO='f3?M$rt+$]#5A^As[._U[1>47q&+SK_B);t/<<H5cM-!J:[W?3PC^0%CVe
-J^o>%J^sPG"iGu'nCg3Z~>
-"^19U]Dpmig&e8S=oMh1N=5C4$]>JJ_uQ<9a4f6O4nRG2Td*u3<Ue]CI2_h5!JUmZ@0Ldf0A7(n
-J_G\/J_KnQ"il2'nC^*X~>
-"^19U^&QsgeH_rO='f3?M$rt+$]#5A^As[._U[1>47q&+SK_B);t/<<H5cM-!J:[W?3PC^0%CVe
-J^o>%J^sPG"iGu'nCg3Z~>
-"^19U^&QsgeI8;T`7:P6M$qF'8k-hreI[NFe\;*H/[]G'9fp3Q8mop>eJ`-[\!SA^<D#WtV`[@m
-W%EcVLI".hH5;0*a8+7%K+c_bKh>r0LB]?M>tR5s=D:BH8P2e"J^o>%L"-@EK=UL*6@]~>
-"^19U]Dpmig'jt]aP*FCN=4$29M!>%g(9/Og;EuV0"Gn1:-HWZ94H<Eg)=`c]UU4m=%l'*X$&q"
-X=fA_MF'[email protected](`4oLeDG8M?bcW?VEW(>&6lQ92&4-J_G\/L"Z^NJ[b.%6%A~>
-"^19U^&QsgeI8;T`7:P6M$qF'8k-hreI[NFe\;*H/[]G'9fp3Q8mop>eJ`-[\!SA^<D#WtV`[@m
-W%EcVLI".hH5;0*a8+7%K+c_bKh>r0LB]?M>tR5s=D:BH8P2e"J^o>%L"-@EK=UL*6@]~>
-"^19U^&QsgeI8;TA8RA.M$nhJeLYD0eI[[email protected]'!/giP.m$Nqd/]R/eJW9PCUAd+eM:W^T;hmL
-!$5eSP,iPJ%@\_^q:-:6$#P$.-"\d['7uGKeNd(m!)b]hUiiPceUc8)eHNjC\a\<>J,~>
-"^19U]Dpmig'jt]B5j"7N=1@Rg+@(8g(9/HE+As/!0.&W/3Qj"ec;68g)4lXDRbK5g,!;iUTOTW
-!$>qVQ*57W%A,%fq:ZX>$#k<5->>-e'8;bQg-Sh"!)kfjW-G=ng4@t3g',NJ\+&':J,~>
-"^19U^&QsgeI8;TA8RA.M$nhJeLYD0eI[[email protected]'!/giP.m$Nqd/]R/eJW9PCUAd+eM:W^T;hmL
-!$5eSP,iPJ%@\_^q:-:6$#P$.-"\d['7uGKeNd(m!)b]hUiiPceUc8)eHNjC\a\<>J,~>
-"^19U^&QsgeI8;TUU$$`M$nh=8hPMeeI[NDZCh2U!/gij=Z]Cr8LL>0eJc04^E";J"\LFmT/Sh3
-MZC'5!g;*aH5b<]D>D]uK+G8rE$]*KeJ!P!!(o"_2bqW9R3b2<J^o>%L"-@EK=UL*6@]~>
-"^19U]Dpmig'jt]Vm_ikN=1@D9J:nkg(9/L[\Nn`!0.&q><Ph$9.6_6g)@iA_]9bR"\^UrUGt@9
-NW?NA"-qToI2^ffE;A3(L(C`)E[GKRg(T1,!),1d3)J&FSL-bHJ_G\/L"Z^NJ[b.%6%A~>
-"^19U^&QsgeI8;TUU$$`M$nh=8hPMeeI[NDZCh2U!/gij=Z]Cr8LL>0eJc04^E";J"\LFmT/Sh3
-MZC'5!g;*aH5b<]D>D]uK+G8rE$]*KeJ!P!!(o"_2bqW9R3b2<J^o>%L"-@EK=UL*6@]~>
-"^19U^&QsgeI8;T`7:%PM$nhJeU*e]eI[NFe\;*B!/giO.Q^Epdq#l^eJ_LPeW0og&(Q,r-u>m`
-MZClL!g9R#H5b<]D>D]uK+c_bE$]*KeJ!O,!7cgc2dOt*Gb>OmJ^o>%L"-@EK=UL*6@]~>
-"^19U]Dpmig'jt]aP)p\N=1@Rg4#[ig(9/Og;EuO!0.&V.m6a!fOh\ig)=-Yg6)Yr&))T).;u?h
-NW@AY"-p$-I2^ffE;A3(L(`4oE[GKRg(T06!8<9o3+(C6H__.!J_G\/L"Z^NJ[b.%6%A~>
-"^19U^&QsgeI8;T`7:%PM$nhJeU*e]eI[NFe\;*B!/giO.Q^Epdq#l^eJ_LPeW0og&(Q,r-u>m`
-MZClL!g9R#H5b<]D>D]uK+c_bE$]*KeJ!O,!7cgc2dOt*Gb>OmJ^o>%L"-@EK=UL*6@]~>
-"^19U^&QsgeI8]:a46n>RlSYm8kI,"eI\01e\j/30Xbt1C0nkA8n?6CeJcFm8j\T^=\;0(W]ad/
-5qpO5NC#mtO$qMoL&'78Ps3aKLJ<7teX8\2@7ic'>C"c@9hJ@,J^o>%L"-@EK=UL*6@]~>
-"^19U]Dpmig'kAEbhApMSiY5#9M<Y+g(9f:g;u+B1:hO;D.1RN94lZKg)A.$9LG#j>>.T3Y!6E9
-6Sd'CO@2F)P"+/%M##a@R6]K[MGJh)g7:RB@n]/1?$k;M:/"[6J_G\/L"Z^NJ[b.%6%A~>
-"^19U^&QsgeI8]:a46n>RlSYm8kI,"eI\01e\j/30Xbt1C0nkA8n?6CeJcFm8j\T^=\;0(W]ad/
-5qpO5NC#mtO$qMoL&'78Ps3aKLJ<7teX8\2@7ic'>C"c@9hJ@,J^o>%L"-@EK=UL*6@]~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]AqOpeUc8%eYLahe-4..^@9iCJ,~>
-"^19U\`V_!g4@t/g8*Hrf`fg:]^XT?J,~>
-"^19U]AqOpeUc8%eYLahe-4..^@9iCJ,~>
-"^19U\^e0?Y(<a,Y,8?'dFF$HK*@7R_!p&EJ,~>
-"^19U\D"cM\q.GD\u*%?f@kuRJH^tP^@9fAJ,~>
-"^19U\^eKH\q.GD\u*%?daa-IK*@7R_!p&EJ,~>
-#$LBV\^c7IJSp$VJSqH)"`L*aeVBaqX9#AerN$1XkJ6T@6@]~>
-#$LBV\D!1"JVJ`1JVL+X"Ld%<L7eIK!Nq^dY6E_H^@9fAJ,~>
-#$LBV\^d1/JWPGEJWQgl"ME=9LS"LH!NVLaX9IDB_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP"hO-ReVC+&]`R5W\Gj/Fp?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W"lfR=g4l[-_?/e]]`,bOpZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro"mc3AeVC+&]`R5W\Gj/Fp?06\g-U;~>
-#$LBV\^c7gY,hr+S"$@XXJ;8SWe%7&XG3ea]'e2#LT%o"d.)pnrk/L/kJ6T@6@]~>
-#$LBV\D!1KY1a30`5L3[g<[^UfR_b-g4n;hir@lhL9&2.eFA9srk\j5lFuc@6%A~>
-#$LBV\^d1YY3$&Hcd1S4k1\/-jFQHEk(`"+li5YgLT%o"d.)pnrk/L/kJ6T@6@]~>
-#?gKW\^c7gD#RcCVQ?$\?NHOOrEff)XCYb=XK8B"?NcmR?XIgKX9NZO?\PS_RJgItO^DY#UL.ej
-rEfYh?XI75X9tq/9hf3#T2nZ\EIk3BXG3ea]'e2#LT%o#l0kp8rk/L/kJ6T@6@]~>
-#?gKW\D!1KM>h`$db;A4GQGXarHJRmg44G"g=k'UGQc$dG^,;Fg'3X`GcBEN_Yn]a\9NMWcZk8E
-rHJFSG^+T,g'ZDM@UalAa_bKrOFc,:g4n;hir@lhL9&2/lLD6<rk\j5lFuc@6%A~>
-#?gKW\^d1YOT'_2hWDiVIf[d'rI5(+k(eHHk2tV$Ig"0*It*g\jp%3&J$S5!c2E+s_LI=&g4,0h
-rI4pdIt*(AjpL*kB4m"^e8o88R"=CNk(`"+li5YgLT%o#l0kp8rk/L/kJ6T@6@]~>
--X#m"\^c7gG=[RI=e_TDM2>,\?u/;R5aSR+3gZqLWeiEdV42BqOnl'sO\9S]XK83WJVdWR<b8A2
-8p-RVM2=0YM(jhcX9"u\q5aq"6`d@OXH$GbX?;'8JZOU-'Y<_aeVC*:`r4f?PGPt+p?06\g-U;~>
--X#m"\D!1KQWpVqER)cjY-)H5H&>ae;8Cna9#007f<.6=dDV#N\G=hs\6b-4g=jkCUTS^&D1UEk
-?'N8iY-(71Xurodg&]C4q:Z2'<8-&"g9bkRg.[(OJ_Gk4']T/Lg4lZFb5L>JP,H16pZfK^fg1,~>
--X#m"\^d1YT4#.;GhL_7\$p7VJ<=0+<m'R1:<M_]j0q:_h9V<q_YN=4_dntWk2tDkXLEPGF,8u;
-@[t_/\$nuQ[m7M&joO&Uq;r%?=m"jCk.Z*&k"pWkJ`_^L'^PePeVC*:`r4f?PGPt+p?06\g-U;~>
-**M^l\^c7gN`rNcIVPrHXEBAcKpl,*I\NolCHVQs!'L7^!K17XX8uXbrN$W%TluHXMd3?X<h-6R
-XEAccX??E^!F$Q>X9tq-='&e2N`iHb4FsSbXG3ej]'e2#LT%oPn(#smOgr*ukJ6T@6@]~>
-**M^l\D!1KZZFjSTSD/og6AbSWP`\`T?Z)^LJ7[#!)3CG!O6eAg&ZE$rRqlfba,WEZ$"dGD8k4&
-g6@uSg._Fu!H]U_g'ZDJDJjdSZuOgR9S(oKg4n;qir@lhL9&2Xn_2^%OhAR*lFuc@6%A~>
-**M^l\^d1Y]m8c&WK$%:k+&p&ZHdX/W7^71O&5f;!)W[W!P3[QjoKn@rT4`!fUfdl\pWYnF3s&G
-k+&.&k"u!<!I?*gjpL'gF`i8t^3Jf&:k@b[k(`"4li5YgLT%oPn(#smOgr*ukJ6T@6@]~>
-&6\G`\^c7gN`rNcIVPrG4<+7#!EbH_X91V:<danJ!'L7^"H-QeXI&db'OHZuVOaeY3#8KpXA>7>
-@B?OV4>Hi:#<])hQ`R9\Q2.KgVFco48?@hSXK4O8XF[I-X;&86f@>YTd/)GGe]j#R^%UX)nCg3Z~>
-&6\G`\D!1KZZFjSTSD/n9HsGh!H>LHg&k*GD4U[[!)3CG"L3+'g;!L<'R-b7d`:'F7i^+6g18($
-HeR1,9KrI0#>Ek*^Y7Da^%p@hdp0Ak>M?H(g=f5Og4@t4g(`QHhV*^beGJ+Vg<ke\_Y<?0nC^*X~>
-&6\G`\^d1Y]m8c&WK$%9:a>r$!Hu9Xjo\M`F/Alu!)W[W"M0!Ck0!P_'RdOSh9tFl9-*$Sk%W)I
-K')2N:dP*C#>jRFb3%j:aSFs*hI4:<@-51Jk2oKkk(2ZLjqR.]g!tkVd/)GGe]j#R^%UX)nCg3Z~>
-*Ehgm\^c7gN`rNcIVPrHXE]McXK5NcXK6VM>[1;.X8kB^X9=GeXK4P\X:AQoXGU>c8"k6fNi\mE
-4T;Dg4KNdMVlW"^X??0W$Dg+kX?<SE=fe\eJZOF(L9(Wkmap!EW9`pNeHi=;^%UX)nCg3Z~>
-*Ehgm\D!1KZZFjSTSD/og6eqRg=gMSg=hj7F`hO"g&OhGg'"['g=f6sg(&>1g95_S>0NG@[+`]-
-9`E`P9\Pkue(RLLg._1n$IMi,g.^5-ESB,?J_G\/L=umls5)IaX6fBTg'FpA_Y<?0nC^*X~>
-*Ehgm\^d1Y]m8c&WK$%:k+T3'k2pj&k2r:^I!fu6joA6Wjoi8Ck2oM:jplgMk.,p&?J)$b^?4!S
-;#]S`;!+IAhr[btk"ta5$JekIk"t3SGin-bJ`_OGL?8a,s4PqXW9`pNeHi=;^%UX)nCg3Z~>
-.9Z*$\^c7gF%(b8>,7fDKS3-OXGfPbRA2`fSV8\ZWe<!XUmPpfKS2A_X<<KnC4p>.U,ICP=EU^G
-@=5/XQnF&F24&tKKS2(]XCX!ZX9tk!KS3($Pur]m;h;$$XG3e]]'e2#LU-TsrPAiRNhlC3_!p&E
-J,~>
-.9Z*$\D!1KP$"W[F3r&jVl+(#g9Ob<_TkZ?a/M,1f;C[-d(tK@Vl*)_g*!_+L8TcMc:+;%E0T)/
-H_&mE^cJBk7),W\Vl)`4g4)-Yg'Z;:Vl+"X]l0gHBn=uhg4n;dir@lhL:$X!rP]&XNMcI8^@9fA
-J,~>
-.9Z*$\^d1YRU*/%H/-q5YcqlDk.=f\c.Ygcd]u$Sj01\NgWPXbYcpgujrh?FNj+OlfgqsDG+@^U
-JYhMkb<<)68'.tuYcpFUk(Z"ojpL!WYcqd&aE=_kDLpr$k(`"'li5YgLU-TsrPAiRNhlC3_!p&E
-J,~>
-#?gKW\^c7gE;jALVQ?*^A.>!/F(Ag=S7H/mAn6@hraZ&#M#CiaGl+QBFo>hOMjsZU#F2BlNgm,O
-M#CiaPPo"pC94LoE;6L@OCVmlXK71fA>XpZJZOU-#.j6SeVDVNqL]!6o&mgXg-U;~>
-#?gKW\D!1KNrFM0e(VP7Igs<LP(.tb`IEBHJq'HDrdOsiXo3_LR/>S;Q2Q15Z,HTj#JJjF[)LbQ
-XSmVK])@*]L>(@bNqh<7[srnIg=iTWJ'ro%J_Gk4#3,[>g4n%OqLJj3o'3sYfg1,~>
-#?gKW\^d1YQMuU?hWDoXL(2GjRYHR-d"[:lM2&"fre:I&[f(p\U&3sPSc+9D]$L>0#KPuh^<l$)
-[Jbg[`VkMoNTTB6QMBSK_1m]lk2s%*L>ILDJ`_^L#4)<BeVDVNqL]!6o&mgXg-U;~>
-#$LBV\^c7gJZOF(JZPiP"hO-ReVCX/b6@\(_!p&EJ,~>
-#$LBV\D!1KJ_G\/J_I*W"lfR=g4m05c3=%/^@9fAJ,~>
-#$LBV\^d1YJ`_OGJ``ro"mc3AeVCX/b6@\(_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP"hO-ReVDWLrs%*JkJ6T@6@]~>
-#$LBV\D!1KJ_G\/J_I*W"lfR=g4n&Ors%'IlFuc@6%A~>
-#$LBV\^d1YJ`_OGJ``ro"mc3AeVDWLrs%*JkJ6T@6@]~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpl"nL%"3?nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&IqqDA"KC8$=nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpl"nL%"3?nCg3Z~>
-$<cfZ\^c7g:HCRbri?cB4,U,@H9+/NG-#I?4?P]Y4??!SX9!g1cE%(_4+VsaJZQ5[#.j6SeVDWD
-qpbqlKCA!=nCg3Z~>
-$<cfZ\D!1KA4fLcrn8$59!?t&Rn6:IQ.h$c9MA*W9M&F0g&[nRcIr>T9;I-mJ_IKb#3,[>g4n&H
-qq;:uJaVg;nC^*X~>
-$<cfZ\^d1YC/.U%roOlH:UoQLUeOZ^T&l&.:f'rl:ekB>joMKqcK51g:T]31J`a?%#4)<BeVDWD
-qpbqlKCA!=nCg3Z~>
-$!H]Y\^c7gXAYA^X8uU:ri?MjXK59cX?<Sc4KP8Hr2]pVI*er0W^BU"SueW&UkjH#XFkA/XJTj#
-D0Z&]"*/6qQhmcoGE8>4VlZtOD47PRM0a$5ri?ERCoj[SENFP)TRj1qXLtV=]'e2#LXYejeHa-I
-n)qLUg-U;~>
-$!H]Y\D!1Kg1S.ug&frMIK%q/9\S34^tMK9g.^5F=T$kRYFX%o("ZGtMTFMqMU/Dsg=iE]NnVs>
-^5A<Wg&mIpMSK#A&!s]FMU^A6V2E1ET!"N>c2QE'SVc(QMN?J^MTUM(J_Icj#3,[>g4n&Hqq;:u
-JaVg;nC^*X~>
-$!H]Y\^d1Yk&&6=joXXlK`:*B;!-nVb2uO_k"t3n?2Wgc\Y[[8(#rG4P1/RFP2!FDk2rk1QKI%e
-ac`@sjo_$7P0*R_&"gVcP2PKbY*.)mVRWCag&C+?VNL$%P*b=.P1G3HJ`aW-#4)<BeVDWDqpbql
-KCA!=nCg3Z~>
-$!H]Y\^c7gXAYA_X:h<s6Dgic3h`6ERB/EB>`>bY7f9=g<ADk%*3)Y8H_IO:4*FtGJ;RobG[[O>
-3.#O`XCcU%=EXJA*,JYVHXEk*Ap[LSH5gaK=f8@&Hu,mb:0XfF321u*JZQMc#.j6SeVDWDqpbql
-KCA!=nCg3Z~>
-$!H]Y\D!1Kg1S.ug(Mb5<79LS9$GLl_:hH(FKsQE=T$kRCd-5"*8"V>SBT^599sjYU9B*;R!dCc
-7\#Bug4>KYE0U4Q*/SNLS9`haJXgN(Rj*f]ER`^rSVc(R@W^=m8'Z\>J_Icj#3,[>g4n&Hqq;:u
-JaVg;nC^*X~>
-$!H]Y\^d1Yk&&6=jq?EQ=l&6&:>"39biVUOHFr=m?2WgcE^A(7*91UUUtFha:S*)sX13q\TRu*,
-8u.Z<k(oP'G+JKl*0G;`UjqO/Lno"GUa2/"GMhQFVNL$&BR8g89A+mYJ`aW-#4)<BeVDWDqpbql
-KCA!=nCg3Z~>
-,?aHs\^c7gXAY@cR?=R4ARIs.X=d"5=/;o?7ldZPU.25cI`nenBn$#^s&8lt%Xqtt7''gPXGpGc
-Ear[-q5aXV-D:@>'d[F&?UgJZXK7=cXK6ecXK71cXE/N8XF[IbX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-,?aHs\D!1Kg1S.R_RJ5lJ9k;Ng,`D@DU7#c>"IB$bui]RTZc$iL7nM!!GQ<Ig('d+HWJjIX4jn$
-g6$f6SGCk?Z7sK$g(c8kJ9b;9@bTP?G1tZ@M;$[aHeOXIJ_G\/]@mJKs5)Iaddm:h#Kq\dlFuc@
-6%A~>
-,?aHs\^d1Yk&&6&c,/U=Lk/gnjum$WFPGq.?;0MDfj3b&W6=<(NN)m=!H)iSjpn>GJQq8f[H>/J
-k*^mYV>96T]/%t:jqTY-Lk&gWB]eHgI-0RgOlkf5K'&MmJ`_OG]B0=`s4PqXe+*=c#KMJckJ6T@
-6@]~>
--X#m"\^c7gXAY@cIVOLGK7dNhX?<Sc;4"@HXH?ScU.25c4KPWYT$OJCBn!.VXK5?cri?ZaA:nki
-XC6mcNE`KXKS*ofqQ'^V>lC`6211%-Lmgc2XFk)cXF+j`X9(n\6\2=iXLbJ;]'e2#LXYejeHa-I
-n)qLUg-U;~>
--X#m"\D!1Kg1S.RTSB@oV58F@g.^5SB#*+og:2%Sbui]R9\S4FaNrQFL7m8Dg=g8Srn7p^I\i*+
-g3]mSZZFjFW25*?qUttUFT'o'6_:-MXi+>lg80>Rg7=*"g&bHq<e8tUg:GuBir@lhL=5Yig'>fP
-mcqOUfg1,~>
--X#m"\^d1Yk&&6&WK"-:YHNGek"t4&Cs(m:k/)6&fj3b&;!-one'I.]NN)'kk2pR&roOcsKs-hI
-k(0r&]m8bmZ*0"bqW7gjHi<(:8#EJl\'A:<k-'R&k,+:?joSo7>(Pgek.9[Zli5YgLXYejeHa-I
-n)qLUg-U;~>
--X#m"\^c7gCFi@i7;>4SH$))@M'623<hY!d?="h;==.?\/?GpK.*nt6Lg"+kXIh(AMQEn?=C+cL
-OYp+>=tuaD<aJpfqQ'a$13!5o'TQ=&?$)M[>@(g@XF<MuGH@mC/q\_VJZQGa#.j6SeVDWDqpbql
-KCA!=nCg3Z~>
--X#m"\D!1KLcB'l=,'aNRZp<OXsnR=Cs8S%GBYRGE%lK[383(t1XFboXE&N/g;u?fYM.^=E-GkH
-[mOrbE^.iUD0L!*qUu!j5E>`s'XVh'G*KosF*E&dg7VG=QeL0A3i7J^J_I]h#3,[>g4n&Hqq;:u
-JaVg;nC^*X~>
--X#m"\^d1YO#q3,>`DocU7=ki\1E&VEn@<BI=3]_Fu+Pp46G[?2UCM)[<R+Jk0uM1\E;qhG("*[
-_FAP-Gs^1oF+&8EqW7j'6^@Z5'Y\a=I%8J8H$tA.k,DN[TB>:m4g0G!J`aQ+#4)<BeVDWDqpbql
-KCA!=nCg3Z~>
-#?gKW\^c7gOSt%AT8SSmP_tHkre^cIXI0!E!K3WLM?K!AXI><tX9XrHV6$POMOjaJ%[N!FMP,if
-XH8=<R>Qleq5aXZMN[q>':"H6XI;nHMPmPWR#6cdXK80kUk,UuXLbJ;]'e2#LXYejeHa-In)qLU
-g-U;~>
-#?gKW\D!1K[f*B7ag&%`]W\Z^riZCCg;3cl!O0cGY6;8eg;CJHg'>3mdG!'QYK-Xr%_f-iYKO,W
-g:"38_QU/Uq:YnYYIXVc'>:TTg;II1YLD4Z_6:&Ug=jk^d"0o%g:GuBir@lhL=5Yig'>fPmcqOU
-fg1,~>
-#?gKW\^d1Y_#:eKe[i<5`jre2rj`*Xk03e7!7q+Z"Ma*]cGRri#K=7/k2*YZdf/A=aLTm4f"&QX
-^q&CI\[fcVjoW?/_u8^2aLSqFc=k)*hra(F\[fcCk1XJ&J`_OG]&j4_s4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7gJZJsT@OG[\X94DX,aa.aJZQGa#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_C4[I5-0Fg&nWm/\lqkJ_I]h#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`['sK/A8Vjo`840[#%0J`aQ+#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZJsTR$*d1X952[P,<f3JZQGa#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_C4[_7@;Tg&oX2\^H&_J_I]h#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`['sbeqNsjoa;S_qot,J`aQ+#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-$<cfZ\^c7gXDp%2ri?ir4?ll#BJV%o-CU/b4Aqc(+ZqklUk,UuXF[ImX9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-$<cfZ\D!1Kg5eLRrn8*r9MfT*KL%@\0Z1P%9PDMF.SNNXc[jf$g4@ttg'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-$<cfZ\^d1Yk*JJrroOs3:fVSBMa]Kn1X3p@:i=de/5T/igO\L<k(2[7jp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
--X#m"\^c7gXK5T)Uo]P[XJe:4@#.pH;1McHXHlbc4KPVkM6*e%?dPkhAo;(!?$EBO<(E^bXD17^
-8!9rY7p5hm#a%VhC94='7s'<`JZPED#.j6SeVDWDqpbqlKCA!=nCg3Z~>
--X#m"\D!1Kg=gU_ce>[Hg=8omH*)%oAts=og:h7S9\S3FY1hTpGgP.ZJW"o<G*gq:CKf'<g4ie5
->.N@0>&jPq#e4&iL>(*[>*FNkJ_H[K#3,[>g4n&Hqq;:uJaVg;nC^*X~>
--X#m"\^d1Yk2pr.gZH.pk2B1=J@9X:Cohg;k/_H&;!-ni\E;qEJ'd<mM3ER[I@oZaEF7G^k)NfX
-?c2#R?[)M3#f9r*Noo5+?^lW/J``Nc#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-)-QCi\^c7gXHHUrJuj09XK8A"VlEj\VLrCXX9q(k4KPGaPH:j#:=-'dSelYjG#G,>PbD*FC4;jY
-5H0!fTnZsVOBeK1(7S9sTlbF.XF[IEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-)-QCi\D!1Kg:;$NV:q5sg=k'-eCSZJe#.Zog'UO-9\S!:]%YkmA'ipRa;pZlQ>"Tb]?G*.L7lb/
-:tD/Abc5sB[rooj*5lU9b`e9Bg4@tLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-)-QCi\^d1Yk/;:rY3)@Ck2tU]hrAmqhQV_5jpFrI;!-Y[`TH<BB[GlcdiY;/So*5-`Rf.SNi:QP
-<T9gcf<^"i_0ae9*RA]Vf:/:]k(2Zdjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-%U&5^\^c7gXAUuA1TYe?qlBp&OK=.Gri?8cX>W:2M9DtAV*ghHQ;W_d5<gf84KPW[7'*Ik5;ZTG
-8tN,cK5Z&7X8kA6XF[IEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-%U&5^\D!1Kg1NlO6/%Wdqq;0l[b@[/rn7NLg-eb<Y05N?d8\1n^1al':f'6-9\S4I<nc8F:dT6W
-?HCjSVMprBg&Oftg4@tLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-%U&5^\^d1Yk&!^j7-:,.qrS$)^uhqVroOA\k"&KV\'*nTh-&3:a_eaC<E28B;!-oq>NY'i<CM2q
-A(0T&YEYd\joA5/k(2Zdjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
--X#m"\^c7gN`rE]I;=XHXK7\YXK5NcXHHedXI;nc4K4oPTrb>UJ^CJBV*ghHQ;X)MTrFKG:RJ55
-7''jOWFfA9C4<7cLP'0>XHQY8XF[IEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
--X#m"\D!1KZuXaKSqsLog=j6]g=gMSg:;:Tg;@FS9\.:$bhCdWUX7^=d8\1n^1b?!bgs\EA\m)o
-<n_r#eq%nrL7d2RX/:F$g:D*Og4@tLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
--X#m"\^d1Y^3S\rViS9:k2sb6k2pj&k/2K&k0@Z&:uTlDfB25/XO-)Rh-&3:a_f4Af\t,rC<Yh?
->NURDiJ;dANi;+&[BGAJk/;:kk(2Zdjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
--X#m"\^c7g73PZI/LIEO4?QN5XA^8uGcZih4AM;t(hp(8=KJT%/C:IB>T/,4INOr<6Te#-Rnl.Q
-7')VD4BE_uXD0j[@]Y/D4B8&*XF[IEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
--X#m"\D!1K==S*C3AK'b9MB-@g1i'%QeJ]A9Okr;*erC[Dq`oY2pg8&FWmM*TI7R`<D6c6`+;Vd
-<nb/i9PuB%g4i9pI+kDj9Phn'g4@tLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
--X#m"\^d1Y>V0rX4>Yp':f)&Yk&2e=T]Wje:h\+X+H>O&Flqh'3md"5HQoO<W%#s*>#8bOcY?:*
->NWn4:in;<k)E26K''44:ib0=k(2Zdjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gTWA0BCOrR<XGj4b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KT\9F=LOn01g5O_iir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YT]Q9RO+HGEk)AF,li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gUT=QT4?RD1XF[I2X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KUY5gR9MC4mg4@t9g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YUZMZg:f*4(k(2ZQjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#?gKW\^c7gWVr4iUm[XPX-oEOrL!neR@^LJRB3"ZR/i`QXSnOjTrb#WU7^8C(9;R?4GU#;BKSDC
-XJT5b5bP3R:cqFHqQ'b!ClA:o"H,B)ENAr;!M`QjX9*o+WVNUrKlI!l"#2o#NV]^_K028?XK-J+
-4GN^6"K#Ed5bRqS!I]7mX:La^4CtIm69I@bU9(4r4H'3?#`ga-XJfVk4Igu(NN<>qmap!Ee+*=c
-#KMJckJ6T@6@]~>
-#?gKW\D!1Kf)<Did)*WQftkVQrP8`d_8t?I_V3-2_#VINg&T"h_$/$9cb[oLh:`XtPY=cOg=CpN
-9YT6/F\GZUg<X>(@F"`'!niC6rn7LZ9MCQ#qUttrB`-QcU-.$&g&\15rRq?;9MDehg'OZN9UFJd
-PY=cNqUu)$F\GZUq:Yk@RJtnN_b<aRe_3tr9Kp_TdWA0ern7Xd5el%&I8!>SJ_H+;#3,[>g4n&H
-qq;:uJaVg;nC^*X~>
-#?gKW\^d1YiVgt*gs+(*jil$(rQGN&bgY_!bi[FSbQ-#djoE[*bQZV\g<A7#h<#L7S5<%hk2M=r
-:rqeUHVdbok1aZJB%m+D!p,NTroO?o:f*P?qW7h4DZ&VuX$G\?joMcRrT42K:f+k%jpA7g:nZt4
-SPW.hqW7q;Hr*hoq;q^UU&O0bc;7>mi9"-<:dNarhKi#0roOL%6d"QLKMYLmJ`_sS#4)<BeVDWD
-qpbqlKCA!=nCg3Z~>
-,?aHs\^c7gS0g[#3bg]5XJ[a?K,dZ_-%[<oX>r2?2btDh.Jg+P*_m_J8#'-]<\W@2(8XC"X?<SE
-=fe\eXE\]cUdV:mLTHJ>qQ'a>0S05)"?`ce8Y>m]!i/mHr2]r^5cFO\!e`mHrN#u]pT+[?XK4Uc
-WH5/B4Sl,^G]0[[6i*kcIlqHEX:7:nXC-gbE3--5Suc.Ur2^/d=HKV;A?;jpJZOj4#.j6SeVDWD
-qpbqlKCA!=nCg3Z~>
-,?aHs\D!1K`@tD*8qor*g=/5cVB]Y`0;U0\g.4Wc7:d]T2#>o4-=\?.>0h(tD*?_/(=?+8g.^5-
-ESB,?g6[iRcrSkIX4jn$qUu"64JVo0"AIP'>furt!mkgAr7V3G;:YNs!iT%ArRq6FpY#q5g=f<S
-ere\?9`!HGR>oqJ<VkDNThL1>g'pa0g3TjSNS<)lakCjBr7VEMDn"H!IbNLLJ_H+;#3,[>g4n&H
-qq;:uJaVg;nC^*X~>
-,?aHs\^d1Ycn\mA:5r"=k28L/Y9dpu19N2nk"J>.8STPd2u;YC-tju<?e][;F$SRD(>W-Uk"t3S
-Gin-bk+J%&gfrol[H>/JqW7jJ5cjtI"An7C@Fb8;!o%fUr8n&W<T3f:!jPjVrT4)VpZ;dIk2oS&
-igJrk;#9;WTp=cr=o.7^W_eZRjpb/Lk(0r&Q0.4<eE2(ir8n8]Fi!4FL$%MoJ`_sS#4)<BeVDWD
-qpbqlKCA!=nCg3Z~>
-,?aHs\^c7gXAY@TK62TWXK,fcX?<SQ?^jVtGBS#.:96RZ:AV$u:8pIQ=.)gbS4W^]!@iBSX;7k(
-XIr+cN`iHb4KNdHXJA7cSu&N=BDS\2QY1mKX9:YeX@]&]X9,Ai4T2>`>E(nHqQ'agKjO_Z!],t.
-poFakO[Z:OXI,,?qQ'gEDlfd&qQ'adHtiS]"?`ce@#+`_'9-=tX?;r6Uo^Y8H<?91Un4ZW9nBC*
-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-,?aHs\D!1Kg1S.>VN[^-g=UeSg.^5=Gf3j9Q^*]e@bON0@f"db@b+B$DSfo;`E`Dr!B$;)g(r>W
-g<3^SZuOgR9\Phng<`mSaO/_:KDO:'^Or<\g&t+'g0Detg&fjC9`<ZIF0e`oqUu"iWH\<p!^X?8
-pt?"n\6.D;g;1:'qUu(?NS;c[qUu"fSV@'s"AIP'HE@,"'=)i6g.]Dod+[33Rr>did)aq[@=d-l
-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-,?aHs\^d1Yk&&5fYFDPNk2_0&k"t3cJ'VPWT:MD4B]`.RB_pitB]<%GFNnO^cscq9!B6b4jqd%$
-k13r&^3Jf&;!+F:k1j2'e(s/fMYcH:abm2!joeNCk$cg;joXMe;#TMYH+d5:qW7k+Z@;c7!^soO
-puVk/_Hl6bk01\MqW7pSQ0-n*qW7k(VMtN:"An7CJ[PL>'>/bRk"s@?gZIX^UNOE8gskK4B7]3)
-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-*Ehgm\^c7gXAVY:Suf"UXJ84cX>!X,XK5!L<c`<\X8kBWX9bdiXK80t<E5[jX8uRci2dEb<gg%L
-=fe\eXE\]cUdY3`"G16eXEskG"HKRbB7^&`#s>;j8Y<(d<E36%X8kB^X9=kjVEh*UX9"2brN$*'
-=&tR]X9a)Q<i`='DHC6BX9<cdXJJ;[X9!fbri?5bXK5fbri?Q_@]ZXS<``J+UK3gcOT)<_PZFf8
-XGs:c]'e2#LXYejeHa-In)qLUg-U;~>
-*Ehgm\D!1Kg1O_EaP,?Ag<WjSg-'75g=ff5D39t[g&Oh@g'H8+g=jhhCi%5mg&Z?&i7\[gD8P#6
-ESB,?g6[iRcrU/""Jp\'g7/(X"LQn:K;8G"#u'(,>ftc=Ci".kg&OhGg'#3.do"Zkg&\C$rRq?m
-DJd&^g'F-bD;!XsMf*k;g'!h'g<iprg&[n$rn7KKg=gkSrn7g\IG3C(D/OCJcY^U=\,P(_]PZ8O
-g5Xejir@lhL=5Yig'>fPmcqOUfg1,~>
-*Ehgm\^d1Yk&"T_e)odhk1X)&k!3rMk2p*\F.&HqjoA6Pjp9sHk2tB=EcT\/joKhAi8tO)F3Wj]
-Gin-bk+J%&gfsd?"KmRCk+qus"MX$\MQHg>#uKdH@FaL_EcQI)joA6WjoikKhGrP1joMu@rT43*
-FE>Itjp7]'F62QHPB;BPjohBCk1s29joMK@roO>[k2q6&roOZqK]_DJF*)]igN1\`_>`Qu`cL0k
-k)JL-li5YgLXYejeHa-In)qLUg-U;~>
-*Ehgm\^c7gXAXRIQ_1@K9hV%YX>lD=R]&fM='K_EX8kBWX9bdiXK8@\PESPmX;@L2Suf#R=fe\e
-XE\]cUdV;cL1[BcXIfET"J`'"B7^&`#s>;j8Y<)KPEV71X8kB^X9=/PM)1:iX9"2bqlBg6I.s]C
-5-"R_!'L+Z"F+jdV*k'[!Inh_X9:YeXC-h_X:e$sXK47RX?<SR4c)XSXK7dlUOfM*X9Q9(f@>Z*
-nb^iAa+NjD_!p&EJ,~>
-*Ehgm\D!1Kg1R0p^rb<K@UI10g./_a_pr#7DKCs>g&Oh@g'H8+g=k)a]"2/%g)%kLaP,@TESB,?
-g6[iRcrSlSWe&^Sg;s9)"OGfUK;8G"#u'(,>ftd4]"5QRg&OhGg'"<cY!KSng&\C$qq;(,T(gq>
-:>#O!!)37C"IY8'd8g"r!MP5Hg&t+'g3Tk"g(IT5g=em>g.^5>:9I`gg=jA_c@O].g'6R:hV*_4
-o)%,GbCT*H^@9fAJ,~>
-*Ehgm\^d1Yk&%2<bLG\#B4THQk"EX,c/<$\FEs;RjoA6Pjp9sHk2tX9`5H*>jqlNie)of,Gin-b
-k+J%&gfrq'[#!Z&k0s=J"P`)$MQHg>#uKdH@FaMZ`5K[pjoA6Wjoho(\4"40joMu@qrRp@VYB3R
-;WRf=!)WOS"JM+Ch-'R9!NM+XjoeNCk(0r>jq;"Qk2o.fk"t3e;Rg&.k2sj3fn&:Ejp(/Og!tl,
-nb^iAa+NjD_!p&EJ,~>
-&6\G`\^c7gXAY@cIVPsb=C(p-#s>;j;3skHX9EYDX8kBWX9bdiXK7g7R]JXNX8u7ViiEoo<1'b)
-XH$GbX?<S/E3,j'XFk)cRt(78!G?u_X9:YeX@]&[X8kB^X9=u!?R'^hX9"2bri?BEWiTu`XK6qX
-ri?EDXK4UcWH,)A4T;Dk>(WiWG]0[[6`dA^9q2-`!Inh_X9:YeXC-h_X8kB^X:JQpX?<S[?XGKn
-XHlqbXDWTjNN<>qmap!Ee+*=c#KMJckJ6T@6@]~>
-&6\G`\D!1Kg1S.RTSD1RE-D67#u'(,B#%Zog'<c>g&Oh@g'H8+g=jCq_qIf`g&Yrkin>0uCV\Y_
-g9bkRg.^4eNnVi\g80>R`M*+]!J@0Hg&t+'g0Derg&OhGg'#<<GV,3Vg&\C$rn7X<f\2.Qg=i9D
-rn7[;g=f<Ser\V>9`E`TF/@UER>oqJ<SH0M@`A?#!MP5Hg&t+'g3Tk"g&OhGg(/>2g.^5IG^)Aq
-g:hLSg5LU:NS4Trs5)Iaddm:h#Kq\dlFuc@6%A~>
-&6\G`\^d1Yk&&6&WK$'%G('AP#uKdHCs$2:jp.=RjoA6Pjp9sHk2soAc/qk%joKD1ioV$8E6IC.
-k.Z*&k"t35QKHt,k-'R&c`6g'!K*uXjoeNCk$cg9joA6WjoitYIP78fjoMu@roOKPjQ;Q$k2r^l
-roONOk2oS&igAlj;#]SdH*6;lTp=cr=m"ktB[Hb@!NM+XjoeNCk(0r>joA6WjpugNk"t3qIXXP1
-k/hc&k*1GZNTLH2s4PqXe+*=c#KMJckJ6T@6@]~>
-,?aHs\^c7gQnpcc2gVR,IYFl)H8%HD1P7GcXET5sVE?OpQ27QgLcdCZXI`]m4HTQD!A]&^X;7]g
-4?Pj0WG+IWQ`R)j4@#UAF#Z9BDu-OB>r=QYXK7@C4E@M"X9>1Y0Kbg'X9+A9@/?r7F>u*YXK8*Y
-4C>"fXDgE'X9jSC4F+$/G!%mBri@##F0)I@>s(BGXK7m@Q)q'(2`4pCXID=7AZ5U0!*B0$"/fBd
-JGuVUS23pAN\ij\<.V-1X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-,?aHs\D!1K_*CRc7[r,cTW-Z!RlsG=5c-bcg6\SgdS)et^&$FhX@k`Wg;nGI9XarS!C379g(r1%
-9MA::eqHdk^Y7.Z9Ms'gP"/2:N;D68G!e`Wg=if*9Te!)g'#Sm4\Wfng&eQDH2?5)P=IrWg=jbG
-9R5.Ag5]#/g'O]O9UXVfQ:suQrn88aP1nX=G"bcWg=jM(^"V1t7RMCRg;Q`ZJ^sbR!,qkj"4MBd
-UAijP`^++gZpRM\COt3!g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-,?aHs\^d1Yb=#'$8u(P2WNt[KUd7gR7'At%k+Jg<h,$C6aSP$*[ST7nk0n`m:r*(m!CNaDjqci@
-:f(-Rif-c2b3%T/:fc62RS-INPksMLHq-emk2s9P:mpDAjoj:45u>o,joW1]JGSC<RnH1lk2t8n
-:k7Kdk*B!GjpA:h:nd%5Skr7kroP+qRc`biI8Eqrk2t#NaQDWI8k4?mk0Qq$LuJ?q!-S;'"5eH%
-X8_5ed7%a2^.(pqEIm83jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gjK&?(r&at2JZOF(JZR+t#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KjOsTur(I*eJ_G\/J_JB&#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YjQ6H4r(mBrJ`_OGJ`b5>#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#?gKW\^c7gUA]*8Q?@4gFoJHDIWD4_X9G,7Knc[]rc/!cqQ'[=rc/1"XHIUbL>ApHWa._LDQKR5
-4?S%nRSQ%0M6)n34@YJ0X9,@jJc;_RE]cHgW;<RrOtus:!bW@Kq5aU.?i@&.(d'p?qQ(!=4?QuO
-Wa7eMD>L=:Rnl.1M>=4R>&+&<)1an4<1p=oN](CKXCF@TAZVt@0K`46XG])iXGa.a]'e2#LXYej
-eHa-In)qLUg-U;~>
-#?gKW\D!1Kc2Eb-^6FbBQ2]J=TTRP!g',KYW2eRKrfI2NqUtq5rfIAfg:<?SWnlAEf60h]MqZEm
-9MD&3`+2P;Y1gHk9N\e#g&fi-V#K'NOA&>ieb[u#\Ng#G!eVQEq:Yk"Gl?=u+&#A7qUu729MB]a
-fQU"_MYc$0`+2P;XngZOEeaSI)5Kr"C<P>bZUB8rg3u^hJ_Jh(4\TJAg9=,!g5FYhir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-#?gKW\^d1Yf_q3@aIJZdSc7aQWL;H=jos/#Z*`Ysrg<b^qW7dIrg<r#k/3V&[,'j[j*aa#PNLP>
-:f+(PcY63S\)tV::gLs7joXOJXo@GcQr$V*i;2R:_aF@a!fA,Zq;q^5J,SL3+AbnJqW8*E:f)Z'
-j*aa#P5=;DcY?9T\,#.eG`Mdc)6H_3E7X16]h!k>k(QW.M!!iN5Yu:Zk.+0:k)8@+li5YgLXYej
-eHa-In)qLUg-U;~>
-,?aHs\^c7gN]pZ7<bbQ-F`M&pXFNEmXK8C#F^l2gIkZ"f1&@sX.W[+X8"W_&=Y'KQ!N2sWX;7X%
-XK4OcN`[email protected]>PbE&?q,_HX9:YeX@]&]X9,%q1&\0UWBWYHqQ'a?<aPa+!'L"W
-$&G[a5,tW?XK4P\X9<cdXJJ;\X9*6:C&Y1I4KPVlLTIOREFQ#N4KPVHXK5ccri?0a>r[D:Ml[,o
-map!Ee+*=c#KMJckJ6T@6@]~>
-,?aHs\D!1KZVGUBD2)b6Q'$XOg7h9Ig=k+mQ$s_,TKJL)55Nt>2Ng"W>0:TFE&R^L!S#c]g(r+>
-g=f6SZuOgR9\Phng<`mSIBD50F8FSlH<I$Bg&t+'g0Detg&fH755j1;ekf5oqUu"7Cj5j3!)3.@
-$*Dq8:>"4&g=f6sg'!h'g<ipsg&d.FL&Td>9\S3HXP2??O+#a99\S2og=ghSrn7FaG"7,;MqSBp
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-,?aHs\^d1Y]i'/ZF,b*NSXG;rk,V=lk2tZBSV8-IWBd#F62K^M31;ml?e'(cFufQa!T2qsjqccY
-k2oM&^3Jf&;!+F:k1j2'KXU$VH2?Y)J6o>VjoeNCk$cg;joX.U62fpJi`&q:qW7jKEdmuL!)WFP
-$+B!Y;WQoLk2oM:johBCk1s2:joUZ^N;hrQ;!-nk[H?RfQ\=M`;!-n:k2q0&roO:"I7o.RMrk60
-s4PqXe+*=c#KMJckJ6T@6@]~>
-,?aHs\^c7gR<aNrOFqasXJ84cXHZ[HXK5!cXK6$8U.1u8B)8S8AuS"kD4+/#XChI5!=Nc%X::7n
-XH$GbX?<S/E3,j'rN$$;H24NBB7^&`"?`ce8Y>g[!'L4]"%](MW;3LqMI-7_![_]8poFaTCJ_(5
-XF+ecqQ'gEDlfd&q5aUHC&Y1K4KPVlLTHJ>Kjq-b;JU&HXK5c/CSCa/!'Gh6Ml[,omap!Ee+*=c
-#KMJckJ6T@6@]~>
-,?aHs\D!1K_O@KP[\f@Pg<WjSg:V/og=ffSg=h/4buiDrK)41-K%<cGMS`lWg4K=X!=k"Eg'tK0
-g9bkRg.^4eNnVi\rRq:2RebY<K;8G""AIP'>fulr!)3@F"'`rGebRo"YBTs!!\oJ-pt?"QLM#5n
-g7F(<qUu(?NS;c[q:YkCL&Td@9\S3HXP1"%WI<LSBSV@Wg=gggLX#hP!).stMqSBps5)Iaddm:h
-#Kq\dlFuc@6%A~>
-,?aHs\^d1Yc(_Os^osAsk1X)&k/M@:k2p+&k2qN_fj3FBM>H?@M;hOkP0I_'k)'*"!=k:Mjpf+L
-k.Z*&k"t35QKHt,rT4-FUA<pPMQHg>"An7C@Fb29!)WXV"(9\[iVDU:\:4D=!],nApuVjfO)*k>
-k,+2^qW7pSQ0-n*q;q^XN;hrS;!-nk[H>/JZ@qB&DNBisk2q/5O4aHo!)S7/Mrk60s4PqXe+*=c
-#KMJckJ6T@6@]~>
-)HlLj\^c7gXK7.cXK6V[T3[P[XAXgiENDa(rN$*q(cG+`X9bdiXK8=,4?Si,X9!j@i2d]_=JDmW
-=fe\eXE\]cUdV;cWc*3bXDIku"GX"ZB7^&`#s>;j8Y<(K4?Pt0X8kB^X9=PhWBdEXX9"2brN$*M
-I:.p-X9ao99<5.qMLA=tX9<cdXJJ;[X9!fbri?hsXK5fbXAY@<@]ZY)I=4hkXI"?`;uWiu4FsSl
-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-)HlLj\D!1Kg=iQSg=hjHb&t/Hg1[ODOP3s^rRq@u+%0T5g'H8+g=k&%9ME%sg&[qdi7\saE6[+D
-ESB,?g6[iRcrSlSfSuBSg55f&"KL20K;8G"#u'(,>ftbs9MAFbg&OhGg'"g+eksung&\C$rRq@G
-Sp@L7g'G-Y?eF)dYF]>%g'!h'g<iprg&[n$rn8)\g=gkSg1\4"IG3C_St9BEg:s5NC&Zfd9S(oU
-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-)HlLj\^d1Yk2s"&k2r:peU50pk&.SgR-%i-rT448+@p/?jp9sHk2tQN:f,+0joMO/i8tg#G1brk
-Gin-bk+J%&gfrq'jHZP'k)fR="LI7QMQHg>#uKdH@FaL?:f(<ojoA6WjoiGHi`4t5joMu@rT43\
-Vgu;Qjp8c#AE;n8\>O-=johBCk1s29joMK@roOqlk2q6&k&/8GK]_E.Vl+1ik/sU"DuSl!:k@be
-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-)HlLj\^c7gXK7.cXK6V"8RJR#N(ur9=//?ZrN$-r7\Y$Rq5ak$5HLr^KWM7;goLO<=T5B3N`iHb
-4KNdHXJA7cXD`CYX8usbri?5bXK5!cq5aQYri?6T3b'I]q5aUS?Mgf)COGlX!C!O^X8kBZX9<cd
-XJJ;[X9!fbri?VmXK5fbX=n'X3Mrl?XK4P^X8kB^X8kA6XGa.a]'e2#LXYejeHa-In)qLUg-U;~>
-)HlLj\D!1Kg=iQSg=hiU>^4uVZ"%$DDU2S1rRqD!=O!,&q:Z,*:tjXMW7os!gtDe;E;nQ$ZuOgR
-9\Phng<`mSg5VNpg&Zi$rn7KKg=ffSq:YgBrn7LQ8U`=\q:YkQGPg(pLn=@p!D_;Gg&OhCg'!h'
-g<iprg&[n$rn7lVg=gkSg,jam8CQ9dg=f6ug&OhGg&Oftg5FYhir@lhL=5Yig'>fPmcqOUfg1,~>
-)HlLj\^d1Yk2s"&k2r:$@=RG%]4k\^FP:0RrT479?.kdHq;qtB<T`GuZ0(1Fgu\XQG5gV6^3Jf&
-;!+F:k1j2'k*;Y7joL@@roO>[k2p+&q;qZRroO?f9nb<qq;q^fIf&7.OJ_d7!E/"WjoA6SjohBC
-k1s29joMK@roO_fk2q6&k!+Q49]"o.k2oM<joA6WjoA5/k)8@+li5YgLXYejeHa-In)qLUg-U;~>
-,?aHs\^c7gXJ'f<SZHO9XGpVa<-Y++7uER8Q^:sYPs(J#3;T]_V3O$.XI1#^QU^tU!AJl[X;7^%
-NL*MDP$+-<8$%/SQ]b1HEb:YjD>[email protected]=+MX9tto24(;DUP41IJblGXU3T\-XK6!!
-QY(iNXDU3#X9i4"QU@dO?^I*Jri@h8Eic?lBpXuYXK7m=Q)q'[E*T!9X@S\E?AttDKj$a>X@&>@
-6`ctmQ^:1CVjB9-X+@@3X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-,?aHs\D!1Kg<>h!a4c5sg9Q%PCREAb>-GV[^qb*H]hZAY8,CpGd_&)eg;5)6^fgZj!Bcn3g(r.<
-ZbU5-\T#@">M>^(^pn"1OFb3FMYc$6aE*Heg=fZE^gPC`g'ZHI6bq:,cD[EoU\`[Sc'i@dg=h(k
-^k/E:g5Jc*g'Mu=^fK+<Geh*rrn9(uOP8E]L;:?2g=jJ#^"V2`NciFsg0DG/GHol,W,Y\ag/Yr(
-<SGZI^qa+,eA+Gefn%k:g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-,?aHs\^d1Yk1H8HdcQODk.H9#EM1t1?b+7'bKG7pa&:+(9D[cWh8`.3k053Yb?k21!C3L@jqciX
-]ut6S_fs;I@-4DJbJS,XR#&qiP5=;Jds7>4k2osmb@T<&jpL.l8'BoSg9IY;XSV&hfV3<3k2qH?
-bDECak*/aBjp?IZb?EucJ'6#?roPq0R-*P1NQ]4Sk2suIa6)O8Q$h'Ck$cHVI_4aRZ$9=-k#omN
->3=FlbKF5Si6+X6jalQRjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-+'J$o\^c7gXF*i@Brk92XK729:f)RI:h?_l:f*.QC]7-1?M^`0N_iPQXJ1#M:nIZf!EP*;X8o3u
-:_$a3XF*i@Uo^Y::fXTuK`4dJJblGSCf!rRXK7mf:kebI!2KNi!1s1k!g6AtqQ'dJ:f(g(X9)9r
-F8i6AJRADX$'e=`Mla"::f*MXX8uU[ri?0@:fRFq%\QXgXK6YC:i*57W)-<9rN$N7:o17S:f*:U
-XFj>GSZJ1W:]RJGXGs:c]'e2#LXYejeHa-In)qLUg-U;~>
-+'J$o\D!1Kg7;hfL"^9Sg=iX6AnIZ\Aq8UHAnJC'M#LudGP^#"Zt<oeg<H+8B#su*!H#%"g&T\&
-Ae&t;g7Dngd+[36Ao$,SVuC9.U\`[NLh:7fg=jMXAuYX\!7(RU!6G/n!kDp%qUu%EAnHYog&br"
-OoF&8Uj;sn$,'q_YhIg6AnJjXg&ZAprn7F7Ao%D"%a/J(g=hp+Ar56qeRiE]rRqd(B$o>@AnJR,
-g88Ioa4e<-AcUG6g5Xejir@lhL=5Yig'>fPmcqOUfg1,~>
-+'J$o\^d1Yk,)s2N95(qk2s(`Ci$#"Ckq/lCi$fIO8`qqIJW(4^2.V,k1QM^Ct&CG!HYg2joFB>
-C^tgSk,)s2gZIXaCiSV"Yl8G=XSV&cODJa-k2t!+CpNp"!87?f!7Ur0!lSo=qW7mZCi"t-joTF:
-RJu=LXag?4$--ju]&r.aCi%8njoKk6roO9KCiKC9%b>IDk2r@RCm!lBi,!5'rT4W;Cu"0gCi$uN
-k-&T;dcS^OC]NIGk)JL-li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gjK&?Qr/^oQJZOF(JZR+t#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KjOsUTr3cUMJ_G\/J_JB&#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YjQ6Hkr4i<bJ`_OGJ`b5>#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gjK&?5r)`rYJZOF(JZR+t#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KjOsU1r,;YAJ_G\/J_JB&#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YjQ6HGr,r(QJ`_OGJ`b5>#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-)-QCi\^c7gXK5MtMheBN9Mqmd9NnN&9VHV.9EItjB`:[2>('(pQ:tqm:]=#kFKC!dHu=M:JZOF(
-f;o1fmap!Ee+*=c#KMJckJ6T@6@]~>
-)-QCi\D!1Kg=gLSYcHK8@;"<>@<1(E@EXo7@00olK`5BcEh6^6^0uZJAH$!@PM2d?SVr'QJ_G\/
-f@gGgs5)Iaddm:h#Kq\dlFuc@6%A~>
-)-QCi\^d1Yk2pi!\[CR_Ao6\aApEHbB%NRPAccZ.MuI;oH)G8TaC^=lC&V]JS*$eaVNZSnJ`_OG
-fB*;'s4PqXe+*=c#KMJckJ6T@6@]~>
-1g08/\^c7gUg9%N1hplSS!R3K="]ej;lWEN4-qk,QTpt/3M[g$UHt0H2jcUg8"3>ECb,Ld!J?nn
-XF[I(XPBl]]'e2#LXYejeHa-In)qLUg-U;~>
-1g08/\D!1Kcule96ACAf`P6?6DEGS.C"HUu9><pL^ei"h8C/i+cVhI17DVO)>/b'lLc57d!N*kf
-g4@t/g>(Bdir@lhL=5Yig'>fPmcqOUfg1,~>
-1g08/\^d1YgjHoa7?*J+d)gF\F?[dJDrY9A:WZ2jb#Ha79\V+Bg/lAX8^'lG?dEN7O?*=&!O0t&
-k(2ZGk1o)'li5YgLXYejeHa-In)qLUg-U;~>
-%9`,]\^c7gN`rNcRZT`3X<VA.?uT)(>HELU6)T46U.1kuJ#kb.Qq3mOJ#PZ2KUGT:XFL5N!=Naq
-XF[I(XPBl]]'e2#LXYejeHa-In)qLUg-U;~>
-%9`,]\D!1KZZFjS_miD>g*;6FH&cXFFP<\B;q%Gobui5RU"W1O_->+:U"3&iVnurtg7eN"!=k!<
-g4@t/g>(Bdir@lhL=5Yig'>fPmcqOUfg1,~>
-%9`,]\^d1Y]m8c&cGNKXjs,bbJ<k/eHKMKi=5U%?fj37!Wod,mb[B#aWo@%:Yg$nEk,SFC!=k9D
-k(2ZGk1o)'li5YgLXYejeHa-In)qLUg-U;~>
-#[-TX\^c7gN`uC_!'L7^#%rHoLKJS$ri?u'VlZto(cG*iX?<CH8>*&cWB[JcX)pHdHN'uHUoApH
-JZOF(goL^kmap!Ee+*=c#KMJckJ6T@6@]~>
-#[-TX\D!1KZZH*!!)3CG#(r[rX)F)Arn85ge(WO#+%0Slg.^!o>KbaSekk)Sfoo*'Rf;"Acdm[$
-J_G\/gtDtls5)Iaddm:h#Kq\dlFuc@6%A~>
-#[-TX\^d1Y]m9S=!)W[W#)]L4[!%g_roP)"hra(S+@p/-k"su:@+OK&i`5.'jdT(CU]0BVgZ!eH
-J`_OGgu\h,s4PqXe+*=c#KMJckJ6T@6@]~>
-#[-TX\^c7gN`uC_!'L7^#%rHoLlON#ri?u'VlZto7])&RX?<S!)PF15WB[JcTQ%!64FsSbXF[J)
-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#[-TX\D!1KZZH*!!)3CG#(r[rXgC]Brn85ge(WO#=OOC%g.^4U+NrKmekk)SbDt<19S(oKg4@u0
-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#[-TX\^d1Y]m9S=!)W[W#)]L4[_>L_roP)"hra(S?/E,Gk"t3#,1bo=i`5.'es5C[:k@b[k(2[H
-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-1g08/\^c7gXDhrp@tBGCEGoNf5@U]\>HFoL.rL`UHnKDY0TRTDOVjamR;XQtXI1#?EEW:B!=Wgr
-XF[I(XPBl]]'e2#LXYejeHa-In)qLUg-U;~>
-1g08/\D!1Kg5h#NI\X#jOGnkA:jgtrFP>H62iGN+SN;jo4gd&T\0&oJ_MpF;g;5(dOE(9R!=t*>
-g4@t/g>(Bdir@lhL=5Yig'>fPmcqOUfg1,~>
-1g08/\^d1Yk*D'qKrh_4R$<Nc<.j=9HKO@]3g7eMVEL<65ef1n_BILmc':8Zk0530R!8Pl!>(EF
-k(2ZGk1o)'li5YgLXYejeHa-In)qLUg-U;~>
-+'J$o\^c7gXK6hnKrhA4G'U0eG(-NePH:j4G'9=ULAl?.IZel<XGs0[Rs&t$XJV&0G,5,=!IC,a
-XF[I(XPBl]]'e2#LXYejeHa-In)qLUg-U;~>
-+'J$o\D!1Kg=i0bW7ot-QC?OWQCusW]%Yl-QBoGBWrA:rTX^<"g9T8_`0Q^Xg=*I)QI,Wb!LgiU
-g4@t/g>(Bdir@lhL=5Yig'>fPmcqOUfg1,~>
-+'J$o\^d1Yk2rS5Z0(2XStbB)SuCf)`9-3XSt=6iZi6O.WPb=Hk.K[8c^p`'k2*kST%j8,!Mdki
-k(2ZGk1o)'li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-$X)o[\^c7gXK5#VU]%7oA,!&*B;g]h!/(85"`LKD9fuMVX8tLLri?-mE.P*AXNIUK]'e2#LXYej
-eHa-In)qLUg-U;~>
-$X)o[\D!1Kg=fk,cMcGsIeVOsK%>h5!2f`h"c_6i@8(V=g&XuGrn7CqNe,o8g</+Rir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-$X)o[\^d1Yk2p/MgAU.6K_OU0M;a?S!3cAu"dS64B2EaMjoJC[roO73Q@\1Lk/ufjli5YgLXYej
-eHa-In)qLUg-U;~>
-$!H]Y\^c7gXK4P^X9!6bri?0"+-?H&!G89fX;$;GXI2kc<g'P9Aun4rWDK+dXB^^8XF[IrX9Q9(
-f@>Z*nb^iAa+NjD_!p&EJ,~>
-$!H]Y\D!1Kg=f6ug&[2$rn7Eg-as!-!J8m[g(^Bhg;7CSD7SAsJ_ErOen)hSg3'ZOg4@u$g'6R:
-hV*_4o)%,GbCT*H^@9fAJ,~>
-$!H]Y\^d1Yk2oM<joLaAroO9#.DYoE!K#cmjqP#2k07W&F2R.CLuq[ribHj&k'O^kk(2[<jp(/O
-g!tl,nb^iAa+NjD_!p&EJ,~>
-$!H]Y\^c7gXK4P^X9!6brN$$%OT)<l6oV'GKKXWDCTFP;Ccm!DqlCuBBMWJ;G-%W/4Jf-Y=Zh0n
-Q`*P><iN1%JNRIJXI;76Ei])=1gXQkAQ!BHW(K1CXK#Yj4CkOm;ER$^XK77@?)`K?HTZ&CXHG\F
-A6Q(7?Ta+FTK/3U:oX5k&Qk-r=cK8,BrjOuXClp^XB^^8XF[IrX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-$!H]Y\D!1Kg=f6ug&[2$rRq9k[f4tk=%:`oVbNXSLtLG6M+j>jqq<62K4KjGQ.j_e9[VSFED3&r
-^XZ[bD:[FpUeH5[g;?TXOP0Nb1j=7`J7skpeQkkhg=LXE97GUGBM;$]g=i]'Fk<NcRnSUig:Bsm
-Ira8pGYG0lb=K4*A_-Y1&TG24EO4&cL"]ASg4GpMg3'ZOg4@u$g'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-$!H]Y\^d1Yk2oM<joL^@rT4-(_#EI,>>!l:YYq5mO6#HaO\he6qrT)DMe\AaS`\j5:u19nG>P;4
-b2Hl-F5l?EX\a^uk06_!R-"5-1k'ssLMi:;iF>^4k2V"h:ke&kDGX)sk2s-LI,hJ/Uem*4k/:)8
-Km;b?Io*N7f1a,LCZ5'N&U(tPGeMn3N94+!k)#ttk'O^kk(2[<jp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-$!H]Y\^c7gXK4P^X8uObrN$$%OSu6j6)Ufc2K#U'M6(N@XD`C]X<O&SI3NuDS5Z8c;O(IIXAi#t
-GFbgdAupPrXFq[V=KJTIEr2ppV&Fq+Io;q>SubtUG]9a^D6.0$XI4C9L176B?*#r$XC-jB?*'81
-T<)CVXCR!c?;>^3I/'cT4KPWA8OH15XD2E^.X\>!HYe87JZR%r#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-$!H]Y\D!1Kg=f7!g&frLZi/SYE45`!%TCj1g-gkQGcobWS_B'kqq<72-_DoYGK":Eg1S'>[G#A,
-g6]k6Uk7<qK%d+N[W'sSQB;!t1smJC-)#"qCrtCJ\X/?1e;Dt,X4kF[g8TMSZ$"bhMV<?XY]ea5
-,g+hcY1e?&g3@+o_4CAT&PUp4Y?Y(9\(ZRiK/K7Sg74"Ng4@u$g'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-$!H]Y\^d1Yk2oM=joXXj]`$snG/4(=%ThQMk"(]uJ%4X'V<4#:qrT*I.B"hoIF)ogk&&.a^ZKKM
-k+C)aXbl2AMWV/n^inl&Ss]E;1u0CZ-`V%8En'5m_k<=Xi0!/Q[H>`0k-K^&\pWX3P3.;'\pWY[
--Iq7.\)rCLk'h$:bGP's&Q%WP\RAZR_<-`8M`@Trk,"2kk(2[<jp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-$!H]Y\^c7gXK4P^X8udbrN$$%OSu6f6)Ufc4KPVkM6&*(49.SBX<*d)P#dHHK-NK@/Tj=[XI)hc
-Ue3a$Aun1rXK7ImL&S.R4Su37V*ghHQ;W_b4?P<9Sl7a:UTBhT4ADZR8iJjp+KR],XC-idOK>NT
-T<&kl4?63=?>T>:&pJ;rXB(LcJnD*cJ:ME_XK6DcJZOF(bH(oZmap!Ee+*=c#KMJckJ6T@6@]~>
-$!H]Y\D!1Kg=f6ug&ZT$rRq9k[f+ne;q'IS9\S3FY1bW09E7ibg)e+@\S\NoV(GA73L!Fqg;.@S
-csBC+K%`uOg=ir_WW(TO9`*Nud8\1n^[email protected]_=FHcJ$*@9OcE'?:IU^.,%AKg3Kf=[bBG?
-b1[q29M&dKG_u.J&snX4g24CSV1I@SU8*O9g=hUSJ_G\/bM!0[s5)Iaddm:h#Kq\dlFuc@6%A~>
-$!H]Y\^d1Yk2oM<joL+@rT4-(_#<C&=5W0&;!-ni\E5XI:]OGkjrVc]_fNA:Y:i^K4IfI7k0.T&
-gga/CM<7ask2sF3ZMrtd;#BB0h-&3:a_eaA:f'EAe8J/ag?-Uh:[email protected]('m`_<0lg
-e`IuN:ebZdIZa?d&tkQQk&\K'Y))6&X/qD[k2r#&J`_OGbN9#ps4PqXe+*=c#KMJckJ6T@6@]~>
-$!H]Y\^c7gXK4P^X9!6brN$$%OSu7>6)Ufc4KPVkM6($?XK6cMXEo;rXI2hH<f14K=Jr6aO].UJ
-B2G[0PH7VnXDW?cXF#S2XK7.cqlDNK6_6o9;O^^]XI,'6P,tHIXG`UMNE`K,F0)HiX?<Sc@#05H
-XICZ2XAtIcW.:sUM>XFUArutm#\AXiXB(LcJnG"`#-(ggXK5ZcrN$$LGCciHXO4*R]'e2#LXYej
-eHa-In)qLUg-U;~>
-$!H]Y\D!1Kg=f6ug&[2$rRq9k[f+o=;q'IS9\S3FY1e-'g=i(Ng7"Veg;7@1D6J/rE7EUR\7rb4
-K4WbP]%UbJg5DHSg75$jg=iNSqq<dP<6/C[BZ4l7g;121\_>D2g9ATNZZFibP1nW[g.^5SH**Zo
-g;Ghjg2+@Se=tZAY5HuSK"(^4#_8f+g24CSV1JX"#1mk)g=g\SrRq:GQ\!kAg<nUYir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-$!H]Y\^d1Yk2oM<joL^@rT4-(_#<CS=5W0&;!-ni\E87Mk2rN&k+ej:k07VXF1H_>G2VN%_JdTZ
-MJD9n`TCunk*)S&k,#8:k2s"'qrTWh=jpm&D:!CXk01T\_rf`Yk.8t&]m8b1Rc`b/k"t4&J@;A;
-k0H!:k&JB&i2c!h\GYIiM8B/Q#`#VGk&\K'Y)*)>#30pEk2q$&rT4-\T7Q-Uk0`;qli5YgLXYej
-eHa-In)qLUg-U;~>
-$!H]Y\^c7gXK4P^X9!6briA:^.Q2OQX@+?rL4ggdTdrR5V-Z8HN3&j2:9:Nq."<[p/"i1o4B8&G
-;*8GeXI2R@@kFRZDEL%(XG/i"@]0+)10l2X-\*V4R79;7SUN4S5F&<c1d"?uXK6S-4DoftBq[%F
-XFE?,3M3CG<BNO4TIVj?ri?0n&9[rQ%;q!'XI2R@:7\Jf5!G82X8uRbri?0u4@+P"JZR8##.j6S
-eVDWDqpbqlKCA!=nCg3Z~>
-$!H]Y\D!1Kg=f6ug&[2$rn9PN2+3ebg/fq"Wi%G'bVrVWd<J>YZ.dSi@bTOM18-Os2Trg49P_hm
-Ak[beg;7#eIQ>j1MbHg0g8[h?IFJ)I13P=I0qpJ?_,sBBaIkXh:qbS<6;1\'g=hfc9T,f#L!2JV
-g7_2L8BTZ0CeR^?b;VbNrn7Fq'pS[N%?.FCg;7#eA&m<W:/8M%g&Z?$rn7G&9N-MrJ_JN*#3,[>
-g4n&Hqq;:uJaVg;nC^*X~>
-$!H]Y\^d1Yk2oM<joL^@roQC_3(T_)k$'Q9['26Df/d1!h0r0s]B7m8B]eGq26&U63S);Q:iY(8
-Cf#q&k0770Kfn5SP>G)Hk-Il\K\u[h141j[1oiOYb["%[e#>Q.<QO<`78RI=k2r42:m8.<N7^0q
-k,M6j9\&:VEDT]Wf/cBiroO:3(7b?c%?n6_k0770B[Z&*;cCa9joKh@roO:=:fi51J`bAB#4)<B
-eVDWDqpbqlKCA!=nCg3Z~>
-$X)o[\^c7gXK3mSV>dOsN*PPI!H^?jX9!-b_lNp-<Mf>h!D$hhX9,+sS,TJjJMF'RXF[J#X9Q9(
-f@>Z*nb^iAa+NjD_!p&EJ,~>
-$X)o[\D!1Kg=eE(dJhi#Z?59`!L-.Dg&[&$_qG1/Csqt0!F(-Ag&fQ:`W"QmUd!:Zg4@u*g'6R:
-hV*_4o)%,GbCT*H^@9fAJ,~>
-$X)o[\^d1Yk2nXJh>ZO;]R/i(!LujPjoLR@_r_$FEo$BM!FU`MjoX4Wd/N//X[:ork(2[Bjp(/O
-g!tl,nb^iAa+NjD_!p&EJ,~>
-$X)o[\^c7gXK7SFWr9"!RHL[OU@PAfJil/Fm]6D*r&at9hQ-fS4AVU@X9"fjm&U5eSGfMiV4`C@
-JZR5"#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-$X)o[\D!1Kg=j*EfDXD'_WTYQcLTZkV+aRUmb.Z!r(I*nhV&'A9Ou<;g&].Dm+MKk`r4TldE@*p
-J_JK)#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-$X)o[\^d1Yk2sRqj8J*?bie-gg%+8-Y#%romcFM4r(mC'hW=oR:heJOjoNfgm,e?-dJ`2.gt%&=
-J`b>A#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gq5aUh=Pp1\F?0/u!0clQ!J,C)X9+k?QLCmZM^5=(Sq`R$X9"bpr2]oVGk8!;X%`/e
-#-3K7XH/+3l)XuYU7A"MX8nIAX9"WdrN$!_r2]s`XHWXb!EYnEXS&Y!]'e2#LXYejeHa-In)qLU
-g-U;~>
-#$LBV\D!1Kq:YkkDr97LP=bT(!5%^R!Mbpkg&f2L^$jYZYV"M]aJuuEg&]*6r7V0=R.K#4fO4@*
-#2-#Yg:"$.l.Q6\c,S*$g&SbBg&\q=rRq7`r7V4ag:R@<!H-&2g@a/(ir@lhL=5Yig'>fPmcqOU
-fg1,~>
-#$LBV\^d1Yq;q_-Fl2<^Rn`_@!6+Eh!N_j'joWjfaRA6q\hN4-e$I0djoNbSr8n#MU%@CIjCRuG
-#3E2"k.n=Yl/i)sf[8FEjoEBXjoNT`rT4+!r8n("k/I>^!HckCk4Rj@li5YgLXYejeHa-In)qLU
-g-U;~>
-#$LBV\^c7gq5aU8H/>V&4Sc&Y4R]?O4LhHn<g)mP"[8rfOBP6GX8uLbr2]pCEV$74X*jQ@#-0op
-XD0;Wl)Xu&I:S$&X8kB?X8tnbrN#u]r2]r^X??K`!HiI7XS&Y!]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1Kq:Yk/RGQWt9_mBB9^g[89XrdWD7T)g"]!_([W5[Dg&Z6$r7V1<O7V'+fq.ii#2)c]
-g4hT-l.Q5qSpmX0g&Oh(g&YL$rRq6Fr7V3Gg._M"!L/aug@a/(ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Yq;q^BU>G#4;#05R;"*NH:q5WgF2[M/"]FFD^j'>YjoK_@r8n$QQh0>?jeh\4#38\m
-k)DINl/i)/VhMDIjoA68joJr@rT4)Vr8n&Wk"u'>!M#U0k4Rj@li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gq5aU8H2al[Ilp7hR?Biu;4W@a@m!qiFXpZYA#]@,(8kP&>rA^W=$/U(XF_0L8Z]"Y
-7QaA5poGc(XK67l<\dTBXI;mHG-%KE4CKLcSl7a9OK>O54@hi,P!M3-SbfE&Ug#rj6EFrb4Dq6!
-5tO1eX?KHG4H0-<)HL0,9UVuC4Zl`:I3r>a?DX`D4ARQ/XK8$cri?3e76H7uX;G-$XK7RO4B6C&
-Wan4pU37T%P9O&/M*"6,X<Es'4C;U"P!M3gXDMWHRSKrL7QaA4N#uXSAgXUW?p%_kqQ(BHI:S#4
-V-Q2l-%DOd4?ek.Hkeb>ri?iT4A_Q%*b_X%*ccTi4CY7%*ef:hB`"k;P8ZABW2tXe4@fCP!^*PH
-ri?-CF+LFcX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1Kq:Yk/RJtnTThJZj_RWQ<B?-o#IS=e-PW!SVIFe;L(=[Y(G!k!-DbNj1g8,]]>h[oF
-=A3/@pt@#fg=hHID*Vi;g;IGoQ.jT,9RJIeaD"=E\(]Q09NtN5\Pl16`qnC(cZ;d.;qd"#9T.V=
-;I)tfg.l3W9X4HJ)Js^m@)CX*9h]BGShPF`GLG3-9P$6:g=jYSrn7Ie=%oOeg)+k;g=j)99PfdD
-f7-J6cBT`C\gqXOY"Mstg*+7;9R)!>\Pc,*g5CSo_dhE6=\N5?Z7(;QJM>g-H;&M0qUuX>SpmWl
-d</-00;6L&9M`+NSJk14rn8*K9P)5C-A1$B-BO`k9RPBC-E3pjK_sI0\faI9e_6o>9NqGL!_h<A
-rn7C;P(D?[g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Yq;q^BUAj9iWDHu*c,3UZCsoO?Ki!$JS2kjkK];mk(>j[>I7NGOF\koIk,o\#@HQ^m
->u5.XpuWl!k2qgkF$jnOk0@X:S`\^S:kCC%dr/&^_<0m[:gdJN_cKZNdJDu?gNl\L=QYZ@:m:$[
-=(5"(k#6%r:qQSd)KU@(B$KJQ;G_DaV_`j"IGO%R:hi/Sk2t0&roO='>Yq["jqr?Wk2sTa:i_ob
-j+^BSfpsO``%?&m[npH2jrqoW:k+/\_cK[Gk)tX:c=l@]?;P4X]IJafLbe,MJ5C[MqW8KQVhMD<
-gjDqL0ri`B:fG0lVArEHroOr_:i"Ia.#[5a.%$f,:kR_a.'g*+Mu2WC`$.fMiT@?a:ga4a!`8#U
-roO6ORXsVojp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gqQ(X::me>cI;>pW0n3?(XHuec3/"A?M6&@iX@T#]X:8QnXG\j8S<9nS4KPVHrN$-Z
-U9&oXq5aUDD>pU[/!26E4K)/HXE/MhN3%alXI,9SUdV;5C94'`Ip&\NQVmU\'jH[!L,WjqXK6_b
-RP:A84KO0!VlW#WX<L\XXFb&cJubtgI&o/\XAtI)G-%&XWiW:o8Z]"^=/2j/K)2Q4SlMGbQ!'uc
[email protected];X?<Sc8tN,cW]dGbU/[_c?sJq!VlX6^D0B*5:99AJXFk)c5^b\F4KMqHXGU<[X:g_c
-OI`IYMl_[kXI,6RVF%Ac4T2>rEHeLO:old\B<44sJZPqFSZFrTX??<[!D/p^X8kB\X9*sSJc;_O
-QVi=8orJA/map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KqUunAB#33TT82.C5G<)Hg:q:S8#Y-dY1c"Eg0;btg'rA0g9<fq`ja[U9\S2orRqCX
-cJ#(Gq:Yk=MuMER2RkQU9\!dog6.\BZ.c3Hg;(DUcrSknL>'g8TlAK7^h3Gs'm$_8WCDZ8g=i$S
-`&u/q9\QC>eCmUmg*1Bcg80ASUtOIXT%ZN5g2"<^QJ0//f\5'$?/"#NDU-seV>An0a_]/S]l;HS
-@#s#kVqSOug.^5S?-1gSfM:/Sc"bASH?Hi>eCo/MMjACYA(n03g89DS;4^CV9\Ofog95\rg(M!7
-[`@*EZ.c6Hg;1GUdT"rS9`<Z[O-eS:B%fr4KA'#QUY=F.aP'>Ag._=r!F<hGg&OhEg&e&'U]/sJ
-^Lr,Op"BW0s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YqW8aYCWtr'W/p)l6E57ek/qN&9<mW/\E6#hk$Zd;jpcmMk.*kAdD=u-;!-n:rT46n
-g#fDnq;q^RP5aSe3Q!_p:uH39k*hfe]B6Ikk0(g-gfrp>Nonn[Wd!@_b&$q:'mdOTZUp1Uk2rJ&
-c9TnA;!+u[i9!l4js"l'k,sO&XlSW+VWL@Vk&JA-T'"6QjQ>US@clguFP>l5Y579Ee8j.&a*->%
-AXDP6Yi`]Ek"t4&@asQ&jAP.&fPo@&JU>@[hr]EtP+Hp"B]cnYk-'R&<MrTp;!*;:k.,p:jq>VW
-^sV:l]&pCjk01j-hH8q&;#TMkQ_3E`CZ\IUMWRatXQJYUe)jKhk"tm9!FjRWjoA6UjoVXHXT%>_
-a_cUkp#ZJEs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gq5ap?H`X;VLod\VKOb"_$p:URXK5ccX?<Sc8>,j]!'L7^#s>;]<'39(XK4P_X9=YR
-4=t1@X9#:bri?JiX?<RHV&)6V4)R1[X:@@oS5;=.7''gPXK8@S@fEG/4Sl,Z4T;DoW'R>_XJ/1Q
-:9:NZXFk&bX???\,$'l.JnD*A4Zk$<X?<Sc<Kg.HXK4UcXK8$cXK7I)4?PZQqQ((*>*#b?@B?PS
-END+u4=`q'MI)'HX/rD&4fk`S9rtFsWIuKY4?A.4H@&gjXHH"7/nM+LW'%.DX=sQ8!)E3g!'L7^
-#s>;Z;*6m+XK4P_X;+De4?PR(>`:e1;lk.)4;sclF`VSHq5aTgTDbhk4SGiWGB&28orJA/map!E
-e+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1Kq:Z15SD)\BXkMLZVgeX!$r#AKg=geSg.^5S>Kcot!)3CG#u''qCJ7Dng=f7!g'"oe
-9K@_#g&]c$rn7`Rg.^3od2bnS98cLCg($g1`F_e7<n_o$g=k)UI/_h"9`!HC9`E`Xe5FcLg<Ed=
-@bTO0g8BGSg._@s,&OmEV1I@(9h[43g.^5SCV+#ng=f<Sg=jYSg=it_9MA'MqUu>1EjaW%HeR2?
-O4m&%9Ij<#YBR$pg"P04:>4F@@G9Gfeu1,n9M)1@S"4V1g::9Y3e5p]eP+[jg-#@.!+Y]U!)3CG
-#u''mB1tlrg=f7!g(e!a9M@q0Fg4WRC"ehG9HhL2P`h,oq:YjTao0on9_R0@Q]H^Op"BW0s5)Ia
-ddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Yq;r$IUupfi[cZ`2Y_E)=$rH(_k2q0'k"t4&@+P5;!)W[W#uKd7E)9A*k2oM=joiP*
-:csU1joOI@roOSbk"t2:h&fHi:QnWSjpk5MctcHO>NULEk2tX.KDt!5;#9;S;#]Shi)eguk1O(d
-B]eGRk-0U&k"tp:,'1]bY))5N;,B$Fk"t4&EQ)S:k2oS&k2t0&k2sH.:f'obqW81IGe`CJK')3g
-Qf^m=:b,l7\:1f:jlY^d;Wd,gBBJ@;iit+4:ee3XUnr?Mk/1G#4br0"iDAZ5k!/iA!,2&f!)W[W
-#uKd3Cf!i.k2oM=jqVH!:f'dHHb3+pDs!Wf:a=HOS=5h:q;q]eeG\M0;"j#PT9k,kp#ZJEs4PqX
-e+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gq5bKQH*"*1<i`9?O]%sTLg[;HX/oWaX?<Sc8"fa\)L68%F"=>EAZKB'XK4ObSoCc2
-PH-ZTXK7.@r2]l\ri@8*X?<RHWEbIaST/[nX)'PmG]9]f6`cGOX/g6&;kg=K?i$i=EHeIa@u"Kn
-X'^^P9rtEYXFk&bX$$6[-<651Jn;#JW2M"iX?<Sc<0N5GX,@^mXK8!bX/r$rS?%^$XK4L?rN$Z9
-Ni\jOU8oncXFOubX(/6)<(E/OX=C55X/r1$PcL*pSl2>aLkfhnX=?uH=-9OEA?8"o4KCTGH#Kaa
-A#ubG>ktHKF*4O#0s#\=X'J&nX?<PNG-$U-X/fa3V&*G]LTEV=P8^!nRSHVHq5alpSuZA&X?<PV
-DY^@7F`[M_!I7@iXS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1Kq:ZaHRG-B*DV<^'\7j1@XErSog"LYPfhC,R>KZis)OcW<OuD$kJD#HEg=f9Sac>(k
-]%KT)g=iQ&r7WGjg=k4Rg.^3of6+IRa,lFKfnhrIR#]j@<SG!#g"DFrC!PD6H2?50O-ePQIB._J
-fm0a<@bTL/g89ARfhD7r->^6HUk%/qe^Z=Dg.^2RCV$cofruFIg=jVQg"O_g`n@bog=f3&rRqp*
-[+`Z:c.P1=g7s>SfmVT!CKe=Kg+(]Kg"Onp]\1&ea_9#RXK.5Ig,<HpDR\:kJ(d`K9\E+mR>onQ
-IG3D/FSXW<P*FXX52)Hafl^6Ig.^29Q.iHcg"Cf-d2dE\X4g8#\fo,J_dd2pq:Z-]aOu!qg.g8D
-Mtu'-P`l"!!L[>HgABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Yq;rT[U?:UUFQMVM_J\)h[XdL:jlV$$j\Y($?e,&9)PWJXRQ9K5LZO:ck2oP&e<T0:
-`8sXJk2s!Lr8o;%k2tc%k"t2:j*\Q%d[-AmjcMpmTU+\b>3<_DjlMfFDqX6\JGSCCQ_3C$KXHEn
-jaXbbBBJ;PjfaF$j\Yg9-?@#dXbZ%=iScPhk"t1%E5]>8jgcDlk2t-%jlY6;d,i$Ck2oLMrT4c<
-^?3saf]>;_k,aL&jb2dKEF6Z`jsoChjlYED`oY=8e8F"%[Bu*ljuI,;FMd-7L?;Lo:utO8U6Od$
-K]_EVHMQ\NR[iK&60=r,ja:1mk#(6aS`[M3jlM0Xg`Lts[,t6I`$<^mc=gn:q;qune)c8Fk#(6k
-PPO>AS=9E=!MO+Vk549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gq5aU8H2al[S39#[XK4iR@'##EC8!dbFZk#54^@ib%XC3Z:3ipU4bGtTXJA!Nri??!
-4bZ%rX@k/CX<]p0XDU1O6A7R[XBIb[XK6G*Hp"L3@m,N/O0"m84a4!/7Qk,RX;,_<4f#094["b*
-=?Vsm4aBU^Uh2cGr2^m-4]AFQ4f,5E5_;FQ4`HiQ;ll'D?"IKHJNZ.gri?>u4^"kfKb]LDX8uLb
-ri?Pu4bZ&#XFNGsPcUs+<rT0&M*4!hri?0#4]23[*^r5"W]`_NTPpp5:-F:oKfrjQAmB,QGs+<[
-XIUqGpoFsH4aK5lXCOJJ4cZV84\u'Y'9>:>Krh18Kft[%R6=Pe>-+fYAG</176RTNXJS-OpoFL=
-F8i6BVEI4rXS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1Kq:Yk/RJtnT`_B0pg=fY'HJ58kL<NA$PYIRV9m$6c%[p+V@[c#+9r:ahg<`Q"rn7Tc
-9rUk8g0Zl<g*BAGg5A\"<2`Qpg2]npg=hZ`SP7bkISHe9[bAbr9paSf=A=)9g(fZC:!hUr9hhnH
-E)"'29po9]d"+omr7W./9ki<d:!qZj;5I?d9od+cC>--kG(>"pUeOQirn7Tb9l\n@W#Mr=g&Z6$
-rn7fa9rUk@g7h;9]\;)$D>r5kY"_Virn7Eg9kXIZ*`l'^fM,B"bDk60@nipsWD._dJTZb%R8$Dp
-g;c6opt?4@9q+i1g4)hr9siWr9kF=X'=LV0WS5irWD1"Y_+ea'En]6FJ+qY%=A@?"g<r]"pt>b5
-P5a/:dS3YkgABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Yq;q^BUAj9id8<c6k2ooGJEF(5Nn7-@S5Gut;1&0%%\cgjBVOXL;6Ns-k1igCroOGu
-;6j'Uk%$UPjs3dck*&ZC=g:l7k'9g7k2r(/V,6=:Ki,-Q^uj'B;5!(6>u?.IjqX4[;;:6B;,Osf
-G#?>N;5.Msgk\h8r8o!F;/bT*;;LA6<N]T*;3oL)E9=u6I><I;X\hr*roOGt;0V0bYoU@QjoK_@
-roOYr;6j*^k,V?V`ocEMF8k;([o$"*roO9$;/Q<p*aDQnjAB+Ces5C[BMl'4Z;H4*LjP3FU/=e7
-k0cD:puW'T;5@%Nk(Za=;822B;/6*m'>RIBZKC(BZ;JX(bY`DDGin.mLA0g8>uBSCk2&sCpuVUI
-Rf;FNh,.7)k549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gq5aUc<9UC`Vu3=jWp-Sc0V&'B!I/bZX9>T"UhPDKX8o6tU]@@YXSejoV;83R6Ak]B
-!L$^*X9+&JWVNUuX/)P+JE!X6UcG?SXJYok!3>Ri!E,EdX9+kQU4KECX9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1Kq:YkeC?X@Oe,7MlfBLui4iR?Q!LT/Eg'$'Sc\8._g&T_%cN)M\gAK7sdG<LW<3Q5R
-!P<Bjg&e0Zf(n#&f[%luU>jl1cq)X>g=#oF!86hp!GKFNg&f2cc%4UGg'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Yq;q_'E9QEahu)4/j6>\,5g]Gk!MH"Ujojc"gPi6&joFE=gAp0sk5<s6gth)n=Le:k
-!QB<%joVeuiq_^>jP/FLX5`7FgJ$Mek2-$j!9N\3!H-6_joWk)fR`2^jp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7ghQ-]mr'UOKe#WY?6puOmX8n%R6i_GsX8o9u6i^2FX94q[7"4*r"\D*rXK5e,6i`j1
-XPp5b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KhV%scr)Wm0e(OoA=')*`g&S2O<reTQg&Tb&<rd#pg&o;q=.eI*"^G,_g=gfL<rgBo
-g>U`iir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YhW=g!r*'0?e)gbX>?e,qjoDge>6(;]joFH>>6&Z%jo`t7>H$NC"^tVok2q0k>6*3)
-k2GG,li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQ_i!2BCm!M-+YX8nuTX8o!nX9#>rJZS^L#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_Iup!6tGq!QNUZg&TBXg&TCrg&]jPJ_KtS#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`ai3!8.53!R]fqjoF%ojoF'4joOPsJ`cgk#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZQbj!Jk.]X8t>$o;htm4nPf[X'fM?F'tR'X94NMN10.8!.+1:!gR/?ri?0Z@"n0Q
-!d^qori?-#PQ%WbU/db8XS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_J#q!N^VFg&Xa*o@a5t:A!6EfQr)%Oa>(4g&ne!Z,H%`!1WN4!k`iLrn7FXHDpDg
-!h7o5rn7Bh])LCbc"tFOgABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`al4!OdRWjoJ/BoB$)7;Y9)UjFE$JR=N`Mjo`EA]?fm,!2T/I!loheroO9mJ?nb.
-!i4tSroO6%`;\m#fQ,Dkk549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQbj!EtN_X:pnaG&aUbUQhCPTp27KPaebNP_T.<+.8@hTrb>]PcLic(nQ=BV6$&K
-R]N?MUm7^@XK8+[T_YYkCOK`Hri@B4Pbb%TSWoD@Wg'<DR&mB]1mFK2XIPl^Pc(U]Pa%oDXJ(D4
-ri?0kF]87?%@36ZXJD/`R\-[_4KL[EX9!HbrN$$+MLhl+X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_J#q!HPRHg(V66QB0bRcFh9QbIl'J]YrOO]W(k`+2Y\;bhCdb]\1tU+3:9RdFuFL
-_qNPOd(Rc>g=jc`bPBioLn9'orn8X5][4sXa1T+>fY#SD_:mVb6+k1jg;V.b][PTb]Y)MCg<?Tl
-rn7FnQ"p9O%DKL.g<[Le_o^Wd9\N2>g&[G$rRq9rYCYF)g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`al4!I2?XjqGkVSsSU%fuDP(f>cG"`m<f&`j>X++3hg[fB25;`oZ<(+k*Slgucf"
-cK<s&gW/$hk2t:8f(nG1O/I]:roPKL`nT2/d`0>ij2Tinbi\';7E3^:k0VT;`o#q:`l?Znk1@"<
-roO:0ST+Pi%EZWOk1du>cID"=;!(URjoM!@rT4-0\:Nf>jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZQbj(g;s$XF4&I4`RR%=&`4hJK9?0,\='=;a(,]+bs&s7pN-C<)dq?D/_t5:99%H
-<)nd=+&s=_,HRY@<*#[gX=J(7A;%%cJQ,T8B9Q=p<-Y5n6r[-=XEkmdDQKpT6Z,k4XCbF2<i)n!
-X$-E_!L-O^X:BVW<-,.",)TB$S#e`R4T;D_F`[M_!FCY7XS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_J#q(im";g7E%o9on#YDJF%+Ua;kR/V)QaBhnZ]+ffBn>'8PiC2/pcMiLrXA(mbp
-C29u`-Yt)H/DABdC2M,ig+.uNI]1uSUha^DK"Gi6C73I4<bcEJg7'C'N8!!A<JtU?g4=!RD:.(k
-fhMG!!PE1Hg('ZgC6@5U/$E`*`7do=9`E`HP`l"!!I(_ugABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`al4(jNdWk,30;;O?P)FDu<HXXC9p0Sef,Dc6Ss+gc6.?[Lq3E,_9.P*TG"B]cI;
-E,iD,.<6eX0BUu0E-'S+jsuLjKsBe&X`8;^MT'UTE1u)Q>B"Sdk+jADPNM"g>*EoXk(mtqF5?!@
-j\c!=!QT0Yjpn8-E1,k$/\,kBcfS'd;#]SXS=9E=!IhP0k549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQek5+YcKXGpPdXCZCQ9RDbL6EEhNV,!_cXK"FbXI`7cXFG#D9oG!3Hu4.;G>>62
-NK%^bX?`(5RQRZBI>r\FqQ(O-UnFQcPujocG'$3JXK,ib@WSW3=fe\erN$L*(OW<PB7[.cS4p#c
-X$-E_'9lFsXGfl2NE:M/2I<5PVQ?2eRJs8gR8<d_!KgH7XS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_J&r50.Nag9PqSg457<@%=Ns;qbU!d::DSg=T0Sg;mjSg7a;+@^*.TSr9"_QXeaj
-Za,C;g/5RW_bAcgT<b+lqUue1d*'kk]l)BSQBGCqg=^qSI?N<lESB,?rRqb/*hD$%K;7/S`F.ER
-fhMG!'>/)6g9G(iZ>Q5e7!I&$e(V[m_Z&6i_IWW!!P!#ugABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`ao551=N(k.H-&k(f;cAYm&?=QX/Bh.YF&k2]G&k0n,&k,OHQB=YZrVNRX(T4mB9
-]tBD]k#KJuc;<Y2VnB!7qW8XIgXb3Ca*$A'Ssj!<k2h<&KUV&<GNS$arT4UF+/\2FMQGt&ct;G&
-j\c!='?>(Sk.>69]QC"48:B:DhWE)Fc2Qi+b\I+=!Q&r0k549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQbj$<iIkLLI9cGB']Dr`]P<XGpG<@fEG4W]dGbRn`j_!JE?0>8*-9HAbEkXFFDX
-7V/YdW'%.DX>Bi[!,M8/!K^F^X8kB^X9iWj@YLnE=fe\erN$$r6iO.f>)rT`"?`ceX$-E_"dDre
-XG&M1>69qg4SGiWF`[M_!FCY7XS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_J#q$?EN-X*`RSQ]KijrcA<pg9Yk"IK%q(fM:/S`F8`!!N8BbF;)0BS$670g7`P/
-=Ff+&eP+[jg-P^[!/U=%!Om"Gg&OhGg'NM+IAtr.ESB,?rRq;"<W:\QEjYi""AIP'fhMG!"h\U(
-g8RF<F98r*9_R0@P`l"!!I(_ugABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`al4$@';I["@H&TU4e6rd"a)k.Q&GK`:*;jAP.&ctE=>!O5/oH5"/YUq1)Mk,ETO
-?&.QBiDAZ5k!]2p!0?g8!PrpWjoA6Wjp@'HKX0aTGNS$arT4.9>5mXbGeX1>"An7Cj\c!="ikTE
-k-@JUH31tG;"j#PS=9E=!IhP0k549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQbj6!B;MVdk41/Q]$A=bVQ6XJf#PUTCPiKJ81_Wc!!6GBg#pJ;%lq<FMsr:982R
-Kf2\t0onD[3L,b5KnWg6XA_C[X>m1nH\HNjI;=Og?_^;2XEI%1X@n7cKrg1hLod\P=G;H6Q)pX4
-08HX1Rr^lSXJ]QXKl2X:/qp%pX9!HbrN$$+MZ'UW;a>o8#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_J#q6#s?de:+*j3H*WgEN,pYg=9k%ce@*rV`_$6f8Q#pQ^H9NU8a'NCO=c8A(l['
-WC17<5.+%q8\MZXWMt'pg1aI\g,RZ;S#MODT89JCGgBfTg6Gagg0^h=W7nLCXkMLRE2fgY^"UZ.
-40.)h`0+$(g=1PEWJmju4/pO#g&[G$rRq9rYPm/UC/KQ9#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`al46$U-+i.\2:4E]f2GI"N"k2C2Fg?.PKYX#VYj-6.@TV14qX0RqqEJ!=VB]b>H
-Z:JZY6GH=89ut5#ZEeo@k&+5qjuD=YUp?DgW/n6fJ(eLrk+,c7k%1i_Z0&Vd[cZ`*G-\E"a6(sX
-5IBS8c^InHk2:omZBMWD5-il:joM!@rT4-0\GbOjDcMAN#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZQbj!EtN_X:8lRP@L\qO(2[iXK7+sri?3e@q00NX9*EPE;lp[BOc@h@qVm=KWM7m
-A!:Dd@s`QOGCciQ@q246PTFl>X;GeaFf_Zm@qDa=@r/5cA"p&m@sP/WH"1RfX:Lq5@uRLjQ"+<9
-XK7@j@rVFK#AI[oXHI('ReWrbF`[M_!FCZ_X9+V-EIk1q]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_J#q!HPRHg'raa\p`;d[=*JCg=iNhrn7IfI=6_Hg&d@aO8diSKRK?CI=p8#VqTj`
-ICaj<I@H_!Q_`?=I=9>n]-`X6g),]qPhOi_I=U&#I>Q[<IEgK_I@8gCRXKnhg(2>SIBqS\]mY<\
-g=if[I?+<\#D@Mog:;W[_t_pdP`l"!!I(aHg&eo6O+H!hir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`al4!I2?Xjpd<'`.[:8^P%9fk2rt<roO='KS53]joUp'QN$"fMhIkdKSnpIYib)3
-KZ&P^KVYEBTWR@eKS7t>`[I5Kjqs87S`](4KS\dIKTP>^K\>M4KVIVkU4eO*jq$!qKY6I0aFo5'
-k2s:/KU2W"#E4>2k/2k*cM6N&S=9E=!IhQXjoWONQ\"9'li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQbj!N';DX9+B$X1,/2?`<t*!ha8,ri?0]E3"Pk#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_J#q!Rc;4g&eUAfsfZ9Ggu`H!m?;Lrn7F\NnK!;#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`al4!Sr=FjoW5_jgX@QJ)L=g!nN=iroO9rQK<\[#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z>gqU4KCsXF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(qc%4T"g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Nq2fn&::k(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uYt(+H:rRJZOF(o;i/-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%R5+.'eEXJ_G\/[email protected])Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&j(B._L>pJ`_OGoB$8Cs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uYsD>E+38JZOF(o;i/-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%R48FL$JOJ_G\/[email protected])Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&j'KHG"gkJ`_OGoB$8Cs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>g9NIe0^XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+Z@U_\g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]Rf3rk(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NIe0^XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+Z@U_\g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]Rf3rk(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NW#pZU7d(=JZOF(q5ae3map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\_7(+ZMiJXc-([lJ_G\/q:Z&4s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\`Np=]`$snf[bW9J`_OGq;qnIs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZ!Q1/<W(X8t^FJZOF(JZS[K#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%R7I5[peng&Y8@J_G\/J_KqR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j*\6YNk+joJ[TJ`_OGJ`cdj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZ1"M2@_'XGIsXJZOF(JZS[K#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RG"Xf]Oqg9)a/J_G\/J_KqR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j:8\$s]Gk-l_PJ`_OGJ`cdj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g[&a:oM1MaZXF[JJX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K[+YPpY(>;Xg4@uQg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y[,qD1\:Ndnk(2[ijp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#[LpT+Uq:f)P@XI+\8X9!jAJZOF(OfSbumap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CpqCpY#l!AS%Fdg;0]]g&[qfJ_G\/OkL$!s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3dWpZ;_9CMTd/k0("'joML0J`_OGOlcl6s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\?#[2pT+TiR$aVLXH.GsX9!.'ri?)kJZOF(Q)k2$map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\Cpq"pY#jU_84CMg:!.<g&[&Ern7?WJ_G\/Q.cH%s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3d4pZ;]fbKJQ#k.mDZjoLUcroO2hJ`_OGQ0&;:s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZgC86N$qFCK2[M6*XH)+[c/XE[9eXK5*P859)b%p__qXK6I\88##[88t:o<e7?'
-XIcKt]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S(G>B&<MPC/BpXkM<0+Br[9g6c*>g=fu<>@INb%sD0rg=h]4>D(Y3>E7!5D1UDl
-g7I"&ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jp^@!CbqRt?r6\)uXW,%,HRk+Q1ak2p9c?t]K$%t.j3k2r*V@#F*T@$]JRF+NJ)
-k+:]>li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\u[KaTK90UV&jlS5c^uZ31utHXJUDSXK6@gTUAHSXJ/XSXK86XTVSZf32NZYJ:XeQ
-XIcKt]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%Sagb":=@d3b7';VBaG7`rs/g<uU?g=hNAb/.N>g<OE?g=jqDb0Sek7a]k-UOh-M
-g7I"&ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&kU*ekP;hh'erI<orGo9%MYWk1uqek2qpcf$.dgk1O[fk2tJlf%]?F9&/KOXF]Mb
-k+:]>li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\?#Zmri?>eXK4RcXK4P^X9aSiXK6YcXJA8`X8uIbri?)^rN$-LCnan$JZOF(Su`.-
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CppVrn7TNg=f9Sg=f6ug'Fa+g=hmRg<`n"g&Z3$rn7?GrRqCGLs9\VJ_G\/T%XD.
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3cfroOG^k2oP&k2oM<jp8>Gk2r>&k1j2?joK\@roO2WrT46[OP"O%J`_OGT&p7C
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\?#Zmri?>eXK4RcXK4P^X9aSiXK6YcXJA8`X8uIbri?AfXIGWZVGM2Hri?-]JUsnR
-XJ2d#]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\CppVrn7TNg=f9Sg=f6ug'Fa+g=hmRg<`n"g&Z3$rn7WOg;Lk^dUeAnrn7C\Uk.6N
-g7m:*ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\E3cfroOG^k2oP&k2oM<jp8>Gk2r>&k1j2?joK\@roOJ_k0M<7hJ8@:roO6rXb#Vc
-k+^uBli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\u[ER4;U,ND&7\[(Lj=*(Hdn_XE$!>=fa8)XBQR'XAg;tGH@l[4AD6FXHYC;X9,Fu
-.=nROXJ2d#]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S[V9H?gHM]JLq*IQ@1*DF*!g5nEJES<N2g2nIFg1i'%QeL/I9Obilg:TNHg&fr<
-1kFA3g7m:*ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&kNm:``H\OrgX6++rKJ*`0i<k*SCeGNM+Jk'A5dk&;h<TB>9p:hS#7k/KXbjoXXZ
-2hC+Bk+^uBli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gOK8IqJc;_PN$=mFXF[IIX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KOP0_fU]/sKZ7="Jg4@tPg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YOQHS$XT%>`].MQak(2Zhjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gOfSUi-p%@/!Mbp2XF[IHX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KOkKk[1J7Z#!RAB0g4@tOg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YOlc^m2GX86!SYSFk(2Zgjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#^kFk!Jm=6?RaT_kej=6HY#Kf(tS>ca_t4A;NOU-q+HVQ?7L4CtJfX93l54Fd4/
-"K5fm4Iu8K!G.ktX957n4Au0[!*Aor!KhF%X8npeX8uY(JZQkm#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\CptiQ.4LfDW]XQbPTunDWf^hW'j<PFkY2S9OZ9$buRMWdb;W59Rt[ig&mp?9VM=:
-"P%rp9ZQq^!J/>eg&oZ29PFFZ!,hPb!P"6jg&T=ig&ZEFJ_J,t#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\E3h*S^cd%FQV]cf)+S0FQ_d%Z:@_eHfj(!:hJGDfNV0rhWE-\:l"$+jo_MX:oaBS
-"Q4u1:t#.$!Jo5"joa@O:i?9p!-Itt!Q(6'joF!+joKqdJ`au7#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#Zme#WOfk,\PFqlBd9kH#G\Ml`aBXC?pcN`rMWSZI$TX?<Sc@#+T["$EZd4Sl,^
-KOh0c4SYuYH(t)8!F:W]X8m25X9"`@ri?,`WqWRqJ7sM8`iKBUmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CppVe(Oe\k1Tf/qq;%/kLp][YhIK)g3fpSZuXl-a4cl@g.^5SHE?ts"&.G&9`!HG
-W.*IS9_d<BRa(W]!Ht^Fg&R*+g&]$drn7BJf_=)#U4e*O`nCXVs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3cfe)gXpk2lY?qrRmCkN3Pq]&qgOk(9u&^3JdNdcR3hk"t4&J[P@:"&S.B;#9;W
-Z%_?&;#'/RU=f8'!IVKVjoCY?joN]/roO5ZjS.d;X,DPk`o[Kks4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\?$u=XK68)?:A$pXJ/WUJukn^4Dcm)UfolGS?/fN4A/bFSO5M@U\_&-QTR^<XCat*
-4F=02TM7OeD3?K?>Zdg!X93PZ4BMN`'g=7OXF2s@3G(UZVI)H,XJdn.D+:,lX:nHtXC?pcN`rMW
-SZI$TX?<Sc@#+T[".$$`7Ja(gKOh0c4Sc'49eN!<N%B'5>c"N&+>>pIXH>V<XK5c&<'5`5XE-=<
-XK7<p4$]mB0gr*:0:f1pBS!8)X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\Cr6&g=hH_G?8iug<F>*V:sFL9Su*0cuMfW`nK.P9OD\Ua&PfNchc?2^e@h`g4EIH
-9Ushjb@4/)MRY[cF`5V'g&mNW9Q'j`'i$gDg7CZe8:jgpdWeHKg=8EdMcn0sg(S)6g3fpSZuXl-
-a4cl@g.^5SHE?ts"2<L7=Sg_SW.*IS9_mBr@QMQ`Z8[q?FOAf[.6UADg:'a`g=gd[C.tGWg6+m`
-g=ibM92XEh5$$BF4NH0MKRqjsg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E5)6k2qh.IU%/8k1OZLY3+Yt:m"/HgNZOpdH9T':h=dqdTKCggA9qIb"u@*k)!Dg
-:o*79en7gEOi'<.HZn0@jo_(m:iu^!'iR<Yk,1_09Slm6h1&7ik2A\5P$ZZ5jqDRRk(9u&^3JdN
-dcR3hk"t4&J[P@:"3BWY>l*RcZ%_?&;#06-B0F]*]K2NYHedb*.m["Yk.sl*k2q/*E)<\!k*el+
-k2s5q:K?Q26!NJ_5LS\pMh1$1jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>gbAH&YR-Aj"-4K2AHXD*/qK<0DVXHJUFUdV;=@B?"KK3"hMO]V=Z!'L7^&0R%8
-4KP;YS#fOoX@Q0HOHB=?!'L.[!'L7^&2J\eJip,AM6(i@XD0tGTmld<'0N@t@YUtE>-(AfXESZc
-4KPVlL\\"QX&bG\X9=2eXK4PZX:.mmXK4[+XDE9cXBgb^X9UkhXJ[2*X??K`!Jt1_X8tJari?E8
-Krg><XK7^gW.D%jX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(^J,\.F0Wlq49\+'og4c5NVV7P,g:=TEcrSl#HeQIqVesi8\8M)q!)3CG&1P$@
-9\Rg0`7epKg080o[^Q%d!)3:D!)3CG&3ldJUeKKeY1f,'g4rLoc(Ojc'27-6I&bo-EnXm@g6[lS
-9\S3HXSLQOfkn=sg'"@'g=f6qg'hN/g=fDag52BSg30^ug':=*g=.Rag._M"!NgYHg&Xt$rn7[,
-WS4b"g=j8XeUcGpg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`NpsLAp<Y1Uo'N:uZQ:k)?<qYNDZNk/4pqgfrpJK'(H=Y]JX__K>S8!)W[W&1bNX
-;!-JQcfT.nk$Vu:_8,p0!)WRT!)W[W&4<B[X\e/0\)s3Lk)NE:fW"Z.'2[iRK!a[SGiiPbk+J('
-;!-nk[JAqdj`AB:johrCk2oM8jpZ"Lk2o[0k)lM&k'Xc<jp+`Fk2.]/k"u'>!OmRXjoJB@roON?
-ZKAoGk2sa+iIU.3jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>h)8H,[u4KLZH4J`iV4?-h5ri?SlXJ/cY3CKrWLTISKJn"_\!'L%X!'L7^%6U_n
-4KOuHXK8=mX@SEHX8kB[X8kB^X9Leg4KLZH+T=J*:onDJp8esSDQKpKL9-D=X@o+cGB']HXK5fb
-qQ'am=.B#e"GC<eX??9Z$r<:mX?`_cCj`=c?&SW^#<])hVa7Dc4T;D_M-p7`!BmI^X9kRjX@]%c
-XG:;dJZQnn#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\_7),>lNFb9\N1o9[OkS9LsV+rn7iUg<FM/864GkX4l:KV0r9r!)31A!)3CG%8>L0
-9\REog=k'"g0:uZg&OhDg&OhGg'17)9\N1o./lmBB%i#sp=^4MMqZm4WnOh#g0_nSQ]Kiog=gkS
-qUu"qDoDJ*"K6e'g._:q$tR6/g/6DSM4NASG-Lnu#>Ek*e5G#S9`E`HXa0p"!D_;Hg'Pu,g0DeS
-g8fYSJ_J/u#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\`NqC@K,Bs;!(U::u*3i:eZR>roO\ek1FfQ9O$Y1[H?W#Y(Q`9!)WIQ!)W[W%8c3L
-;!-&:k2tRPk$YsujoA6TjoA6Wjp"ZE;!(U:/,i?ID!$b?p?!'aPNM"Z[-#)Ik%)p&TU4e;k2q6&
-qW7k3FjKmG"L3[Ck"tj8$u4&Lk#LC&Oeq4&I(K7<#>jRFhcJt&;#]SX[t"D>!E/"XjpBXHk$cg&
-k-Tg&J`b#8#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#Zmri@8*X?<RHWE>@cTR1C&XEQM&G]9`s7')8PXK6c0<MZ^W=no&u4T;Dk4KPVH
-XJApcXI=^A8>,^Y"$EZMLAn7S4T;Dk4KLZH4KMtGXK6?AC4?)^!F(3TX;Gr$XK5lcXH$Jc9:`/.
-END:(XC-gbXF"LWX92OdXDe*>%:X^dXFt,cX?<ScVGEKUX:.mmXK4[cXDE9cXBgb^X9UkhXJ\@c
-X??K`!Jt1_X9^thWH,)AD,4jEX9!ibrN$$U=+RHsX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\CppVrn8Mhg.^3oeo/1SbFF9[g6Y.[Q]BdP<na^$g=i()Cs^nDEVS5f9`E`T9\S2o
-g<a`Sg;B`?>Kccp"&.F^WrC]P9`E`T9\N1o9\Olog=hP?LS+Lu!Hb4;g),m;g=gqSg9bnS?cUle
-O4m:]g3TjSg73Wkg&l6&g5Z*c%=Fc$g8KJSg.^5Sdq$/jg'hN/g=fESg52BSg30^ug':=*g=0$S
-g._M"!NgYHg'CI+ere\?MI_D>g&[q$rRq:RDLpNcg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3cfroPA#k"t2:icW6&etn>*k+G0*TU+_t>NWGEk2rJSEnoflGPL;#;#]Sd;!-n:
-k1b"&k0C*k@+P)7"&S.$Zi9(e;#]Sd;!(U:;!*A:k2qrkNi;m<!ICsJjqsGWk2q9&k.Z*&ACBV5
-Qf_-,k(0r&k+m_1jo]_Bk*>r.%>1P?k-9X&k"t4&heC11jpZ"Lk2o\&k)lM&k'Xc<jp+`Fk208&
-k"u'>!OmRXjp4lGigJrkP%fjRjoMN@rT4-gFFiSujp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\?$u=XK67mIl2m5M5=378><(t4E3E`VHc6.0TW;t4?RJ\TgLqFVY[A.QTQraUh2<9
-K.q#@Uea*JUQR>nK(uDbMEFe4XK4T>4H4bCE(+n7HDb164J/Q02f/Jp!gajHrN$icKWM8N:cqFH
-XJ&$E=J`*f4?R2RXJJ*Hri?ej4?PO'XI:;HXK8@14?T19XG7CHri@VE1-0lC0OUn<5-.d@3-;7'
-OZY<[Wa@H>I5#WAF#YsXXK8'X5G5*ZV,*?TX9!ibri?1$:b%$tbcD#[map!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1K\Cr6&g=hHITgPbAY0h#Y>Kt`Q9TMg"dre?O4gj"Q9MC>qbZ.>Vde_Z3^e?jac[n9[
-VEBUecX]^ZcaZ/2V>/a^Y"WQVg=f:a9XC<QN`VHBRac^Y9ZbgP7>Urs!l#qArRr*^VqTkOAkZUY
-g<<SkE73IY9MBueg<iYorn8&[email protected];>Cog=k&*9MEI[g8bsorn8l35=qKQ4aP^I:YK\P8!DZ\
-[nJnXfQfWdSii%eP".fVg=j_E:s7SHd:Bohg&[q$rn7G+AMo%mbh<9\s5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1Y\E5)6k2qglW^j<Z\D2(#@+jOu:mOl=hKr(l6,2Qu:f*>8fNM*qh>67Jb"t?"gPJ2&
-YX"31gM'Jtg;?3OY5%,s\57(uk2oT-:q`blQ<]q[UYp`#:t4Gn8W`r6!m2dVrT4rsYib*&CJ\Ws
-k1Em7G2;<,:f)r+k1im:roOn`:f'^Fk0>N;k2tTU:f,R%k-Po9roP_D6;=Dk5_.lb;s&0j9:Y/,
-_,*BnjF9G.Va-R1RS-(mk2t5l<7^3oghFe-joMN@roO:CCH-n-biT,qs4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7g\?#^JHh"0<F*4Ud!E3UmX9+A=U\Lnk?X!3*!B>\\X9"YbrN$$%OT)<_V'h[^XN[aM
-]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\Cpt@SFP;6P*E*&!G[2Jg&eTKchQ2pH#iZ5!Cip8g&\s$rRq9j[f4t^d5&Rig<A7T
-ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\E3gTV"*RJR[gMB!H<nXjoW4dgA'e2IsLeN!D9NEjoNVArT4-(_#EHtgbm?-k02rl
-li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\?#_2Vt@%nR63TSX7*+iK`!q4F6fn-Wr+sZ:#i;UVQ/d[!NN'lX9#6!pT+@ke>rb"
-3]<B)X8o*pX8o)JXNR[L]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\Cpu9e+D>s_G!Xfg$dVpVu03gOmC^$fDJ;B@cQ/Ce(Eg:!S>fpg&]^TpY#VpeCk"q
-8jpJog&TP!g&]mSJ_J<$#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\E3hQht6%6bYV-+jmV=3Z2@DuRHru8j8;^RBB/+ThW3h]!TW)3joOB"pZ;J2eE-k1
-:.WS-joF38joOT"J`b/<#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#ZopT+UK4?RVbXGCB\X8uOdri?*TJZOF(Q)k2$map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CppYpY#kF9MCQ%g8o_sg&Z9'rn7@RJ_G\/Q.cH%s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3cipZ;^Z:f*M@k-]m:joKbCroO3gJ`_OGQ0&;:s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z?[IKWM8TWN)ntXK8?]W2Qf!Wgo6RXJi1uW;`k/WK!XRXK"=[WN</!WiW.uJZOF(
-Su`.-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S(UeYq3Uf@JR(f\5'09%DMHg=O?Tg=k*0e^aZQ&(\)3g=k.Ne^iI,e^rO*eq)P+
-g7I"&ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jpmiN_P-j5T+XjQ>U`:>t0ok2Xh+k2tX`iSjdu&)t:Tk2t]!iSs"\iT'%YiIU-B
-k+:]>li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\u[KU5U`_8E$8(D>cakh(-kWrXE64+XK4-H5XL1+XB-R+XK6:T5[pgL(2KWh6@l4h
-XIcKt]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%SaX;)?q[N[e[=FkYAC*)U2!g64aJg=e_n;,jOKg28CJg=hK*;1.)s*/Mik;h<YR
-g7I"&ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&kTo<As"%Pq?iQI-0?e*`Zn9k*n_ik2o!:<EQQhk&`/hk2qjK<J'A>*fnr,=FoUc
-k+:]>li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\?#Zmri?>YRB/QPXK4P^X9aSiXK6YDXJA8`X8uIbri?)^rN$,hV5mp\JZOF(Su`.-
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CppVrn7T>_V.`;g=f6ug'Fa+g=hm+g<`n"g&Z3$rn7?GrRqBSdFi`JJ_G\/T%XD.
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3cfroOGNbiVdak2oM<jp8>Gk2r=Qk1j2?joK\@roO2WrT45ch;j$rJ`_OGT&p7C
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\?#Zmri?>eXK4RcXK4P^X9aSiXK6YcXJA8`X8uIbri?)^rN$*r7@Qu%XF[IDX9Q9(
-f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\CppVrn7TNg=f9Sg=f6ug'Fa+g=hmRg<`n"g&Z3$rn7?GrRqA"=2eU!g4@tKg'6R:
-hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3cfroOG^k2oP&k2oM<jp8>Gk2r>&k1j2?joK\@roO2WrT449>gR)6k(2Zcjp(/O
-g!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\u[H_R5LD3Tf&XC2P7%<24:DEXJ0r?Suc^<XI),JXIW.:UTCOaR='ajWb45Tri?-4
-7tIamXJ2d#]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S^e_F)2lbX9b+7*4-!6c.C-g<H"%aP)H!g;$D3g;d`tcJ$uP_O[^\f7HH)rn7C(
->(PCYg7m:*ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&kR(bX]n:fLO`R8CZbF8'KoRk1QDKe)l^Fk0$TYk0e"Eg?.O$bbh`/j,$@KroO6;
-?\.?jk+^uBli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uYn*r_EckGYa*V:N*32:D]D"XF*f>B<5$-XD:UrXCG%%J?5i9:Mg$3!K::_X9+qC
->Cil,XJ2d#]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%R/.raZ8VQt38,A<#.=A/E&8g7;bbKA($Mg5':Pg3mLBU>">5A;U<>!O?hHg&f;R
-F+N%rg7m:*ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&j"Erb;\gTk_!OC6[]VC)>(Uk+ug-MWShlk)X8sk(IJaX6/Q`C6AMX!PEaXjoWsl
-H@b40k+^uBli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gOfSVP=)\)>!g-Q_JZOF(U9"R1map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KOkKlRDN4YL!k<-uJ_G\/U=oh2s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YOlc_iFHujf!lB'<J`_OGU?2[Gs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gOfSV'='pN[JZPBC#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KOkKksDKp`dJ_HXJ#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YOlc_2FFSl(J``Kb#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#anMNNIkJZOF(orJA/map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\Cq"mY.&u9J_G\/p"BW0s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3k.\AEgZJ`_OGp#ZJEs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>m`>@)7EX9+/PG(H`GXF[JQX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7.[FEic@g&e?bQ@[b@g4@uXg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`O!pH@D+TjoVr(Sq6$Tk(2[pjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZC"7;@FOXJ(5tSZJohNCs2O"."OjNW-![JqS]VJZOd2#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]%RY!=,3X$g<?Cia4f7pZX3Xb"2:V.Zi8YZV5JmuJ_H%9#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]&jL6>`PuDk1Hi>dcT]J]jq'("3I^K]`.$oY-<K>J`_mQ#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\uZio2H+4^XB9(H;6-e"Sk?)cRTF*52QWuoAn>k2XF[I3X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1K]%S*g7;@D!g2DOnBA)"maBmTS`,:-W7,$@LJU`W0g4@t:g'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Y]&js'88j=;k&lK9D<9pBdpqP&cZFu!8ET&oLk_+Ek(2ZRjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7g\Z>g9NW-!pR<j00X/rCo9!#+\=*f1dXF!ZfH:WX=XF[I4X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1K\_7(+ZMrPn_OI#Rg"P0$?J=,JDk!6?g7)N?RTlV>g4@t;g'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Y\`Np=]`.%/bbV$qjlY^SA*2prFekhbk+lXcUL:6Uk(2ZSjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7g\Z>g9NW-!b<Gl\%X/rCo9)bmrN,EN?XE[;8D?-2XXF[I4X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1K\_7(+ZMrP`CQ"**g"P0$?N/X_Z&=Ncg6Z%CMZCbJg4@t;g'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Y\`Np=]`.%!EKcSCjlY^SA,bTp]9AG.k+H,]P5rs\k(2ZSjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7g\u[$)4^O5OXAa1L'o&fUBeaq8O$.Q*>cau8F)tWJXH`mKJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S:$9m=)#g1c[t)l_Q*Kg2'\[7udGFkYMrOcagpg:[TsJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k-9;16:Ck&6Z?*4+eKNC'E&^JUDeHfjFBR@/H;k/[Y?J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZKqF`ihJXIaQhM287"F`i)5U],B9VuEdtFTm])X@YLKJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%RalQ'Jl5g;oPYXfU6kQ'IoocMj(/eGe2%Pm+DGg0I@sJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&jU,SXmX[k0om-\$kGASXlY?g&@NBi;Vm=SHZUek$h-?J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gS?)^&JZOF(O/rPsmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KSD!spJ_G\/O4jfts5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YSE9g.J`_OGO6-Z4s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZgF@q1@sXI<X/P,taH@q2%1XG14pVQ?kI@qU@oJZOd2#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]%S(KIX\EQg;AAg]%YlHIX];jg8]UNdb<EHIY*.)J_H%9#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]&jpbKn["uk08U6`9-3tKn[q:k-ThrhWEsuKo(BCJ`_mQ#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\uZiWKS3?oXA";#8?8X^KS3($Pur]m;QPO^KRd<YXF[I3X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1K]%S*IW2OLLg0gkX>hRS6W2O1Z]l0jJB\KA6W1nBbg4@t:g'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Y]&jr\Z*A;ok%1g&@HHBXZ*@s(aEFhnDW\0XZ)`5&k(2ZRjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7g\#^EGPcR!KX?EV\6`d@OXH$GbX?<S/E3,j'JZOF(N3!5pmap!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1K\(V[6]\6'5g.g8J<8-&"g9bkRg.^4eNnVi\J_G\/N7nKqs5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1Y\)nNH`o^+[k#(6r=m"jCk.Z*&k"t35QKHt,J`_OGN91?1s4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7g\Z?]n4BJ>[4KPVIX//1bX?<SE=fe\eXE\]cUdTd8JZOg3#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K\_7sg9Q&529\S2pg!NdQg.^5-ESB,?g6[iRcrP_OJ_H(:#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y\`Og':itIS;!-n;jkX)%k"t3SGin-bk+J%&gfo?lJ`_pR#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\#^EGPcR!KX?EV\6`d@OXH$GbX?<S/E3,j'JZOF(N3!5pmap!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1K\(V[6]\6'5g.g8J<8-&"g9bkRg.^4eNnVi\J_G\/N7nKqs5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1Y\)nNH`o^+[k#(6r=m"jCk.Z*&k"t35QKHt,J`_OGN91?1s4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7g\u[$>XK5BcX?<Sc4fbDHXK4OcN`iHb4KNdHXJA7cXJ^lOJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S:?g=g;Sg.^5S:"dong=f6SZuOgR9\Phng<`mSg=37QJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k-Uk2pX&k"t4&;<?V:k2oM&^3Jf&;!+F:k1j2'k2<])J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7g\u[#m9heZ^XC=mu=feT)9hf3#T2nZ\EibO)9hg)<XH`dHJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S9c@:=#tg3d=;ES8o^@:=]?a_bHpOP7?]@:Gk_g:[KoJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k-"AnH,:k(@8XGNIh-AnHh\e8f/5R-)G-An\.*k/RJ:J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZgMS"$4TXJhVXVQ?krS"$@XXJ;8SX/rCrS"0JZ!]=DcJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S(S`Pp3Xg==0]e(WO(`PpB]g<[aWf\5''`Q%o2!^qCdJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&jpkd*UP0k2=V5hWEtVd*Ub6k1\2/jQ>UVd*_jT!_7k%J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gS?)^?JZOF(O/rPsmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KSD!t:J_G\/O4jfts5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YSE9gOJ`_OGO6-Z4s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZgB4[!tiXH5S.KrhA,4[#%2XE$HeU9(G,4[O_$JZOd2#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]%S(E:/7,/g9saOW7ot$:/8FTg6#-*cJ%!$:/leuJ_H%9#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]&jp\;Gs+Kk.jkmZKC;O;GtKrk*]+Fg#hFN;H\S5J`_mQ#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\uZi\X/f3aX?<Pa4fbDHX/eCbO'/Na4fimIX.r+7XF[I3X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1K]%S*Of[srOg.g5P:>+&qf[rpP[;jjO:"ktpfZmQLg4@t:g'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Y]&jrbjQ(:"k#(4#;WZ_<jQ'2#^Nei#;<FO;jP!jik(2ZRjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7g\Z?^KVGrh^4KPVIX//1bX?<SE=fe\eXE\]cUdTd8JZOg3#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K\_7tQdV?JL9\S2pg!NdQg.^5-ESB,?g6[iRcrP_OJ_H(:#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y\`OgihJgNt;!-n;jkX)%k"t3SGin-bk+J%&gfo?lJ`_pR#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\Z?]q6<Bq`4KPVIX//1bX?<SE=fe\eXE\]cUdTd8JZOg3#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K\_7sk<,U"89\S2pg!NdQg.^5-ESB,?g6[iRcrP_OJ_H(:#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y\`Og*=EN9Z;!-n;jkX)%k"t3SGin-bk+J%&gfo?lJ`_pR#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\#^EGPcR!KX?EV\6`d@OXH$GbX?<S/E3,j'JZOF(N3!5pmap!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1K\(V[6]\6'5g.g8J<8-&"g9bkRg.^4eNnVi\J_G\/N7nKqs5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1Y\)nNH`o^+[k#(6r=m"jCk.Z*&k"t35QKHt,J`_OGN91?1s4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7g\u[$%XK5BcX?<Sc4fbDHXK4OcN`iHb4KNdHXJA7cXJ00sJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S9tg=g;Sg.^5S:"dong=f6SZuOgR9\Phng<`mSg<G&gJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k-4k2pX&k"t4&;<?V:k2oM&^3Jf&;!+F:k1j2'k1PF<J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7g\u[$.4?R)NXEH]gCTOOM4?RqkV-c>IM6*@M4?o+4XG7.GJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S:+9MBi_g6PE+Lt^L89MCr0dWnM[Y1h'89MiCUg8b[oJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k-@:f)f%k+5CGOQPV_:f*qLh1&6t\)u7^:fYQuk-PW:J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gS?)`FI=\JNXH9Lf]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KSD"!+Sq5UHg5t"mir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YSE9i;Vh*u]k)e^0li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gS?)^XJZOF(O/rPsmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KSD!tYJ_G\/O4jfts5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YSE9gpJ`_OGO6-Z4s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gZ`FY&20Z.!,s4:FXHG%q4@/tJ!Gs:]X9t:\4B%oSN]]F0V#%.pE'-7)JZOF(WN6<8
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KZe>o'6^QNU02,&)g:B199N1rE!K&`0g'YVp9PV`(ZqO/:d/)GuO%`62J_G\/WS.R9
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YZfVb>7\Jo#1/Le7k/98V:fmYY!KoD;jpK75:iOtI^/.XSh"p.8Q;CDIJ`_OGWTFEN
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\#^3g@'$FtE,VhWI]TV5XIk<MX??K`s#g+Y$;-nkG&aU1XK5fcqQ'oaXK4OcU.gu+
-XF[ITX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\(VIaH.ptRNfDcDTA&!mg<-MNg._M"s%N7B$=:g-QB9gjg=ghSqUu0Jg=f6Sc!\A=
-g4@t[g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\)n=!JEGuuQBgUlW935=k1-p&k"u'>s%rOR$=hQISs\Z9k2q3&qW8#Zk2oM&fk&BY
-k(2Zsjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZ49J4OOMXFt,/DuHa<Bn-)_##phgX@ApHq5ap5H%9LXXK7k@>E\ia#s>;j4KPQQ
-:L8j.XF[IVX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%RJ>U0NW!g8KLgNW%Q3KVA@u#&:g)g0)Zoq:Z1)RA,8-g=jK>F1D)##u'(,9\S.=
-A9Y/,g4@t]g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&j=VX'q1Ak-9Z6Q2ThGN2lj=#&qTEk$H\:q;r$;U8s*Ok2ssiH,KL@#uKdH;!-id
-C43OAk(2Zujp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uYs@BV>@+"':V1DuHa<@YXi_#"tMgN*NGHq5apCAS>A+XK7Ot=I/fb"$EZd4T2>_
-MICm`XF[IWX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%R43KZa;J")bW:NW%Q3I&d/!#%,F)Z?4eoq:Z1:J:r*Jg=j&iE528'"&.G&9`<ZH
-YBugkg4@t^g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&j'EMq.gh"*DDRQ2ThGK<tO=#%Z0E]R/d;q;r$NLPpPhk2sO=G00UC"&S.B;#TMX
-\Up]0k(2[!jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZ4+4Dg:`X=nft:B%<rSkH*_X9aYjX/pP@GUe^LX9;.eXEJU^X8u^bqQ'c]XK4P`
-X94)Y:oJrHJZQ)W#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RJ-9T$F8g,k[;@fG'_a^<^"g'Fg,g"Md&Qo22Gg&ta'g6Rj!g&ZK$qUu$Fg=f7"
-g&n0lA^u@cJ_I?^#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j=D:m/cZk!#JYB`@,qe7I_?jp8GHjlW4MTfB^]jof2Ck+7t=joL"@qW7lVk2oM>
-jo_f4CZ0j,J`a3!#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#p^<E-&BE)&t'X9"nbrN%&q@B?Q!E,[1[XK7sTRB3J^Sud*TXCJ?5@#1ncE)ut>
-#X#2i4KP2<AWH_j!CVNjXF[I[X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\Cq1XChh[hNal>ng&]9$rRr<nHeR2kNfGiqg=jS@_V3^MaP)rAg4%c0H*,fSO)=mM
-#Y`t+9\RZ`J@#4.!EQ%Jg4@tbg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E4$lEcC03Q"a\[email protected]')4?Q'F26k2t)hc0".ue)m6hk(Vs[J@=V&Q?3&f
-#Z0[G;!-A,LqWcL!F)^Xk(2[%jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gZE+6r4KGQbUMTn1!L.s0X9XGABWS;+4.6)L#Xpj_XK89]4Dt/"!H;'<X948@4H'$:
-!f7bGJZOF([&aJCmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KZJ#L]9\J.RcADMR!P=m#g'=QMK\G/#9>^\^#Zj]Eg=jtK9T/o(!KM!qg'4WP9X3=*
-g&0P*XrjKkg4@tbg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YZK;?m;!$j%foZ0p!QCl5jp/1gMrs0M:X&h##[C2Uk2tMs:m1h?!L@d*jp&7j:qGfO
-jo"6B\0.r*k(2[%jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZS[K!DIrnXF[IZX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_KqR!FVROg4@tag'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`cdj!G/6]k(2[$jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#_2V7ir2VPrFS"0%i^VYR:rV4aokV#HndVlZWlSH,YgX9"rjq5a[pSXleVX9,)d
-TD5JhSt2YTX9YDpXK8@kSYu:b!Ml`HXL,&5]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\Cpu8dCn67dam@1"4kN5e+q]#dE:1sci1rdeCr1H`rO]ig&]@Eq:Yr!a2cg-g&fO>
-anXQkaN)U)g'>gKg=k)ta4'k<!RTGLg9fQ<ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\E3hPgqDhNhVmDT"6.bWhYH::h:C`Ng]#V&hr`SjdK&;+joO#hq;qe8daI1OjoX2`
-eG//-e'ctKjp0Jmk2tXNdbjl_!Sl^dk-X7Tli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\?#^HII4*;HXW3,X9"oLlDt"tKDqqPHhONDM3<XqKDo9ZOnc![B1kmOqQ(C*="CAR
-912E0END)l9.G^uXG&fHqQ'gr=%c2&qQ'g^;+jW9qQ(6V91r3MXK7:H=0/K691rEgqQ'^DD1Sdq
-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\Cpt>T'b55S9qs:g&]9tlIl8hVZ,9LSG(Y>Y.:UeVZ(oB\G4b[JmVlaqUuY/DDp5&
-?WUT$O4m'1?T"q=g8I_oqUu)"DdQk-qUu(^B4#,FqUuLP?XIN^g=i`2DVEfn?XIg+qUtt>Mh0Th
-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3gQVsWUJV1QeUjoNu@lK/,&YQ!YaV=s$S\AP`:YPs+R_YE6qM.C/&qW8LFF?/LG
-A6WS5Qf^nNA2q!Zk-7d:qW7q9F_#$EqW7ptD.I:_qW8?eARo`%k2s0WFQV_>A7ToFqW7gSP(Dc&
-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\?#Zmri@*:QBn>JSXu@;VlZ>\R?jkSXHZh3XK%SSXI5BRqlC+)QBn2FXF=!3U\Lo(
-R[0nRVj<jEQDL[QL7YKJTer()poG07E*'--08G<RX/rCmQD^g_Q8Fnsri@!5P!"c+MI&EHXI#of
-E-SIKXK#TcXJf$<@f!//Rn]uc4Sl,^D0i:P:AV%+:8t=2I&s>PFB>QF9!#*YWMr".TDbhk4FsT@
-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\CppVrn8@@^:qtJ`lZ36eCqga_7nRUg:M9jg=O'Tg;:STqq;A0^:qbDg7MrjcM6*,
-_nO^Ue%WiC^<tZSWlWoJbX0%^pt?F)Nc3Xe40,Def\5&u^=:le^-]QQrn87:\P0EbYBN[og:u4m
-NLAM4g=LPSg=9l"IJVY#`F7KS9`!HGMjrG<A,=mnA(K@jS_D\;P]#4/?J=+/f@EWeb5L#o9S(p)
-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3cfroP3WaN3,udF?Oahr`29bfJi,k/DJ9k2XP,k0;!,qrS4GaN2ook,<(:g%a\C
-cH+u,hoO0naP>q)Zd\(!f1*j-puW9;Q?D?45I@e+jQ>UOaPZ.=a@=7troP*R_be,1\U@<:k/u]G
-Q(d?Zk2Um%k2C3HK_jg6ctDM';#9;WP,.6cB_pj*B]A0:V<6faS93oUAEN#Rio3e4ec"V1:k@c9
-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\?#Zmri?W<;GpStCEleVA#rW_;c7Q5X9iijXJ@ICXA^XCqlC*E;GpPbXAUTILA@nb
-LK%/bXHt,CF<-FDCbULCXFD6gB_e_JU+eV\TWC8WX?NYcNDrebXIW60;JE56G?7iEX9(Mc4T)8\
-4T2>dS4p#cNE_*GqQ'gh9rtEYqQ'g:HE<Q1poF_#=-K_R:Q\`WX9XtiX/rC<<Fc$0!'Gh6[&aJC
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CppVrn7m.BP;;:LFd4SIG/EtC1rS*g'Ne,g<_oig1`Liqq;@<BP;5#g1WHZWqk?_
-X(l=$g:o.hP9dQiLcqWhg7]d*K_a=?c94c\bM#YDg.p;SZ>4-$g;dkPBSG0oQ>UR=g&at%9`3TE
-9`<ZM`aINSZZE*oqUu(k@G9F/qUu(1S(bbipt>u*DS"Q=A@QOUg'>9,f\5&8CjuB;!).st[+Y`D
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3cfroO`ADJjRXO"PEiK][5;Df1g=jp@?Hk1`(4k&3<4qrS3PDJjL@k&!1tZh`_t
-ZuBo@k/o<4RjPo4O?p)4k,KbGMtuKRfg&:qf&ffkk#1:&]Q%hAk0e,oDN3f@T655SjoSBA;#KGU
-;#TM]d:MJ&]m6o:qW7q-BBJ>QqW7pDUuos9puVhBFN!=dC;P)kjp/nHjQ>TcEeXMT!)S7/[,qSY
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>gUEW3$YOcGGWX/.bNXG1/D8uSh4FKDQ_Gc[uaHE;U1qQ'pgNfHnkXGgEZX9tLc
-LlQ%^XIE<qQN!rdAV9u`!'L"W';[f_3MWZ4NcoEDV`fcpD.0NI4T;D`MI)#9X93?cX??H_!Lcd^
-X9XYgXK5$cKjsn["Ii,eX???\"DrIdRSN[[#bkFhXK5*cO]VO`!h*8crN$3eC2g8UDL-l8[B'SD
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\_7(NO8diP\?rV.g!N:9g8]P-?IdbmPhOiOR+g8PS(aQiqUu1h['XAGg9Phqg'Yl#
-XL*M5g;IrO^AcgeJ>W>"!)3.@'@BKZ8C-!V[$?^+e5!$NML4(29`E`IYBQrEg&m;&g._J!!Q/FG
-g'=m*g=flSWI=Ws"N=g'g._@s"H/c'_diMr#gRD+g=frS\8M<"!lK!$rRqIeL5t!AMjo:O[FtiE
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\`NpcQN$"c_S3`OjkWP`k-T`SA)ZR=SEAt"T]YC#UZSS8qW8%*^:n<ik.?!8jpKO?
-[_@NXk0J3raSt<&LTg^>!)WFP'AZJo9\\]!^7L\Ri)6nqOb)ZW;#]SY\UCa^jo^jBk"u$=!R5?W
-jp/JFk2p1&Z@r):"OLfDk"tp:"HoSCc=m%9#haCGk2p:&_K>e>!mYu@rT4=&NgAhiPG<]k[H7\Z
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\?#Zmri?f>>$<&LV*h>cQ;W`GXK6ncXK6Acri?/`X??<[#AmXJ15N#j>kkB$ROS5>
-"bs+[>#hU%X8umbri?)^pT+dt0KUn[X=%1RN3&m#r`TDTXK4P_X9j)P<iiB35Z/VRri?,fV>[Iq
-4T;Db/5e_dV>I=sRn]uc4Sl,^D0i:P:ALsl=-<K`#Vo:H.A*]-=/Z"u!c(eHri?)^JZQ5[#.j6S
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\CppVrn8'/EcNS]d8\iR^1alng=i6Sg=hRSrn7EIg._=r#E!PB5HWYFFSOPj`&%C5
-"fg;1F)9J-g&Z`$rn7?GpY$&$4\@cYg+m\eZ.dYXrc/+9g=f7!g'O*aD;*]k;.q5Mrn7BQdJ_c!
-9`E`K2eZ&NdJMW#`F7KS9`!HGMjrG<A,4gZDRf]"#X<!)1s+IcDUeX=!f(T@rn7?GJ_IKb#3,[>
-g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\E3cfroOoBG^(_"h-&n&a_eb:k2r\&k2qu&roO8Yk"tm9#Ej=V6al-hHhc_(c8PZH
-"gd@RH#hsEjoL7@roO2WpZ;n;5YaJnju%C+]B7s&rceOHk2oM=jp@Z&F6;V:<c07croO5bh#6@8
-;#]S[3c7q^h#$4:ctDM';#9;WP,.6cB_gckFMe%>#X`K82q7!3FPm&Z!fqAUroO2WJ`a?%#4)<B
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#Zmri@#2L2[lkV&+3-=J1ZrI>1q#XHQ^lQ)q'I.YRW!$;uV.+`ONH=b^.VqlC^9
-D0L_ZGb[]SL-;32O\]SVXK5-NFFL<mH5ca`'O5TYXHtT2V-K1aF)m"`EMeIDL8k0R#c*VGNhVhm
--]e8.!CN^^X8kB^X:Lbc>X53gX@Z*eXIi@EL/.`L,U%92XF"]:Ht'1YNu"4dXA3nm?%T/IQ=`+O
-X?:oc5H:\FI@pJ>!'L1\!>p69XLkP<]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\CppVrn88tWfA%0d2e@LDp,L8SuQhWg:M9I^"V2J25g9($>HN6.ZW5oEN4-,qq;t?
-MO1?1REns)W_LXi\7C3,g=g#9PG$X`Rj%aa'QoFSg;#ejdWN+RP*)c:O4($iWn.1'#gg+U[EcLa
-0t.)8!EIPGg&OhGg(2*8FA^QAg0J+?g<!s,Wal%^,V"u2g73quSUK5G[2d0>g1$>IG,<p3^4Ai$
-g.\-=:tO8lT$%#c!)3=E!?Rkag:Q&Cir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\E3cfroP,0[$D]Mh&i&lFk48VVmL^&k/DIka6)O!33i;A$?!5N/=#A:GI2\NqrSgW
-P+]1UU"WbIZr,E:_J+kMk2p<`S#PQ4Ua,j#'RQ-gk/op:h0[*%R[LO\Qeo)6[,M#H#i*<o^Y-]4
-1r0+Q!F":WjoA6Wjq#_XHWK(ek$hoak1"4SZt]O%,V5GIk,"*FVM+*o^E1bak%L<mI'2VXaG<LC
-k"r"`<9)t7Vq(b.!)WUU!?e:kk.Ba[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\?#Zmri@$+@X*9IV*fB7S?.`RCLX-AXF"DcJ#o`D<hK2h$)h<IMeoJrKOTr9X:oP^
-E3,L;G(!haXES,_KWM8G@W_UN!Ad.BX:U5OLTH,;Ni]=/XK6SSCTO3.@K<8"X9+2eM#OIVJ#WCJ
-!.4XF#&@\FXK6brri?3[@Uc#0X8usqri?0F@VPhC"eK2!XK6jL@K;boX9<KOTr_u-@K<J)X8kB]
-X9*5_Q%?$KX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\CppVrn8:-I$gIpd8ZBY`S.\=Lj[Y)g73P<U"\5BCs)S-$.XEWY_h)fW-koGg(TNp
-NnVF!QCiQ:g6R,6VqTkFI$=Q`!C9fcg(:EtXP0P![+a6(g=hg>LYBoMHiVRhg&eC(Xo@#TT[s(q
-!1`u@#)@TSg=i'frn7IYI!j-:g&Zi7rn7F?I"hRR"iu)<g=i1uHiUq\g'!F`bh@dMHiVjqg&OhF
-g&d0_]ReeKg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3cfroP-DJtT!;h-$;#d,r&eOFl<Nk,!Z]WoiHnEn1!J$/pJp\rc(:Z%BX`jqF&4
-QKHMFSu71Zk+@6WYib)rJt)c%!C^5kjq,&?[H=ZE^?4RSk2r4dO65!lJcOX%joVuC[f5CiWT*m=
-!2]VU#*4Amk2rJ:roO<oJqDSQjoL@TroO9SJrTcl"k/(Xk2rT@JcNsmjoh!%fB/(lJcOm-joA6V
-joU\ta+<Bbjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\?#^mFo&0@LbXP]X9*B.M>4.UQu5'_XJ5WB!0?iT!0I,.!28YY!EH%^X9!C+rN$$(
-Tn0;VX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\CptlQ2929X?NK[g&d=7Xn^TR_2D%7g<KPh!4DOS!4Mg!!6j]]!Gg2Lg&[AJrRq9n
-b^nKZg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3h-SbhIM[R.1sjoUlO\+o(hbEGiZk1T[3!5J6i!5SN3!8$Jt!HI%^joLphrT4-+
-fR`1rjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gYH.eSBlF!P!d/4%poFX[Bka9BSc!1%JbH/FK)B<_S:RbmXK/E,]'e2#LXYejeHa-I
-n)qLUg-U;~>
-#$LBV\D!1KYM'&MKoH#b!gJD+pt>nZKn[b)a8CVkU\<CAV>Q#I`IZ`og8ip3ir@lhL=5Yig'>fP
-mcqOUfg1,~>
-#$LBV\^d1YYN>nbNKjG)!h>7CpuVapNK)QPdeo()XS1cVY5F7Zd"1>1k,[VKli5YgLXYejeHa-I
-n)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gOfSS\BS!79XIH9q]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KOkKibKRqj.g7-e#ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YOlc]$N.L,Bk*tK;li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g];ud2GE@-1I&sE*DjRQ,Q#DP.N3&"WDl<T9#B+XIS?.*VHMOWEHnB8ori?BaDj#g/
-K7n03JZOF(WN6<8map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]@n%2QaW?hS_Df!NPF3$]T'(cZJ)UDNRRm\#E=kY`nI#DS,(b?SN2\5rn7X_NOl'g
-VPfElJ_G\/WS.R9s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]B0mIT>726VWR$KQ-&1Na-F04]]QklQ/DT'#F1^sdH7<kV"s-TV*($RroOKuQ,Kr7
-YHX;<J`_OGWTFENs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g]<!6C,?Q'm26;[CGYt?4;g;UhOdTEuGZh,I@!Hi?Is,UPDKDlUX:Tq:G`Sr-P$E63
-1lN5]GZ1MkXF[IQX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]@nLD/9!"Y6e\_iR:jsnC708k\AE?UR;ps4HC:$NTpCM&Mil]ig(:&CRC:i'\TO<V
-6*VG[R;16&g4@tXg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]B1?[/p8ak8*7@5Tl&Z>DkVV,_T[>"Tm,YZJ>&MgWh,<GPF:P0jq+X[TtogQ_gA(t
-7CsUqTlAn?k(2Zpjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZ)uX?<RHX=O9`s#g:^%QphoM.gQ\XE\]cXFl*tri?,tQM[`aUIG-_!'L7^#&()#
-XK8-cJZOF(WiQE9map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%R?^g.^3og,Aq`!D?,cg($g1g9$$]7,!ufg=iF"?iJa[B>=>t!RFjGg&OhGg'35a
-9\S4F=b5:Xg8`j2ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&j2nk"t2:juNF!s%r^W%T)<M[u6/8k+J%&k-(muroO5uant3$g0FU=!)W[W#)hV?
-k2t?'J`_OGWoaNOs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\u[)<X?<RHX>bHUJ;$IeXJInXQ<8Z]2lqCCXK8:f9rY4n;OI?_'Ve*uV5^O`V6$bm
-X>d&YQqsfbT;7%>JZQ#U#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%S?%g.^3og.%O*U8V2>g<iFE^2Ka47G=>hg=jum@b08aBYjT"'[Kk7dFR#OdG!=!
-g-sKE_.D?Sb0Y^nJ_I9\#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&k25k"t2:k";DLX0Q$ak1r\ma`XYV8`ln3k2tOGBAr"4DTr"?'\ZgSh;[R#gudbO
-k"4Imb\H;&e_>Z;J`a,t#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g]<!38,(qV)/;o`p?smiM<+&cTXIE6u<?R='D.$aRPCd%I?%2XO&#WB7=.$(X=(#EL
-X;tGO=8o9%,?9;rJZQ#U#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]@nI6.]5D033^#6H?tJ!C3jeQg;RrUCFHRDML'Sf];9UqFeJTb&(G??DSb&EDL-V]
-g*L`bDuSGk/8TmkJ_I9\#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]B1<L/[.II41W=RJUs!CE.N-gk0S4$E@S]bP(A1-`NFQ=I&Zu)&)V>WFj&pmFFf"$
-jsPD)FoLM(/olO*J`a,t#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g]<!0HLma9lNL[)9Lkr.6Sqr@qXK7hGS;Wu?XGD[uXK7J=Nqf[WSVW[4X::SRLoII<
-P_c$7XD]VXJZOF(Y,hi=map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]@nFJXMV?_ZGtV4XK:.0aK2^Ng=jEF`j!P<g8qBig=j!:[.r>VaK32Vg'tm"XOl0"
-]<'92g5Ir-J_G\/Y1a*>s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]B19a[EQA1][5f_[C,/Ze$Zkqk2sprdCRfhk-_V<k2sIe^A-gle$[BujpfPB[Gp=F
-`jOI]k*.mNJ`_OGY3#rSs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gYH.l+=]ndmn#QMWr)j#Cp8e=?+'SWE!JHnmXF[ITX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-#$LBV\D!1KYM'-1E,][1n(IcYr,;Y%p=]S8-Z]1>!N3hdg4@t[g'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YYN>uIGB\,Pn)aVpr-&.4p>uFM.<tgR!O9q$k(2Zsjp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gYH.i,O,oh!X8o-qNrYUAX9+iOOFaKaXJ`-(]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KYM'*3[^O0Cg&TS![K+5=g&f1#[Xm.`g8EX/ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YYN>rJ^qe=bjoF68^];XQjoWiD^k(X!k,7>Gli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gQ)k+1D60gTr_W`bXC2$)"f8<%X&5&VX8nUd;$Cm>XD:\!JZOF(\uZ+Imap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1KQ.cA)MqZmArau;Lg3N[1"ju&XfOqbkg&SneB*F7Jg4s=TJ_G\/]%RAJs5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1YQ0&4=P31ngrbMY\k(*GI"l8>'jD;a1joEO&C^$'ck)X?#J`_OG]&j4_s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z?*KG@R_U4Y/]XP4YgU9)>V+V1khKKOm6HXAkOQ</@VQQ^9t0XK5!$HMX]PNG+ZF
-403OEQWf`WR>ld!JZQSe#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\_7@?Q[RTA9fPg?\b+SU?2E7ldAbXLVgqFog1nC;C9?3&^V<Xgg=fhYS,1hJZ@p!-
-9A5Sl^N.*C_6\^HJ_Iil#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\`O3RTS2Ii;*.TN_t<'kA,>=)h6Pu$Y_Q$:k&AJcE44nGb0!`7k2p-(U\a*^]SjqT
-:Ze18b';(kbe/MhJ`a]/#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z?ZQE*03CJ7u$c4KO9/8X?HI8Y:*7XH"2j:Aq7!Hqn1HXB:QHrN$'p<Ls,j#F/Dh
-XGpG%HM=KLDL/C$H`WW2XG:+RU4KCsXMCnA]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\_7pCNc<_+UP%:S9\QLP?,#%2?-8@[g9_u.A,Y*dSn!2og2OJorRq=uCWHG.#JG')
-g9PgYS+kVFMji@WSD(hjg8fF'c%4T"g;)DHir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\`OcUQ?MEQXGc6';!,)n@`dcY@b%!&k.W$KB`7&uVJ(Y:k'"O:rT417EROjK#KV)G
-k.H#(U\EmZPG@9&V<6$:k-]VHfR`19k.p*`li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\u[6M+=A8%XFOucX?;>KSt9,MW_?cAKn-*\StE*cQqD.fXK7RcX??H_!Lld]X9XGh
-XK6#cDL2&Y%R?toIV4*u:TUXsSjm4hJZOF(_Q3sQmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%SLQ-o!*hg7s;Sg.\YsaiSS8f3iidW1qg3ai`>k^g;i@g=j&Rg._J!!QALGg'=R*
-g=h+SMjsIp%T1d1T7`b;AD5bha]X&CJ_G\/_V,4Rs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k?h.PrU%k,aL'k"rR?eC8`_j(<e0ZE)nUeCE^Db@?Xck2sR&k"u$=!RPHWjp//F
-k2qK&PG@m7%TVKMW/@NYC$+R;e6[gfJ`_OG_WD'gs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZ:3,:at/XFM]c6@h8uX9=heXA`m4X8kB]X9+GTFoJHE8tN+HrN$$-L]+:Z=HKVc
-4KNFHpoFa]>H4d+I;4U7rN$&p>,["RJZQ_i#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RP7/2f$!g7pE%;km%cg'#-'g1c?@g&OhFg&eZgPlBA=?HChorRq9uXSpiXDn"HS
-9\PDopt?"\FP,=$SqjIZrRq<^En,`pJ_Iup#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&jCN00(W4k,^FB=KG?ujoieCk&-4XjoA6VjoW;.SGqXQA(0R:rT4-3[Jf4mFi!5&
-;!*t:puVjrHK=5NViJ9$rT4/oGi=59J`ai3#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZRG=DV!<XFOiYVQ=']XK6_cXAbD_X:IFpWf*s[VfP=NV.i"R'o)^h!'L1\!'L7^
-"$8Ul1&e6TJW]o4!IS_]X:'DlXH@9\S#WQkRWsCbJZQhl#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RhNE/ADag7s/Gdb8lKg=i!Sg1e8!g(-m2f<O&`e<3t#d=k4e)QNej!)3=E!)3CG
-"%u<A55s7:UUU3U!M,)Fg'aI.g:2o3`7N_s_j>r.J_J)s#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j[fG*-h,k,a<ohWB3sk2rG&k&/9=jpt;Nj1=C8i0muDh2G-+*4,Y,!)WUU!)W[W
-"&D`L6N6*JXMXqu!N)"WjpS&Jk/*-Tcf=0McCfaNJ`ar6#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z?HLEETBE3$hk3XK#Pg4Dh0f*]/6CX942>5)K6>#GQ78XK6%MLAn7S4oDA]4oMG`
-W[BS$X8sSIrN$$ID>pU@>Wcf'XH.f-X9!>GJZOF(`N09Tmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\_7^>O)`n-7PAr=g=LLA9T.WA-:47%g&n?K:TaTL#L/@Xg=h0!WrC]P:&N]F:&WcI
-fJ,Vig&WdBrRq:CMZ2<6FA.MEg9mRNg&[9?J_G\/`S(OUs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\`OQPQZqTS8hkbVk2Uhc:m0tb-q:'4jo_qd;n)_f#M>F!k2qOAZi9(e;Z,YW;Z5_Z
-j>94&joI/WrT4-XOoFJIH;K^ck.dkmjoLhTJ`_OG`T@Bjs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZS%9!>gTDXF[IlX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_K;@!?S@og4@tsg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`c.X!?\e%k(2[6jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZS%9!/lE0JZQek#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_K;@!3h%.J_J&r#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`c.X!4maDJ`ao5#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZSmQ!Ml^nX9#&rnZ2_anZ2bgVr"KVP;8k`XF[JNX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-#$LBV\D!1KJ_L.X!RTErg&]IOn_*uen_+#leDAm\\j4Mkg4@uUg'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YJ`d!p!SlZ4joO/rn`Bi'n`Bl.i83St`'`1.k(2[mjp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gJZSmQ!FCW]X8tkbnZ2^QnZ2b+Ibh(+8tLU8JZSdN#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_L.X!I1dGg&YF$n_*t:n_+#!TAA3%?-.ZOJ_L%U#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`d!p!IhQWjoJl@n`BgJn`Bk4W86S:@aotkJ`cmm#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g]<!3(2JP9b6`d.l4E[a+E]deqEN!J34HceIS30&LM4m^-9VD9a,D7ai4Cb:j8o0)A
-PcUZ`4FF6'+YZ$IXHFG\4K5>:4KML8QM[`uAJI=>XK8C:4D:[p5r+-F@AkJ'4HoTB-_*:`SY@iX
-4A2?KXFE?69!"@A4CY4iLceKuSue_k4F=0'0oTg?Tn0;$X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]@nI#7>FKe<SGlG9U+8aOA($uOO\nU9Y&m2`_96^Xit<L@*AH$,H!\b9RYFE?&>CO
-]@tVO9V'n\.QpJDg:/7q9\7l]9\O5C^AHV!J/V+4g=k,59SD!N;Eq-?I+9l/9Y1&R-cShVa3Hl.
-9OGusg7V,W?J<.f9RYCDXA!2%akG*^9Ush\5-fiMb^nK(g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]B1<78WHQ&>3=[k:n6\0Qr&E7Qf*Zr:rMMYcqm`"\(GCkA_-b@,I'P#:k[`g@Zdfi
-`TGs":o3=+/3m%Xk//?8:u^M';<Dg]ant38LE'-Hk2tZa:lOAq=$s8TK&JFF:rN1l-dbdkdb-sP
-:h8/>k,D1!AEM$2:k[`g[SU^<eE5P2:o*7*6+i.gf7E(?jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\u[)1IP$+5XC$gcF*2MHXG/1*SV!rE4KO]HXJdq"<gg%Z<h]Dl'/t-:Kk%3C057M/
-XBCUcDL/BjM>aLV8>,s`"DrLeR8<X[!'L4]%;UBnIqYpL<f^:^XD34ZX=095XJf0c@SNqa>-**f
-XH=Qa=fe]Z@Y86nQmA9)>)o\%H)t@AJ"2.BXGEq^]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S>lT/rcAg3BdSP*D&og8Zs_a/.MD9\R$og=8KVD8P#HD9_t3'1S>BWI<L+4,)CO
-g2XOSMjrFFY5R&T>Kd$""H&`'_IWJr!)3@F%>US0U4h77D7+35g4u<qg*jOKg=C,THt(g:En[(?
-g:/K:ESB-GIAVPK_(Nj`EjXPZRbE$hTuEm[g5+Geir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&k2'W'.7Zk'sl&R[fb:k-Hu.d]V`p;!,];k2A_$F3WjpF4gBP'2"q[Z@qAP5)eWm
-k'+T&PG@8h\GbOj@+P>>"HfPCc"["9!)WXV%?IFLWf6)^F2)bWk)QD8js\/gk2CC&JnO5[Giklb
-k/&O\Gin.pKWg0nbV7Q/GeW=)U?6r1WmIr#k(r.(li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uZ)uX?<RHX<7F(!DkoXX:@@oVIDYM19>_>XK8+\9E)!n;3q*\!'L7^"?`cE9r\,n
-#8fQc3a&OjM>aLV8>,s`"JSAe9:bm[!'L4]!&+=6#skYoLea;<XD34ZX:fb*4?P?R@YUtE>-(Af
-XK7k0GlFcT4B[`HX@f(c)*C#B=KGkRJZOR,#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%R?^g.^3og*lqo!G5%)g($g1dsXn`5MDHag=jca?iJa[B>=>t!)3CG"AIOT@b1P4
-#9QW58o`R0Y5R&T>Kd$""O1*'?cVur!)3@F!'C0R#u]L2X^f-"g4u<qg(Kf.9M@XNI&bo-EnXm@
-g=jH)R/YeM9Q@Jog0MhS+&#@#E8#T'J_Gh3#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j2nk"t2:jsp@,!GbO2jpk5Mhh+a%6ft&-k2t::AcCfmD9;\;!)W[W"An6mBB&pQ
-#9Zi>:3YiL\GbOj@+P>>"P@&CACC;9!)WXV!'gHZ$!69O[V3eFk)QD8jq=@E:f'KdK!a[SGiiPb
-k2ssSU&O0b:j9\:k$lj&+])!1G34:GJ`_[K#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\u[)<X?<RHXC-gbXDi9'XFr"'N`iH.1oup@XK75;=.$(Z<hfJm#<-e,K4V-C>lC`<
->E,_^Ff\o+XDk8B8>*&'XK6G=@ed#=4KOC'XDN<cXDk8+=--C^XD33cE;HX^PZ4`cLm2A'XH$Jc
-Iqc!cE0+2'XFt,<A#u"@Suc.UXJ^3B?]"]^!EY,/XGj4b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S?%g.^3og3TjSg5_A\g8Hd\ZuOfe6JB%eg=iX7DSb&GD9_t3#=as3VL[C+FT'o-
-F0jTLQ.gJcg5an@>Kb`\g=hX"I/)D09\QY\g5;BRg5an#DRXE7g4u<SNr%HU]PH6TXh/t\g9bnS
-TnV4SNj`l[g8BG"IG2IeakCgAg=2A@H*."u!H,&kg5O_iir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&k25k"t2:k(0r&k*DL+k-6f+^3Je67HVR/k2s+cFNimoF4pHQ#>1NKYD;8PHi<(@
-H+i@tS`YC2k*G/l@+OJ+k2r%HKD=RC;!,:+k)uP&k*G/MFhr(Zk)QD&QMT_i`c:/'[`3p+k.Z*&
-WK$'&QG@\+k-0TGK]^E0eE2(ik22]kJ%,@<!Hbi&k)AF,li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g]<!3(06'@%5'j,74?T49F?F(mXJokqE&W<KT0,5DVk['N9VVBb#Wm)iAZ2\&104CU
-'W,(s6(k<S:-=N;XIqmBS?/fj;N1CP'RDlJVQ?e74?S\+68XBL@]ZA*4GN[5-(d:^@%B)CX@tC?
-XF`PsGc[>r4CkClM`aj==KJB(4@,X61H9ITX9+Y%H@`/VX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]@nI#4-*C,:Rfj[9MER]P>$Epg=CpNN^]\ra\5BSe'DT!@F"`'#YU=SJCW@[5]$GR
-'[h%r;p3n@@na5_g<3Gh`nK.sBX7Ee'Uh^?e(WE29MDkJ<'mQHI+lq_9W@jA--8hSH,i3Rg0d1d
-g8%D9R+fGO9RkUHYY8YIE8&`]9N''X5t@+;g&er+Rt9:Pg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]B1<75F,KD;l&<%:f,['Ro"f2k2D4pQ:\.>e5/tmhqDgAB%d%C#Z$mcLZ%<*6ur:h
-']"%2=4ZNfBi)M*k13X2dH9TMDS5c,'VeKRhr`s^:f+ph=@KM[K'(j.:p]u[-.PjhJC6hlk%7!/
-k,hHVU#sTr:kmoj\km3cG37Y-:fl6"6qa!JjoWRCUOhQdjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gXK2GRBBZDs4QNRETguAh!D%0\XGa.a]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KXP*]MK':ng9]Xn.bZ_:*!F1Y9g5FYhir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YXQBPbMWj1&:upa>f3bfF!F_:Fk)8@+li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gYH.l*4?R8Un#QMQq`Fp:4HSa-"bSloOfY&M49/XOX8l)p492;3X9#/uJZOd2#.j6S
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KYM'-/9MC&in(IcQqb.&X9Xa-<"f=p[\D"n!9E95#g&Pa_9E<Pog&]USJ_H%9#3,[>
-g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YYN>uG:f*&/n)aVhqbR>_:r)8V"g:]k_WK2B:]Pk-joB2p:]TD*joO9!J`_mQ#4)<B
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z?$B13K\"O$#FRXF[I(XSJq%]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\_7:45F'sV[S08Dg4@t/gA0G,ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\`O-F6_3B%^edaVk(2ZGk5"-Dli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4T2>^9O`RSJZOF(s/ZF9map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\_7(+ZM`DV9`<ZG@=3X[J_G\/s4R\:s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\`Np=]_pml;#TMWAqPZsJ`_OGs5jOOs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>g9NVojX4T;D`NZWFqXF[I(XT,@+]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\_7(+ZM`DV9`E`IZm_5kg4@t/gAfk2ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\`Np=]_pml;#]SY^+,_*k(2ZGk5XQJli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\Z?$K2Kc+&O$#r3X9!B\JZOF(JZSjP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\_7:@7$ZK[[S0m(g&[@rJ_G\/J_L+W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\`O-S8=eo*^eeD;joLp8J`_OGJ`cso#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z>h%VLbh"XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7)(dXg,'g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Nq?hLXg?k(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uYt,.ZK"\JZOF(o;i/-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%R5026qeeJ_G\/[email protected])Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&j(G34sh)J`_OGoB$8Cs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uYsA;2p..JZOF(o;i/-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%R43B<m*BJ_G\/[email protected])Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&j'FD7kG^J`_OGoB$8Cs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>g9NIe0^XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+Z@U_\g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]Rf3rk(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NIe0^XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+Z@U_\g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]Rf3rk(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NIe0^XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+Z@U_\g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]Rf3rk(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZ!b5$sHOX8tgLJZOF(JZS[K#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%R7]:3a8Ig&YAFJ_G\/J_KqR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j*r;LcR_joJg[J`_OGJ`cdj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZ0gFEEYHXH+6KJZOF(JZS[K#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RFbPEWK0g9i#rJ_G\/J_KqR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j:"S"%:Wk.`(>J`_OGJ`cdj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g[&a:iJUsnRXF[JJX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K[+YPiUOh-Mg4@uQg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y[,qD*XF]Mbk(2[ijp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gVlTlIJZOF(KWGBhmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KVqM-CJ_G\/K\?Xis5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YVrduXJ`_OGK]WL)s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gWN60#BeB.^.AAX[X@k@@TgLqFVM$U:XElO@QTRj@XCa@KAZVt50pQi6G`jdC4>qbA
-XF[I]X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KWS.F)KK8k^.Et.Ng0d1ebZ.>Vd\f3]g7(3e^eA%fg4D^\J(iUm5J<:DRCGFQ9LP\-
-g4@tdg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YWTF9AN'-pu.G7-bk%-s0f32!ph6B2'k+b//b"uR0k(uW"L?@W=6HGZ]Tu0/k:e7^>
-k(2['jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZ+1?!W2dXI/um$*88sEa>09S:<ZrX:/N&K8j*(<MZ^W=faabX9h"jXFaE0XK6Pc
-ri?Kr:9:NZXK4scXE8Q8XF[I]X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%RA6G'9k=g;3c3$/(T7OESRr`h?*$g'i=*VR(?^Cs^nDES=+cg'LI,g8/Pgg=hgS
-rn7au@bTO0g=fcSg67_Og4@tdg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&j4MI!i9_k0*aO$0@_SR!d6BdAg%<jpZfAYJ#5,EnoflGNMa$jp=lHk,r[6k2r5&
-roOU6B]eGRk2p(&k*qikk(2['jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZELMi1T'X@\>.6E?1aG)JulX8kBXX9N*T</Fh6@fEG>4KOTHXDW?cVc%eIWiU>a
-ri?Kr:9:NZXK4sJ9:hi.XF[I]X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%R[>Ycqo[g0Lqe<8"]#Q*=Tog&OhAg'2nfC9;QVI/_h19\Qmog5MKSe7b:rf@lLP
-rn7au@bTO0g=fc4?c^HBg4@tdg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&jNQ]"2n*k$kp5=lmF@T"8G2joA6Qjp$C+E4:,!KDt!D;!,N:k*)S&heo0<j5uo#
-roOU6B]eGRk2p'ZACK.]k(2['jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZF:<E1N5XBnn,NNAsDXK4P`X8kBXX9N*g=`@T"@fEGL4KPJ^N`MUMN%S*UT<*0V
-XJ^?4:9:NZXK4ri+K0jmJZQ8\#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%R\>ChtuAg37@LZeEf+g=f7"g&OhAg'2o)EK5+>I/_h?9\S!5Zu*b8Z8ueSb1`,C
-g=2P/@bTO0g=fbC.Fj"'J_INc#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&jOUEcO.Zk'h>k^#n-Rk2oM>joA6Qjp$CEGF!N\KDt!R;!-\W^2qT^]010ge`NEj
-k22lXB]eGRk2p&f/)c'AJ`aB&#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZE6P)VDbXH/O-7'!.OXK4P`X8kBXX:ersTIO0*?)ap!8$&e7Amh^A8H+bf9<<8W
-XJ/1Q:9:NZXK4scS:#^cWf!U'XF[IaX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%R[#]!=c;g9nN'=4tu#g=f7"g&OhAg(Jb5au+7HG1PBk=k_SoJU,u'>Q22L?eUd-
-g<Ed=@bTO0g=fcS`gr[Sf<<PPg4@thg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&jN4`4S[]k.ejQ>NO[Dk2oM>joA6Qjq<6QeMhceIH'DA?KUC?Lk+XM@/e([AEKGN
-k1O(dB]eGRk2p(&d&*]&j1*ipk(2[+jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZWa:/NWFX<^P9=KH0WPCjg$S5("uV#.5$Ub#->>?e1Z:JOiOri@/'XK6ji:5_jd
-:,Ok'8OfLW:/5T+Q68ao20>pn!/#j(JZQGa#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RmW@qIc>g+HlFE7omk\u-aA`FC*%d/2N)cSo1aF*$'0A7K>`rn8Deg=i2DA$BGe
-@m`Rm?!5Nl@q1;J^+!;s6^-6J!2b>$J_I]h#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j`kBP]hRjtLI^G3+W1`NUV`ctF\<g\^+@gH/p-H$SPQC1qP'roP7uk2rTfBY%k&
-BLbL)@U@f2BP<Fga=C\47[rPl!3^t9J`aQ+#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZLDR[p4FXIP`JVQ?GZVkfcVWW&=dWr&k)Wg]HZWM?PrS!p#KX9P?!XJ;5QVYZ_d
-Trb&YR]3BerL*kdX?TgcJZOF(\uZ+Imap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%RbJ_oL'Dg;UtIdb;j]eBl+Yf)EPef_aA0fYb__f$E((`P]jsg'5aSg<[[Sde^id
-bhCF]_q*PlrPJceg/)b=J_G\/]%RAJs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&jUbcI1Fqk0VE!hWEA6i7uW2ir74'jSS'HjNc08inNVXd*C2?jp'E!k1\,+hYPM&
-f]Lr6cJn!ErQYQ&k#?N^J`_OG]&j4_s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gUT=GgrC-c_f;nt$JZOF(\?#nGmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KUY5]TrE0,3f@g4tJ_G\/\Cq/Hs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YUZMPerE]J=fB*(4J`_OG\E4"]s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gUTFBf!2G+HJZOj4#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KUY>Xj!7$/LJ_H+;#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YUZMR0rR_,'J`_OGNTLH2s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gM6$\gJZOF(U9"R1map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KM:qr[J_G\/U=oh2s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YM<4enJ`_OGU?2[Gs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gM6$\cnuMn./8]s>JZQ5[#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KM:qrVo%F/#3/W:@J_IKb#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YM<4eio&^"64-G0WJ`a?%#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g]<!3(7Wh=B:op^14FsT8IQV@AEN="?4J/^VWB<InNiH#?:TF8m'r*lR3g?_44Ar8^
-Am8YN>A%#P;*:3EX9!]bri?3r4@lIKX:'tIJinNKXIMCIDGl%eJZR+t#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]@nI#=Hm-PB%kmh9VgCrT1k#POP,Ue9Zl)CekAu3[+B"cACp\3(!fQI8\<]l9PE/6
-Joc3_F+S:aB2$,?g&[b$rn7J!9O$-Gg'b/VUeII[g;Q`pN+ddrJ_JB&#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]B1<7?(>GkCZa]7:p&mBW)/LiQfXK/:t=^ji_W^P^>j-.C?,0Q("uJ\9uc><:i>FX
-M0XW%H&6X&D,ACSjoM?AroO=8:gi;[jpSdpX\c$!k0Qq;PAYs6J`b5>#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\u[)/F"2DsXCm*cB7YMHXF;FrRX)!94KOoHXJ[Fl=d?(V=/>_p"?`ceI$Xc5!'L7^
-()hoDK1;:MQE48MXK6ecXK7XcXIrObqlC,h@l\6cO]SWR+HqAXJZR+t#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]%S>iOu8V#g4H-SJu##og7L"O_jT649\R<og=.mHE4suBDUA:7"AIP'T"b3X!)3CG
-(*TXuVHLh`^Y3_8g=i*Sg=j2Sg<49Sqq;BRIRo/d\8L$=.(b&aJ_JB&#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]&k2$RQ-s:k)$5&M63_:k,9urc(X:^;!,u:k2/"jGK8jiFkcfU"An7CVTAc!!)W[W
-(*^(,Y?oL%al[i^k2rP'k2s[&k14P&qrS5bKhRG%_K=qd/&d)%J`b5>#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\uZ)uX?<RHX<7F(!CK!KX:@@oWbad[19>_>XK7hO9E)!n;3q*\"G]*%BW;!4!'L7^
-(-JT\U.1SHXK7=cXK6ecXK67h4?OsMqlC,hWB@7EA;%%c<Ki!8JZR+t#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]%R?^g.^3og*lqo!EDhmg($g1f8**o5MDHag=jEQ?iJa[B>=>t"KP3iK\-4W!)3CG
-(/3=Ubuqtog=icSg=i*[email protected];BRekFdkI](oRCV,/OJ_JB&#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]&j2nk"t2:jsp@,!Er>!jpk5Mj,d)66ft&-k2sq)AcCfmD9;\;"LV'&MrXg!!)W[W
-(/X$ifj;s;k2s7&k2rP'k2qdd:f&s]qrS5bi_\c6KsBe&EQ*LkJ`b5>#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\u[)<X?<RHXBCUcXF4c4XGnd4N`iH92QVpBXK7MF<1U+_<M95j"F[AQ@#4f`!'L7^
-(-JT\U.1S'SZHRTXK6ecXK71cXK7>OqlC8lWB@7EJnD*W0pA]?JU)gJJZR8##.j6SeVDWDqpbql
-KCA!=nCg3Z~>
-#$LBV\D!1K]%S?%g.^3og2OLSg7Etlg9N]lZuOfs7,"tfg=j!ECW>)NCs)Y/"J4?$H*.)"!)3CG
-(/3=UbuqtFaP)BAg=i*Sg=iTRg=idPqq;[email protected]&UR?\eJ_JN*#3,[>g4n&Hqq;:u
-JaVg;nC^*X~>
-#$LBV\^d1Y]&k25k"t2:k'+W'k,4-<k.Ee<^3JeD8ERU2k2sIqEREq!En1'L"K1DEJ@>I>!)W[W
-(/X$ifj;rde)lXhk2rP'k2s(&k2s8(qrSAfi_\c6Y))5k6,i!KXJ1:.J`bAB#4)<BeVDWDqpbql
-KCA!=nCg3Z~>
-#$LBV\^c7g]<!3(,&oM`0m]Qs4?Sb+BKTKTXJK8dALN)1Outj/U74e<8X]FV,""IT>bnHf4<cn`
-Ag2mQK-Yq/8j%[+XD9OB@'$Gf4?QoFr2^Ef,@EuQ6#20:7mW??V`d:rXF[J#X9Q9(f@>Z*nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\D!1K]@nI#/!!,a5F]o:9MDtKKM6GQg<k.=J2<qR\P,\9c,<s_>f-?k,#q<1FjSjX9Iif_
-Jh*cNVCnQ9?;.-Jg4qjPHJ7)W9MBWVr7V[d/:(HM;M_;G>>i)ee4rklg4@u*g'6R:hV*_4o)%,G
-bCT*H^@9fAJ,~>
-#$LBV\^d1Y]B1<7/XAu!6DW7X:f,'jMbn^fk1tJ_LGl3q_ba0Qf[",*@EnZ2,$If>He[]*:b>Mu
-M(PtbY;*%R@o08hk)M_iJ`c++:f)Ppr8nO%/qI;a=-'X`?rt>0hbmI*k(2[Bjp(/Og!tl,nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\^c7gXK2GZ?Iu7ZRSMnE#+nqgXFW('JZOF(dB!P`map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KXP*]XGh:XM`+%c\#0Lf)g8$m]J_G\/dFnfas5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YXQBPnIb3]_c=l8##1[eEk,go+J`_OGdH1Z!s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gYH.l*4?QrHn#QMQr&asin>l[j.STH8!1WmK!*oE&#?ErYS?/ffT7O(pXO+$Q]'e2#
-LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KYM'-/9MB]Yn(IcQr(I*>nCdqZ2IZ42!6"e/!-S1m#Am.>`nK.nb(88tg<eOXir@lh
-L=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YYN>uG:f)Vsn)aVhr(mBInE'dk3+hdE!71R>!.4V*#BN^MdH9TGeUck6k0W5pli5Yg
-LXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z?$K20H"%O$#m_XF[I(XSJq%]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\_7:?7$ZK[[S0hTg4@t/gA0G,ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\`O-R8"Jf)^ee?gk(2ZGk5"-Dli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4T2>^>A\qmJZOF(s/ZF9map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\_7(+ZM`DV9`<ZGF,GP&J_G\/s4R\:s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\`Np=]_pml;#TMWH'3a@J`_OGs5jOOs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>g9NVojX4T;D`Pp:'qXF[I(XT,@+]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\_7(+ZM`DV9`E`I]e"tjg4@t/gAfk2ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\`Np=]_pml;#]SYa=iU*k(2ZGk5XQJli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\Z?$B13K\"O$#K&X9!-CJZOF(JZSjP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\_7:45F'sV[S0<mg&["QJ_G\/J_L+W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\`O-G6_3B%^edf*joLQkJ`_OGJ`cso#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gXK2H"T_PSnVk0KZXK87unZ2ekSu[FDJZPZK#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KXP*^(bP9creB,h`g=k!,n_+&qak;7!J_HpR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YXQBQ?f(eA4i7-98k2tL[n`Bo4eE)8DJ``cj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gXK2GR-MXYI>"M;LXK5QcnZ2eW+.n+cJZPZK#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KXP*]N0_j?,Ea;t^g=gPSn_+&X-d%"oJ_HpR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YXQBPc1\g);G[b.#k2pm&n`Bno.Fj"3J``cj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g];uR=RB3?RWM#cRQ_gdbUmI`:ri?d%Q`@-aQSk,%XK7nEU9(8ZV3dbPX9k\hTWG5n
-Q^gX>JZOF(UoXd3map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]@mhB_V3SUf#u(U^X:chd(datrn8%'^Y%8g^I,cYg=jNEc.^[^dD*d%g'Q*?bM(\#
-^VsI#J_G\/UtQ%4s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]B0[Yc0"!-imuN-b1u.AgWJ)DroOm=b2h^@a[XG'k2t$qf]M,7gre+FjpBebf&l,R
-b0XSIJ`_OGUuhmIs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g]<!iC-`ijdP^+?N;-0iu=&DsIXK7"O;/`Ot;&iGUXK5q^O0"]n;,L;SXJf2t<L^(%
-;,\g6JZOF(UoXd3map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]@o*@1>9c(]UC3aB5cJSDJ*cCg=iB:B8tWSB-_,Sg=h$6[G&DIB4l"hg=:(RCrP+[
-B500DJ_G\/UtQ%4s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]B1rU2!34D`hFo&Cj"k!FDPtWk2rgaCmF/!CaNtgk2qCX^ZN]lCi"(,k2:>tEmWs*
-Ci;,[J`_OGUuhmIs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZc3XK5BcX>HTO4f_AHXIhAOPY$do??N?N4T)8p=c]Yc8rB]nENDl_O+B]3JZP\1
-T7O(pXJDp%]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S#qg=g;Sg-Ws9:"a'og;u_9]3VYLGEgh89`3TYEOFNS?E`(KOP408[\QrVUY=*g
-b(88tg8*F,ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jl,k2pX&k!dh_;<;Q;k0uo``aZNpI@TH^;#KGiGJE;&A%:ZmR-&%Z^o^guXQJ;7
-eUck6k+q,Dli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uZ9%XK5BcX?<Sc4f^^EX91SdN\:<6",j7^4T)8f=c]Yc8tN,-END/!=U&D=OK>NT
-T7O(pXJDp%]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%RNcg=g;Sg.^5S:"`5>g&k%&Zo\2*"0pS69`3TOEOFNS?HCidOP32'E!Cf1[bBG?
-b(88tg8*F,ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jAsk2pX&k"t4&;<:XRjo\HB^-;O?"1mXW;#KG_GJE;&A(0S3R-%$?G6WeF_<0lg
-eUck6k+q,Dli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uZfGLjL.jQnP&)0U%l,Lh@ftW+LL7FF^'?08]\0)377,S"r*"XC#/4QWf3$>G5/T
-Fr?(:X@Z-;XF[IOX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%S'5XILT.^c]]^4hJOMXF_h:eUjEpPG6:&4Ke\;)7E\/`6_,Vg3@Yl^N-EWFN\X)
-Q6<9_g0J0=g4@tVg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&joG[A>7Jb<OJ-5fLrk[>HEWiJFM@S#b/K5Ig^T)8KRFceD4%k'qX<b'CD&HIm>J
-Sg(T)k$htSk(2Znjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZgF?u:U:JmaV(@!\o8@"E<NXK6/EFKCa8?tB8<)/rtkLmqdpXCG\?XH$[rS?/;i
-Ee&;6N>m7rXF[IOX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%S(JHA\\^UjBD]HCNWrHD?P"g=h=.PM3]rH@GkI)39)iXi5UNg4"D&g9c0P`nJL[
-OJA&oZQbrkg4@tVg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&jpbJW[7(Xb"4-JYVABJZP3Ck2q\TS*%bBJVF*c)4#i)[a0Mpk(J?Kk.Q=sdH8o/
-R&lh?]d0G*k(2Znjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gKrb<-GCciHXJ`-(]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KL"ZR)Q\!kAg8EX/ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YL#rE?T7Q-Uk,7>Gli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gXK2GgJ,$)MRWs(LXK7V\nZ2neGc7^6Rt7YlXJ`-(]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KXP*]hU%m=H_jQq7g=j-an_+/iRFU$1`.?Wng8EX/ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YXQBQ)Wqb]]cCpr]k2sY:n`C#+U#G.\c[k50k,7>Gli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gXK2Gc0DMUR:2b'@XK5QcnZ2nc0;#>6:P#TuXJ`-(]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KXP*]c48@M7@uZJfg=gPSn_+/f4NcBpA:`Hcg8EX/ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YXQBQ$55=7FBpFt2k2pm&n`C#(5Lno?C4YMuk,7>Gli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g];uR-Gc[WZUl0bZEL3c.Q#V[Dri?cYEMon,E@5a^XK6hhU9'u,QZ7ZWX:1>5Mla"R
-EILKOXK4O8XF[INX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]@mh-R+fiHd'07HO2'E&]oT?jrn8$RO42h#O"uctg=i0[c.^:#^lPAlg'kWTYhIgT
-O.]b#g=f5Og4@tUg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]B0[CT]XpogUaGoQceIQa-X>5roOlfQf$rNQSk,<k2rV.f]L\Mb*T=2jp]7r]&r/,
-Q`4EDk2oKkk(2Zmjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g]<!uX0W_$1P`?YiG>,'4;g2OmXK-5WG?h,;G:IfqXK7";O0#!17sAEpXJ/[<?')$f
-GA8"fXK4[cJZOF(W2p37map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]@o6Y4ke4R]X8o.QXSRnBpX#qg=V@DQZ^p"QSk,7g=iAu[G&ei>*jZ8g<FB!G.6%A
-Q\HX*g=fHSJ_G\/W7hI8s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]B2)o5j$cp`kNaKT4[3=DkDG2k2_blT7#YFT/`ITk2rgE^ZO*8?_<"Uk1FXFI)4cb
-T8b&Fk2o_&J`_OGW9+<Ms4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZ9%XK5BcX?<Sc4f^^EX9q(kN]1Zd:2-f24T)8f=c]Yc8tN,-END/!BaQIpOK>NT
-T<,,DBn<@:XJi3)]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%RNcg=g;Sg.^5S:"`5>g'UO-Zpf\&@tiXj9`3TOEOFNS?HCidOP35(KaKkZ[bBG?
-b1bRCKn7s/g8N^0ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jAsk2pX&k"t4&;<:XRjpFrI^.F<DBT2*9;#KG_GJE;&A(0S3R-%'@N=%jm_<0lg
-e`Q"oN.L,Bk,@DHli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uZc3XK#!ZX?<Sc4f_#HXJS"ZO[4DFH^1\64T)8s=c]Yc8tN,-ENDKMIt)iQM6*[C
-T<,+Vr2]plV1G_!XKJW/]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S#qg=KcGg.^5S:"`Uog<rOG\5SumS@mS09`3T\EOFNS?HCidOP3["TqS$%XkM?*
-b1bQCr7V1pd=L#&g90-6ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jl,k2U'nk"t4&;<;':k2&eo_H3Y7UrVW[;#KGlGJE;&A(0S3R-%PCWMu_D\)u[Q
-e`Q!jr8n%2gk"U=k-!hNli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uZf[@U:<jJg-5@,($7e@TXY)XEe,]>_\MP,%^bT(i_<.M45u4X@>LWVc7,7?*%CB
->T[mcX??E^!@(TqXF[IUX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%S'OI!72lV(8pe/=Y1)HuC=1g7!86FK3$$.tIWQ(m%!qXi3/Ug0%>-e7sAYG1q1g
-FXW4&g._Fu!A&&<g4@t\g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&jobJpf>,Xt@B//u7HFJorHHk+[<VHF(\E/r0Gg(mm^-\'R*tk$;'Nhf+1!I-,p1
-HRb9Bk"u!<!A8DDk(2Ztjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZgJL5hU]Q\M')L6J^0L6msgXK7>7OK>.1L5>i1(lj?*R\Y\"XGDY5XIY*#Uo^DI
-O-Yp0V*k3_!cKQVJZOF(Y,hi=map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S(PWj9IJ^T,>uWk7!+WkYsXg=ig3\(]$*WiZ3R(pp<C_p>?lg8q@/g;g4nd+ZmI
-[D'-(d8g/!!f](SJ_G\/Y1a*>s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&jph[(OVsb-]UK[)M1V[)p),k2s7^_<0@V['otr(r!AacJ,_Bk-_SYk0gWDgudG"
-^WF=Sh-0d>!gPaiJ`_OGY3#rSs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gKrb<9Nr?$[K:7@mJZPuT#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KL"ZR9[/J\ZVo+)>J_I6[#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YL#rEO^A[0pYg.g^J`a)s#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gpoFI9aK,A^aK,A^JZOF(VlU*6map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1Kpt>_0aP$WUaP$WUJ_G\/VqM@7s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YpuVRDaQ<JiaQ<JiJ`_OGVre3Ls4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gq5aU@EW3$?QXB`n"BIN/4!i[`!)!-i!*&Qk"C3<94F?\$!`UY5poFL8LA7hNE#+#+
-JZPcN#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1Kq:Yk9O8di6^j5q5"Dp[^8h\uR!+,QV!,M2["ElFl9Ut_.!bsU(pt>b/Wqb9KNZ<W(
-J_I$U#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Yq;q^MQi?+Jb(0KR"ER6k:,1Pd!+buh!-.Vm"FMq#:o*^F!cU-;puVUC[.rbaQ6(V>
-J``lm#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gq5aU8H2alGPZ7X`/4lI"V`_%nEhZ3oXI2^SK<0!+CJ0bjXFNr:?EC5L91u:dXJJQj
-J!t^&94Rt&!DH8fX:Lss97<mb@rY/!XJJ:cX??K`#?OQnXA=^H:]7@'=c]YM94b2"9<>4-JbZ;I
-HTZk\JZPcN#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1Kq:Yk/RJtn@]P@H"/6p=rdnJJJOj.7Lg;@9)VqR,cLL7OEg7hq]GM:c5?XMI>g<j8E
-Tu3?C?[_q-!FTF:g(2A6?_5u:IZRp>g<imRg._M"#B*tqg17BoAGt3jEOFN8?\$j?@+s=eU\NOD
-S4nLfJ_I$U#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Yq;q^BUAj9U`c1q>/7I(1hb`HmRFu,pk07FIYi_11O(?)hk,W$'IHK[[A7Xc`k1sQh
-Wm.=aA;'sE!G,sDjq$$RA>eR\KpZD\k1s2&k"u'>#BaS3k%VA:CAm9'GJE:^A;B;]A`i-4XSCoY
-V,2a*J``lm#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gq5aU+LAn7TRVVo(/>K73VkU8[1KL&SXC.Ti8ti!rI@W[*Ro#ZH=0.O,SXi3NRoQ#B
-+H*$SSY?%a0V(/(XI3.\SSN_N*d4)?X//1bR89o[>`bLWRVjLDR9#u^XBCUcWC)oOD.p#PH&VL!
-!'Gh6JZPcN#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1Kq:YjsWrC]Q`/+EH/C3!Je'?[`6#FYgg3Uf[?Hg\8T>sma`+@!0DVDUca2_<9`GET*
-.C%5ga3=P:0ZQZ:g;7aJa,$G9-C2\Ng!NdQ_.D?IFgoD.`/?Ck_JRKMg2XOSelBB:MM0^;R^2\A
-!).stJ_I$U#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Yq;q^1[/T1gcB%te/DK8fhq@/97<?n-k((n.A(TEVVp\Z/cYLtWFQUH2daDF`cZ7IO
-/%aS.db"K\0[`SUk0.qqdZ:E_.%\jgjkX)%b\H:qHbn-OcBC*5b]D@tk'+T&i`a@aOc/AaU:^0^
-!)S7/J``lm#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gq5aU%NVBLY6)UfcU+;`4X<*`r6QDc#4KPVHXJK#d6_(6ZDF6cPXDE9cXGrjR4Su2_
-4KPVoL&S.u4KLZHX?EV\)FIGoXH"Mm6S`A#E3--SJ?5hTO0#F;@]WLno;hpSJZOF(VlU*6map!E
-e+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KqUu#(FL(Yp##j")g<DOprn8F0<E19eg.^5S9\Rm4<E7&mg5K$38_Sukg=imUg._Ct
-"AIP'IB!5",>?fbg=f9Sd32M)a4dmO<E28;Q]BeRKVI2SEOFNSWI3E6^%9qX9S(oKg8EX/ir@lh
-L=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YqW7k@HG'"7#$9^Ek1McAroP9F>$<6'k"t4&;!-PU>$B>9k*&tP:?IY8k2s>,k"ts;
-"An7CKX1U>,>dN!k2oP&h'6*BdcS7s>$=7OTU+a&MlZ"&GJE;&Z\.CYa7JEn:k@b[k,7>Gli5Yg
-LXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gq5aU8H2"BD6)UfcU.5*_+[;fj0;,C/XK4OcVMq@J5HKNKV1Uk2Iqc!cPbP6AXIkjY
-X<]p0XEe`cXH?Sc4KPVIX//(XG]BgO<1]qQQ$?'*Wa1UcXBCV`X9)4B>kkB$OG!M5!'L1\!J6Gb
-XF[IUX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1Kq:Yk/RJ5D=;q'ISbujqu+]-S&43Q>Og=f6Se$@BK:thjtdAKXkTnM.R]?T&'g<%,/
-g*BAGg7!uSg:2%S9\S2pg!N[EQ]Kk9C<4f;]U*-^f64LSg2XP"g&blQFnjYk[\s)X!)3=E!N!;W
-g4@t\g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Yq;q^BUA*dR=5W0&fj4R=+][=A5M"snk2oM&hRhRu<T^Q@gosT:Wf6*&`S'BMk1.WR
-js3dck+\+&k/)6&;!-n;jkWqlTU4faE7<Uba.R,.j*\Q&k'+T>joT=kHhc_(^p*e"!)WUU!Ns:j
-k(2Ztjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gq5aU8H2+HG6l.n=XB?E2riAn74@h,,Aeg)R'l'-V4?R_eSl.[V(5T&?4?QT:XDU-l
-PcUrL'g.MXGW\)iUhpirM\T]+(QPS@ENG-e4A(l`8N]1mXK5AC13]h$S1CK3X8u-Gri?2d'g.HS
-X8sPGJZOF(Y,hi=map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1Kq:Yk/RJ>J@<ujo5g2S3<rn:/.9O'\tJK(Ye)hu3S9MCZ(aCe1i*3@kd9MB6Gg5J^1
-]\;(7)bdTlQqU1kd#/j:YT%t4*jjXfOP7$@9O5>u>te%qg=g9i5F:*X`])?@g&Ye@rn7HN)bdO9
-g&Wa@J_G\/Y1a*>s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Yq;q^BUA3jU>9?VIk'%tUroR"B:glS1L`Eh+*0/8i:f*\Edqqp0*k(40:f)/`k*/\O
-`ocD]*)O?2TMSI,gQEPV\K-<L+26m0Qfbta:h%J<@Sg"3k2pV46_EN'd5p.ZjoK6TroO;_*)O9H
-joI)TJ`_OGY3#rSs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gq5aUMA$)g5G]<AX!IeeYX9+>'TD5Jg?9s.DJZPuT#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1Kq:YkJI]_<)Q]Cdn!MG2Bg&eQ/anXQjGZ'+HJ_I6[#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Yq;q^_KrsJ<TU,<6!ND+SjoW.FeG//,ITD$^J`a)s#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gpoFIQXfMRY.V&7T")KS<W;3LqU6PDR!L9C1XF[ITX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-#$LBV\D!1Kpt>_OXkEh?21G>S",T&pebRo"cF`i)!PH[.g4@t[g'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YpuVReXl][N3/%(h"->](iVDU:fuEdK!QWiDk(2Zsjp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZSIE!L[BlX<aa7U9'lUXK%e\Uo^>]VQ?M^Vl#uZXK8%aS>E<gSXcdTS>`:_S,fR?
-XF[J=X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_K_L!Q09[g*G1fc.U+Xg=XEbd+Zgcdb;sceC)@_g=j]h`mNMoa2ZiW`mrK8`W4VA
-g4@uDg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`cRd!R65ljs8m4f]CN0k2aq;gud><hWEM=hqlc7k2t4AdG<sIda@40dGWjZd/`3X
-k(2[\jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZSLF!g$,Hq5c$,*''uO5-/]s9NIj2)MP81)NKSB8Z]"!,sd*`X?&);Af[(e)GEgM
-Q@Z,gXQuql]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_KbM!k2TAq:[:,,=pEK:>1\8?u=,R+fX1S+ge:P?/""U/lSS"g.=K^JL.n(+^e\1
-^4G!hg?[Gsir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`cUe!l8JUq;s-B,u!;_;Wa6UATQLr,I6Hq,JCKj@clg#0itL>k"S/'M'p6E,@tF?
-aFWK)k3M.6li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gKrbr54?S"mWbjj\6EEOd69L^<SsDnAX;O65JSTXSFf_[4:96mZXIW"cXAN8_XK5?b
-ri?KPDlfd&XK4OcSR._8XF[J=X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KL"[3/9MD&3f8<6q<8(?'<(t3`ahM$Sg)3_:UPPM)PhOj.A(k&1g;dRSg1GN7g=g;S
-rn7aJNS;c[g=f6Sa*>FOg4@uDg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YL#s&C:f+%Oj,m/7=lrnE=A[<*eB)(mjr%-QXH9<JSEAtYC$&^Sk0df&k%oIZk2pX'
-roOT^Q0-n*k2oM&dXKDkk(2[\jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gKrbr.XK4OcRSKrcEiamJVQ;n]XJ&/ZX9LnJ=_iCqK`8%`4KO*HX?NYcN*M*HXK5?b
-ri?ENDlfd&XK4-Z/V1!SXQcej]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KL"[3&g=f6S`+%HSOkQ]sdb7CKg<<aqg'1BYEJU38VuGB\9\Q:og.p;SZ?3*og=g;S
-rn7[HNS;c[g=e`13J#n8g?I;qir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YL#s&:k2oM&c=lA&RHC_>hW@Ysk1<u8jp"esGEA\UZ2Wkr;!+m:k#1:&]R-u;k2pX'
-roON\Q0-n*k2o!S4b;aHk3;"4li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gKrbr04?ORaWG4OXL9-#<XK4OcXJ&/ZX9Lng:KW!TK`8%o4KPAPH=j7Z@l-;(S?,YR
-XG:kADlfd&XK4CB9:Vr3XF[J=X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KL"[3(9M?\beqQjlWnOA#g=f6Sg<<aqg'1C)A8n,hVuGBk9\Rm$Rt9;HI6pUn`S,(>
-g8pI*NS;c[g=f')?cLWIg4@uDg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YL#s&<:f&J#if-c2[-"TIk2oM&k1<u8jp"fEC3HJ.Z2Wl,;!-PDUP\-pKLSd+d,o;f
-k-^YOQ0-n*k2o=OAC0:dk(2[\jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gKrbqMXG\:(UO'#C4KO0GXK4OcXJ&/ZX=QT8VZ;+%?EC5WC94L`<KF5Y6EI8T;63]\
-XFOu/Dlfd&XK4OcXAY@cPYnB1XF[JAX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KL"[26g9<*]cC<PA9\QCog=f6Sg<<aqg+6(Oe,Z)DGM:cDL>(@PCUMmF;qfs?BA.+5
-g7j7gNS;c[g=f6Sg1\4S]P#cGg4@uHg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YL#s%Fk.3/,fq[]l;!,!:k2oM&k1<u8jt'KkhuKXaIcfdkNooK#EPLYm=Q\bgD!#]W
-k,XE6Q0-n*k2oM&k&/9&`bj[ck(2[`jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gKrbu74C(KlShN8hNN>K'Uh267K/tYVqQ('`/n(etLTHV#4DLkpX<(BCXBmPKHoWoD
-0f_?SGG\V-5bG-)/j)6NS#g3<VLbh"XRE4p]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KL"[619QjZqaZW<kZJ&;Ed"+6YVFisTqUu=^4*oS;X4k'W9SV-tg)b(ag3>\\SOl"=
-5"J@9QdTtL;9@O^3_W42`7fb`dt-5(g@*`"ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YL#s)F:jc]2e3Hi,]]NBcgk\,$Y>.;iqW80t5(VgX[H>>&:laQ7jrSR*k'fL!VG0?Q
-5tk*HTA=ij<Rp6.4]"s@cfU$*hgsp@k3qF:li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQSe!@a(\XF[J@X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_Iil!Ah08g4@uGg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`a]/!B.`Ek(2[_jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZS=A!1WmK!*n-W!2G+HJZS7?#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_KSH!6"e/!-QoI!7-5MJ_KMF#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`cF`!71R>!.3>[!8<"dJ`c@^#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gKWG6U@>sfZ!/^TS!E#<XX8n:[Fo[s%X9+6%S,KDh?'"?R!^Af*ri?0s>+5Gl!/^ZU
-!etljpoFIPqlBc_o;hqBrcS:>o;i"?G,b8<!Ka./XO=0S]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KK\?L\Ha31r!3Z4Q!GB@Cg&SMZQ2neng&eFC`VnKkG.$\j!`2Rprn7G#El7n1!3Z:S
-!ihR.pt>_Nqq;$Io@a2>rg!Q5o@a89QIkoc!OgC,g="[Zir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YK]W?tK"LX:!4Vjf!H$0TjoE-pScI"+joW#`d/E)-I)#%1!`W"-roO:;Gg?<N!4Vph
-!jeKJpuVRcqrRlYoB$%Srgj,IoB$+NT&]V.!PmNBk0iArli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gKWG3S55qY_X8T.!Ws#N)40,F]X9,G\VZ*[rWrT7!Wsl(g-us?'X/rD'X/rE$X8]1%
-L.caiX9,G`UA_1nX8]4"X8&ar4T)8]PZ7U_!'L4]!eNdjrN-"!"K\XcX/l6$!NUqQXT#7#XSo4"
-X9<9!EcPFaXT,@$XSo4!X93YuUoaQr#-=l+XK5<cJZR;$#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KK\?IY:]B&Lg"=sUgAfh)f`Fh!f`'S+fW`g'gAfeAg"P-3g">!3YqhE&A(]Mhg">$4
-f\+p0rn7FR?C1ZF!nk!+rRq;)g&B_)f_F/#9`3TF]5.B!!)3@F!i8nmrRqM/g"G*49A%qsg&]j)
-rS%;(!SQ3+fa$0`g4r7]OELQVs4IA*"5);Zf`'S6QT<FHg">!3f\"p3BYK&Odb4obs5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1YK]W<q;uYn\jlGM$k5XNAjT86=jSn9CjLO.Hk5XKYjlY[cjlGOc]/>tCC#nF=jlGRd
-jQ5I`roO9gA=rk`!p%,KroO:DjQ6C'roEk:!)WUU!QB'WjoA6VjoV\hXo7D^j9=Z-j\Ot!roO7B
-Z2Nhbj8nB)roFCGk2q[uR$`7"k5XNBjoa]+jQ-=&%A,c;k2k[ck2bUck&/7kk0iArli5YgLXYej
-eHa-In)qLUg-U;~>
-#$LBV\^c7gKWGie5-1i_=?SfgXK74D4\BgK'g5.fX<:7XR]NTE5!;`3IN)BP<hl`YXK4UcXHcFA
-CTL#d6p5kqX9!<bri?0%+HHH&$"lCpQ`P["4X,[WX8kB\X9"PbrN#u]rN$'p7Qg[O%<"C$/tlkl
-4_CdsTKO\%X;bk:4^G*q.SDp>XH6PcX?<ScKg%_UUE`Su7ZRJL$q-nmL)"Br,<i31;O2m8d]<Ya
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KK\@*k:YOONE)'/jg=iZ,:0j'\)bs]<g)slM_qNhD:JPK?T-A2KDU7$1g=f<Sg:Ucf
-LtZ$'<_f+_g&[8$rn7Ei.CB*.$%ku]^Y5AV:+WLBg&OhEg&\g$rRq6FrRq=t=\ShK%?+%f3m<0p
-:4h3Rb"a\jg)G`@:3P<82.'+6g:)"Sg.^5SW(p0hcRi^'=LA(]$s(a/WZ-W:/5P!RBYK&Odb4ob
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YK]Ws.;s*6!G#D5+k2s*R;IZ-!*E$AGjre=`cK=8p;c7DWW$HL`FP>kRk2oS&k/V"1
-O60eC>>h6qjoLg@roO9&/&)#F$&VVmb3#^%;D,BQjoA6UjoNG@rT4)VrT416?;UX`%?sb"4kGN2
-;MjPuel"@(jr97W;LISU3+PpIk.u3&k"t4&Yu=W.g+R5>?,$=#$sVKKZQ5"X/lUopDTICkdcLc"
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gKWGbpL9.JSN2*./XH-VcXB'PH4Su3*:7A8@@&pAs:TQI:XAtIc3hqC=X/JXUUNC=5
-5,G>sI&sDhGQ"TQ>)o\cB6^288?>+PUQM8GX8kB\X8uLarN$!WrN$E1Km%44E-SIW32*E9qlDG5
-XK6/cXK7@cV_4RB4KOWCUM>=\Lg$OH=c6a"XJ8dcXK4gcXK4^bX'gdcXHB?1XO=0S]'e2#LXYej
-eHa-In)qLUg-U;~>
-#$LBV\D!1KK\@#cWnQ1UZ-LWeg9u.Tg23/09`*NhA&I$'H.gogAD0G]g2"=S8^=8`g!sEBcBF*n
-:XRmQS_DeYQi5VJEjXQSK:'rr>hW-%cF;$ng&OhEg&Z9$rRq7UrRq["W0W1lNgSPD7a0R[qq<\s
-g=h:Sg=ifSe2k\)9\QsicA&(IX`D_2E3Xh@g<XTSg=fTSg=fKSfm9dSg:5R^g="[Zir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-#$LBV\^d1YK]Wl!Zf^E-]@tt6k.l?&k&[0W;#BB#B[5bMJE>q<C?A((k&JB&:"lk+jl'^jg7+2>
-;r-StVWR$-TDdm^GeW>&MP8bC@HLYFg;2G;joA6UjoKb@rT4*krT4N5ZC['<Q(d?k9%`9&qrTP.
-k2qZ&k2s:&h`]HN;!,T4g5W/q[X$QXG.N?]k1an&k2on&k2ob&jajo'k/6#+k0iArli5YgLXYej
-eHa-In)qLUg-U;~>
-#$LBV\^c7gKWGQ]5-1i^=@GY0XFk']X8kB[X9;:eXF"g`X:@@o4KPVaPH5rs:QqlW)ZE/4FcT\,
-XFOucXDrI_X9DdfXK5&Zr^@!lVaX$RSb]>e4T)8]PZ7I[#EqqP79#j[Oo29\4Su2_4KPVZRf9Au
-4JtKHX?<SG,=P_2XEcAr71bPiKrh@SQ)q&TUo^Yo6_-l$XNdgN]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KK\?gc:YOOMDc^"!g8BGug&OhDg&tp'g7+!!g($g19\S39]@nc:A@pRE+oYOMQ*tYc
-g7j8Sg5hU!g(&/1g=fn1='&MXe5o^da8+Eh9`3TF]5.5r#J+GI=)5oq\GY%\9`*NH9\S31_uA@"
-9[ltog.^50/QZl<g6t##<tMihWS6'?]\;(?d+[4$<QAHtg<J=Uir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YK]W[&;s*5uF^/05k-0U<joA6TjofACk+n1>jpk5M;!-n[`TAdXC;o>l,Q:pTS\TF2
-k,XF&k*M_=jplXMk2p2R>[1Rsi*9N+deW#*;#KGV`Gt_9#K1=]>]J88_YiNr;#BAX;!-nRcMlr9
-:u>@:k"t3V03iYUk+Xs:>S+`)ZKC:fa6)MggZIYR>1-r4k0<#mli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gKWJ+P5-1iU:Rc/JUnV"WRs^!m7[oNYXK8!_Ml!(HR[\M@V)G*J9SfH%V4Ub\X(HsQ
-OE$='Ngj(=XJ'6BU9(Gg;1PIDPZsWH?*%+sRpM#SXCt0'X8kB\X9"Pbq5cbiDk`k(J!X<-Rq&:r
-6(<+XXK%aJS#V]VS"!cFS3*XF2PYt%Wg$_aT2h>LGE-,nRu:XNXIVM=VQ?e02jF*=!E`KUXOsTY
-]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KK\BAV:YOOBAAsB\d*6OC`La-a=N.e0g=jVNYgLU0_o7t'd7)C5@BIgDdE67JfRfp<
-[Z@jE[)Hn#g<>,(c.^mnB;3c,]5ts1G1plR`H\W@g4W]/g&OhEg&\g$q:\#\N6TL]TtbTd`I?4g
-;oP-0g=XA5`RhbC`Pm)/`_+b.7F.rDf=Z1Pb%nr7QF)'4`NXX:g;ct$e(WH*7_AHL!H2q.g=Y*`
-ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YK]Z4n;s*5iC=&&!gt6ejd&+55?-pHRk2t-!]%tnWc-W,Mh+68ZB"$Dah:6MrjGC"c
-^mDhc^<grIk1GKOf]M>HD6)FR`HfhWIHG\!d!iRgk)3XGjoA6UjoNG@q;skoPhFT-Wl]J3d"U9;
-=4!VQk2al[d,W,kd*R6Ud8&WU8D:@aj2QB#eT&m]T>#tRd(4bak0d/IhWEmT8]CJe!HiR:k1Jf#
-li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gKWG3S55qVnJPCMsJ?5hN9l-o4VG1.kX?9]]9nf[M:/,]/KM?`_9ji0>L9.IoXK6#.
-=KIQd>"tcnXDUa,Eic?N9hg)<XHQ@QMl^Ve9m<\?Sh4(CX8kB\X9"PbqQ(@29hf_?9j=]f9hg;B
-XGoqnXK8,p9cTb+Ptau0XD:OnKM?_u9qJGNL9.IN9l[7DH;.]EX9Va"9oH*SN`u4Z!gFjGJZRM*
-#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KK\?IY:]B&XULB^8U>"=8@>NXkdU@%mg,sFb@Aqo6@ptDOVdZ"6@="8KWS6'ag=h-e
-E8%a>Ead;Jg5KHKOP8E9@:>h_g:C^$YhFe>@@#X$aZ4>=g&OhEg&\g$qUuV8@:>=K@<:/?@:?+g
-g9Y4Jg=jgN@3!AB]jY?Pg5'1JVdZ!<@EI69WS6'8@?9,jRUL@<g';G&@BeJ>ZuYrq!k^"AJ_Jc1
-#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YK]W<q;uYnhXCe>UX6/P_Aru0;hI^m/juds%B!UR]BkE[nY\'WXAq?RdZf^D6k2qM4
-G36S`G\5[lk*'ChR-*O_AnJ%)k/CqE]&nuaAtJ/Ie3%pQjoA6UjoNG@qW8IPAnIKdApNO`AnJ=1
-k.G;lk2t=qAfT:^a(Aqnk)X,lY\'VYB%5t_Zf^C`As_Y5ULnoQjp,p=B"@'d^3KG8!lcdTJ`bVI
-#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gKWG6UD2clD!e3n3k,\WH<2fbs!_YY6ri?1!A"(WC"0,@BTD5JhRp'b*X9!f[JZRJ)
-#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KK\?L\MQtR_!hs)>k1TmHC=N49!aeX*rn7G'IDa:_"5%COb4sZl`H$t5g&[joJ_J`0
-#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YK]W?tOh9$'!ifkVk2l`^E8^]W!b>-=roO:>K[.g("64BhebJ8.cZk`MjoMH6J`bSH
-#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZR8#!b>8CTr\?m<)e>AX9*<>>_0!#X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_JN*!e5!;U"TUrCMTR;g&d7LFFi/ig'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`bAB!et]OU#lI5EH.rPjoUffH\(>'jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOp6!f`/+JZPHE#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_H1=s0;X@J_H^L#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ``$U!kc.gJ``Qd#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOs7"EIaP=H\6:T<&7.map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>"HdeJDn1GQT@sM/s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V"IXR_Fi/dmTB6@Ds4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7"@/oeCj^f8T<&7.map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>"B!_'M4K4OT@sM/s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V"BFFCOemWkTB6@Ds4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7"@/oeCj^f8T<&7.map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>"B!_'M4K4OT@sM/s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V"BFFCOemWkTB6@Ds4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7"@/oeCj^f8T<&7.map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>"B!_'M4K4OT@sM/s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V"BFFCOemWkTB6@Ds4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7"@/oeCj^f8T<&7.map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>"B!_'M4K4OT@sM/s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V"BFFCOemWkTB6@Ds4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7#\%mu?Aknd?QXj#UT=[2map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>#^hi$GHffTGpe0sUY5q3s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V#_SV;I_+\(J16'3UZMdHs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6#BY$CXK8$:Aq@%YX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_H1=#Et:Og=j[uJUuOMg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ``$U#Fh-ik2t2ELk4]`jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOa1!MFF`XJ2d#]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H"8!R$OTg7m:*ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_jP!S3Tgk+^uBli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(rN$!JJZQ#U#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/rRq7EJ_I9\#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGrT4*ZJ`a,t#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(s/Z:&G9-I[-p9&\?87J9;*7OIPVQ=AMD/P<4?BRFFu_?XXK6%gKnV3oU,4hl
-3H'JMi2d-omap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/s4RP-Q6l=[-quSOGWrL]B1u^Z]K^;fY<@<`9M*slQ:O;Wg=h0BWMht5bsFoo
-8<&2Si7\Cps5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGs5jCET-sEr-rDtbIR1^'Cf"]t`^=k1\Nto,:eg*7SkMRmk2qOeZEZ]RfLAM1
-9U(+ji8t70s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6"^kY`XK82r?4!9UEIM5UXJp2%poG?Y13o``VH9+cS5u=WS?/eSXK7F\J?5i4
->5bN04KPVHXK5fcXGpG8XPg/a]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H1="aYE`g=jmPGR;QhOJ$j,g=MBZpt?US5FKr!dVlnS`bit.`nK-?g"NfJU>">.
-ErF]!9\S2og=gkSg9PdNg>LZhir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``$U"b;&uk2tCsIL4W.Q`5GLk2M_(puWHg6_W@=hK@!'d<!rOdH9RgjlX9rX6/QY
-Gl?b3;!-n:k2q6&k.H"kk2>A+li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOs7'4luW@th![MMb8sR2p%"8?/bm4SYu^H#H*B6CpgKX:J6pR89o:AZVqBGtt6<
-N`uC_$9YDk4KPVlFBjlsJZRe2#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_H4>'7m6fI];%3Y-)EO_Bjr>>M%T_9_d<GRZ(:g<68GFg(.o1_.;8sJD/\*R:F_"
-ZuZ-!$;B1-9\S3HPBF:PJ_K&9#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ``'V'8X*,KsKiT\@?@sbpSO]@,pD3;#'/WU6Jm2=O^gZjpuCNb\H:DM!!fQU1iHH
-^3KV=$;fmI;!-nkRsVosJ`bnQ#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOp6&m89pI&q'a=+[NT4KPVKWN<0`poF[FDfTe`SkB!`*E/6)?A_pHXJI+B0o)ij
->-+fIX?<Sc4KPVl6S+:LXP^)`]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H1=&o__WS_Ag9DPZ"?9\S2rf@nqPpt>q@N0''!a^+o"*GN1?GHZ%ng<hEg5-*DE
-En]63g.^5S9\S3H<B.F<g>CTgir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``$U&pJFhV<3e[FKO]f;!-n>io]B"puVdTPaIb=e7/F>*H0!\ICXX:k1hP16F>mh
-Gin.Yk"t4&;!-nk>!'NNk25;*li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOs7'2agP7sqD&Oc`\1X?<Sc5H1`c4SYujH#KHB6D7/NXJSsbXGC:]XK5+pOVUKh
-N`rNc4KLZHX?<Sc@#1G7BWS:qT7O*)X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_H4>'5"Y]=e49Y\@?Cjg.^5S:Y4=S9_d<SRZ,Ng<6Sk"g='iSg9#^5g=g!7\/&<&
-ZuXmS9\N1og.^5SHE>5pKA,%cb(8:-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ``'V'5YG"?DZf'_SU?8k"t4&<9!'&;#'/cU6OA2=P%9Bk211'k-fkWk2p:T_A6PA
-^3Jf&;!(U:k"t4&J[O%AMrs08eUclDjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOs7'm`YO3^9]$:JY#aGoVR$*GqcO*)DptX9q*HX)^P.MGd5ILAn7q7&6oC*)DMh
-*)AjL:JWgK>Ye.$XJ7=1:I/3dX:8oqXQ6Ge]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H4>'q8cG8l45+A7TQ#RNniB,`:2a,@nRcg'UP>fo]7fY@qHZWW(Tm<m]R*,@n&i
-,@j_0A7S$\FC\p)g<V`SA5[L&g(B*kg>prlir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``'V'r,MY:/[email protected]@U*[._-B[;&-#1QujpFsRjdB65\Sc/!Zi9).>MJ;P-#1&,
--#-L?C2-6#HYR;Ck1_srC0,`Djq<]*k2bY/li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOp6s-X@nR]N'JRA-dVRA?^JT<%sZ!3#aq$(@9`X.ZPqSXH#HX9P>uXJM>QV>?Sb
-SuefWRAR'crL!e`XAhWbJZRq6#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_H1=s2#8n_qN/J_Tpl[_U-cKb1Zd2!7^l!$,aX6fur+'a25jpg'5aRg=!jTde^fc
-aP,(Z_UI5krPA]`g1sg<J_K2=#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ``$Us32&/cK<R!bh;.2bhM%!e`HeS!9!_9$-pcWjjrSVd`g,;jp'Duk2"8*h>5>#
-e)oN2bhhLCrQGDuk&F\^J`c%U#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(q5aR"r($gcfW5++VLbi/X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/q:Yghr*'0Mf\-A'dt-65g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGq;q[&r*TN^f]E4<hgsqMjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(q5aRkr1F%jJZQA_#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/q:Yhor6#)nJ_IWf#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGq;q\1r71l0J`aK)#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(rN$!2JZQ#U#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/rRq7&J_I9\#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGrT4*9J`a,t#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(s/Z:%?QJpC-ntk)>oAZe83B>'PT<`)MATg#4<^f-Ftt4?XK6%NKnU=VU*D?S
-10oI4i2d-omap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/s4RP,GU<.=-pImfFs+0)>YJ80]Hh7GY9&,A9IecMQ9Zp8g=h0#WMgkkbq2(P
-5B_V3i7\Cps5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGs5jCDIjb$R-pe*uHm6;E@8L7H`[5Ze\KHR`:b:bkSjP&Kk2qOCZEYL0fIoKd
-6[XIIi8t70s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7'<45YA?2f&4?PZoDcCC4JZPl.4SYuqGtMJA6DIGNXJ8dc:7A8b4fk`7?YcaE
-N`uC_$9YDk4KPVlLoQG?JZRe2#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_H4>'A$#RJ(`Pr9MA'sN,"#>UY=A'9_d<ZRU1<g<6f1"g<ONS@`7!R:>+?pG_b#,
-ZuZ-!$;B1-9\S3HXOsk&J_K&9#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ``'V'B<"fL?7RG:f'p5P]2OWXQJTQ;#'/jU18`1=P@WBk1Oe&B[5c%;W[&@Iu`[R
-^3KV=$;fmI;!-nk[H+uJJ`bnQ#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOs7'54DICj`<HXK6Q7X<E+q5H1`c4SYu^H#HNB6CpgKX:J6pX?<S/E3-$CL/X\F
-N`uC_#s>;j4KPVl<]H.kXP^)`]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H4>'8+ojM4N?og=hh3g+&iN:Y4=S9_d<GRZ(gg<68GFg(.o1g.^4fNnW*+WbKQ.
-ZuZ-!#u'(,9\S3HD+D$cg>CTgir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``'V'8to5Oeq2:k2r5]jt3Xr<9!'&;#'/WU6KH2=O^gZjpuCNk"t36Q0.(PZZ"@U
-^3KV=#uKdH;!-nkE_F3!k25;*li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOs7';[lT-@DnF4?RP^X?<Sc5H1`c4SYu^H#IhA6CpgKX<(<*XDN;YS#i2&4=>`^
-N`rNc>c^&hX?<Sc?suKbVh(r-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_H4>'@BTL0V-pl9MCDtg.^5S:Y4=S9_d<GRZ*Mg<68GFg)at@g5;D0`7i9Z9JN?s
-ZuXmSFP9FBg.^5SH@&`$dt-62g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ``'V'AZS`18X-6:f*D;k"t4&<9!'&;#'/WU6M42=O^gZjrSH]k)lKQcfW\):c,<:
-^3Jf&HKJ&dk"t4&JV%.AhgsqJjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOs7'0rLr5^]Y^XK5EbX?<Sc5H1`c4SYujH#KcB6DRSNXIrUcXHH_!XK4P`X;3q"
-N`rNc4KLZHX?<Sc@#1nD>HFo@Ob'UpX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_H4>'2d<4;4ZF5g=gASg.^5S:Y4=S9_d<SRZ,rg<7#C"g<4<Sg:;3Tg=f7"g(mB9
-ZuXmS9\N1og.^5SHE>i+F5#?'\:NApg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ``'V'34#P<MeiVk2p^&k"t4&<9!'&;#'/cU6Oe2=PIfBk14S&k/2D#k2oM>jq^eU
-^3Jf&;!(U:k"t4&J[OXQHKO@M_L^k1jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOs7"d2#3=ZEM^4:GVpD]sRg,%7H5+ZtqaX9pj;X,KfTRS5h7R/X0.:Sk.H+ZtH@
-+ZqV14?Pj0D`g.$XJ.1#4>^TMTb29qXQ6Ge]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H4>"h@B'EC\a^9FQ3pN%1L*.sfc?.SRDLg'U5.fs,#?`*c8C_>`.0A^T52.SQg8
-.SN2c9MA79N(cp)g<DK@9L=6_bSH:kg>prlir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``'V"iF59GY@2u:^hm2PUrfG/V2nX/5X7\jpFXAjh#3gcXfp\bPpWFC>@sW/5WWK
-/5Seo:f(-RPYb2Ak1DX]:e$3%fGBp+k2bY/li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(afGM7@Y(W@X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/ak?c$I"C#3g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGalWV5K7W1Fjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(q5aQnr&atVfW5+AWI_/2X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/q:Yg\r(I+=f\-ACf7DZ9g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGq;qZnr(mCMf]E4Yj+6@Qjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOp6!dl_6rN$$QFQTY*B9Mhe"e(=>Q=ibNX8o$pM?&t6X9,#OR"qaI]'e2#LXYej
-eHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H1=!hMT,rRq:NPNLR"K=UR,"iIOa^4TYPg&TFtY5l?/g&fF#_2$_Kir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``$U!iA8>rT4-cSEAr7MSo#I"jXX+aGOEgjoF*6\,aYBjoX)CbD53ali5YgLXYej
-eHa-In)qLUg-U;~>
-#$LBV\^c7gJZOp6s)e1?!'KAE!Jd9<X9P1q?<&h`4Q`^KQ6TU?=HW6W!fpGSLTC]kmap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H1=s-*B7!)2M.!NX<5g'5N5GAKV"9]k%4^FaPOE4GPo!jurNLY;sls5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``$Us-rrK!)Ve>!O^DJjp'1RIW@m>;!-mDaY.shG/En6!l&kcLZSg,s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6s)e1?!'L7^)Ke/)+f_W6:HWj&RO=,":7F-nX'Hp0XAp[1riA_64Ae/@Wb4Ft
-UT?nZXJ/as02t&PXJfVk4FX@s;aEO*XIW3NAgN_DHot)lX?ibcD0r@_@Q\"pD_bHXBWJ59TLc/c
-9.-3H+b#KR#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_H1=s-*B7!)3CG)O3ui.bECoA5&?D__JK>@`:_qflemQg2&RSrn9u.9P6rMfRce<
-cIu@Gg<FHf4DRWMg=:XG9VC*:Bi@^3g;df!JM4^jSP3J1g/?GSMOW>LI8"n6NB_DVK\>)5b?N]S
-?S]TZ.A2aU#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ``$Us-rrK!)W[W)P']$/`Z!@C/CPbc8<4\B[B:4jaAbqk&NArroQhB:i&kfjGHcZ
-g?)Yok1F_:5B'Gak2D"j:oWSXDHBZJk0e'BLbZs4VGLmNk#UF&P,.6uKM[0SPsT[kN903aemRY&
-A2MYt/?+]m#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOp6s)e4@!I\_^X;*k!XFI:M;OOV,G-"Y1NLGrSDlfg&ri?Z8NNB4&Ff^oTXCm*c
-NEWDGr2_k)PcR!KV1l"P4KO5tVQ;n\;O=J%9rrYYXIN7d6)U_\R&jbOXGL;c/!$c^BWS;.8?AnT
-=0/JcNiWGrmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H1=s-*E8!M>/Hg(d<8g7d3NBYiDbQ.g"RZGa2?N7u]Zrn7p)ZeF,rPhNl(fn-$R
-ZZFhor7X+a]@os4d\tmR9\QI<e(RLKB>E5Y@G73/g;RgS;Uj?4^tO49g9,\S2mqA6K\G/'>M@f@
-DVEf<NnO]ss5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``$Us-ruL!N;%XjqU_Tk,RP&DTq72S`Xop]["<ePigh)roOc;^#nIGSE@sJjbg2&
-]m8a:r8osp`o^+[h6H,);!,&Yhr[bsD9D"(BBGtQk0S)&<oE%UbN=Jak-oj&3ksgXN999R@-6Ug
-FQV^^NogQ3s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6s)e4@!N/6_X::%L4CkLj(HafAC91Bori?7%5c[5Jri?H2NNB3TS?/fgX>g,@
-!^s+Pr2_,*XK4OcVdDPK.BJ55XK4Oa5-1iT9rqDO4?PNs5rq/`XK4,T49A0W4T;Di4KPWW8?Anm
-<KpFHNiWGrmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H1=s-*E8!Rt$Hg't5Z9RkaF*DB.!LY?OLrn7M+;V4ssrn7^#ZeF,@`nK.og.)'8
-!`n#Kr7WAhg=f6Se9FY\1tnpWg=f6Q:>4F?@G5Wb9M@k#;G'Z`g=e^h9EJST9`E`R9\S4D>M@f`
-CqOMqNnO]ss5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``$Us-ruL!T7&Yjpegs:kn)h*`,[.Nok>oroO@C<odE>roOQ5^#nHgdH9TIk">VL
-!a=__r8o5#k2oM&i."R"2s.E!k2oM$;Wd,fBBF>(:f'^:<_cMuk2nr.:]b1i;#]Sb;!-ok@-6V4
-ElN(=NogQ3s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6s)e1?!'L7^%:uWB5H1YfNi\jnXAkG_X9+&>@K!8t>E,_cM-m?cAZU>pXK6!7
-E-SIcAZS"qX?<SS9WWFfXG(/cX?<OhN3#uQXGpGcXDOb!VlO'^XE\]cXC\IWJ#m:6XK8'cri?3\
-7TcPeX8tSCPH4u"map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H1=s-*B7!)3CG%=m0d:Y46@[+`Zag2">!g&e0KHi;YgF0jTSXa/XSJD-ZNg=h)2
-NgSPSJD*]Ng.^5?@+pr)g8TMSg.^1BZ.`r$g9YkSg5=6TeCeuMg6[iRg47m-U"Y-og=j_Srn7I[
-=E)^fg&Y*SPM-6#s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``$Us-rrK!)W[W%>X*.<8utc^?3t5k&JB=joVbeK)Oh%H+iA&[t!Q&LZYRqk2qH]
-QD!C&LZVFqk"t3fA`fUEk-B[&k"t/e]B4'Fk.Q'&k)nG"i8o<uk+J%&k(i(NWof2?k2t6&roO<q
-?$>''joJMmPNE)8s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6s)e1?!'L7^%RrQCJZPrR>!,BVRQ<NVrN$#\M#OJI<B<3bXK7CD4G0`:IQT`U
-XK-;&4J?CKKnVR$XEcpJ9Qs&iULuWBX'@c89rtF]4?RtM3af%i@]ZYU4?T%54)$g.XK7"93_97O
-!H*/]X9+1mLQeeD]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H1=s-*B7!)3CG%TlCuUtXPUE_K`j_b*RkrRq9DXT$pFCe@?cg=il,9W$OtTM/%i
-g=_K[9[&,\WMiCAg6kWq@@(4kc[n`gflTo[@G9GK9MCt^8pT.DI+m;@9ME=W98-'7g=iAs8mMAL
-!K3?Eg&e>oXHV?Bir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``$Us-rrK!)W[W%UDn-Xled-GYhi0c;%01rT4,U[f5D\E_]E$k2s?R:p9$DWDHF/
-k2hn*:tLS!ZE[,^k+Y\=AtNO-g5/P1ja0h%BBJ?s:f+"$:4VKgKBD<h:f,Bu:Q/,Ok2rgC:1=.a
-!L'5VjoVq1[?K_Wli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOp6!d,u(rN$$DFMFm[Wi)b"NUNqMWB-sPX95N$3i`1\!C;I'X9Q9(f@>Z*nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\D!1KJ_H1=!gPWorRq:<PJ>fSf[SDnZgZTLf1OQfg&p$X9%X'r!E5t\g'6R:hV*_4o)%,G
-bCT*H^@9fAJ,~>
-#$LBV\^d1YJ``$U!hD<,rT4-QSA41hjP\sC^$k(bj%eP-joa`':?2?9!EZUjjp(/Og!tl,nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(`2j&p5s^Y$X93K/6)FCY".MSBI#Y33]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/`7b<m;Gt$mg&mF7;UP<o"3"/9SW2>-ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OG`9%0-<`[**jo^uO<o*T6"41(LV2aUAli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(n>lVci2csZVXCMdWM"gDo;i/-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/nCdlhi7\4addGfif#[email protected])Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGnE'`*i8t($hX9M,iRWSBoB$8Cs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(nZ2bU<;rs"UPA`K");A1PO5FPPZ..S#+f@JJr:SGk,\YuA7T<DX9,A3CA4e0
-IBT^V]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/n_+#UC]<#gc`6rt",DB;]'\2P]P@#k#0D@ZV6D/nk1TojIt*%@g&flULA0C%
-T<HrQir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGn`BkkEW5)$g9^b?"-/,S`9l[fa)LV3#1SBtY.>n:k2lc(L5(NUjoXOsNVDQ8
-Vm#4eli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(nZ2b3G5eQDQVma`)Ie)I/T@emUmRjWXIQ&aR&ZgHV59QPXJ:u=rN&\]R&-X\
-X-f?WXJ/gMEuCW:TpVIRXK%YTU9(&ZTU;RWXJM;WSY<-dS!^4W?rVf1>-+g*R%(1UR&-1AXK8IU
-0s%IOR%gOHSZJnTYH.r>map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/n_+#*QN#S=^M!Q")LS*R3KDhId)!r[g;V@e_:ZrIdF#eRg<[@:rRsr__9pZa
-ftkS[g<OZ8Os%nFbe_HUg=O0Wc.^C^bJDT[g<ma[a3<8k`PL0[H>BFSEn]7!_8Y-Y_9p*?g=k2W
-52+`9_9UTIa4f6@YM'3?s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGn`Bk>T)RjQb&..?)M=lk4I,'kgrn=3k0Vf>bN.6th;-9*k1[berT6eubMD":
-jibs3k1Op_RNg<`f?;_,k2XY.g#gr8f#uk2k1n/2db*^EccbA2JT7rsGin/KbL#D0bMC@jk2ta0
-6K[F`bLtgsdcT[gYN?&Ts4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(nZ2b3G5eQDQVma`)GH[&OGp9?=&;ndXAW54:iLLrN/S`uXFir?riA;4;,BJt
-XE.38J?2h6XK6TA5upf]Q)nk":fa68+&u->WiB/t<?HOgKMkWbXEnccVa7DcD,=,aR3PO);iq![
-$TtMlJ/j*,,@IUS4Kkgj]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/n_+#*QN#S=^M!Q")IUS=\$=Z<De3b'g1YMUAWDs!ZEYX<g87qdrn9Q/An=f#
-g6-#[U=sOpg=hk@;Jfu\^"SEVASoSZ-Z!@4f[t+RCaY_+Ve9S"g7+#Sdo+oRMIgJ#_C]A2C:=,q
-$V]:.UEcML/:-%(9X!.Sir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGn`Bk>T)RjQb&..?)J.=Y_7SjhF_c$Dk&#?sCR1G9]XoJ[k-/*0roQDDChm";
-k*g(%X6+Q@k2r8k<c`%ra6&S$CNJ(%.<93HjPtAuE[ddGY\e0?k+e.&hcJt&P&"p?bV*aIE5;J8
-$W-!JX<jmj07i9J:p9!cli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(nZ2aeRJs8gW13df'q.KP<MHQiI?9%KXH"BYXI$"WUS:6WX:^[qXK7CfWN9f\
-H<ZJj9TN8:rN%_>P,rMIXH\g.8Wp/3T<(8U:me>V1p!!7N0%FgH<cP7R&k::OGcVr9STXC8#r_m
-4T;De8Y;kUT<,,\YH.r>map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/n_+"S_Z&6ie\qI@'uO$FCsLaET!tOsg9`91g:u?DcH]Pkg(Cu4g=iiVf@ktL
-Rrc'F@CC*`rRru(\_;q1g:Xo(>e&KSakBSAB#*-B6JB.YZ+#%BRru2[^tOis\$0&P@B/&,=kVN_
-9`E`N?-1Q+b1bRaYM'3?s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGn`Bjdc2Qi+iQqMc(!]uZEnTShVnoN?k.W=Rk/uglg"B[1jq5XQk2s=*j5u>t
-UNs\hB#&Q*rT5h8_rd,Xk/P6R@Dh4seE0ciCWkki7cqg$]>9#dUO0h$bN>.D_7F!tB!g^R?KL>3
-;#]S^@as7Ke`Q#:YN?&Ts4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(nZ2b3G583DH_d`fE3)%u<s)p5N`uC_"*\a'GlFcJPZ+ZbKk((_!H(+#<s"jm
-OSu6m6)Uf$H`Us`="KN94KPVKW'('\"$EZI/H/]VML%6`=KJT66iL-nTM1iVX?EVcX??K`"-6T?
-@B6I6]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/n_+#*QMK5=SC#uWNnR#&DZbFAZuZ-!".,(.RJtnD]P?0SWI=a!!K9eQDZ[jq
-\,G"m;UjEXS(`U8D`G8\9\S2seP,tr"&.FY3<!h%Y+%q"E8'#p<W6nCb@/BDg.p;Sg._M""1<-L
-H`Pj)ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGn`Bk>T)%LQUtb%*Q0(a=FT[<Z^3KV=".tpFU&O0Xa)L2'Z@r2=!L-O^FTTm3
-_>WL.<oE,'Uum\[FZ[M';!-n?iDBO9"&S-s48s@.\>)Z=G37q@>5iXNen3:kk#1:&k"u'>"2B&f
-JZIo;li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(nZ2b3G583L9M1.VI&rZ<M2>H<G=[kqXAu&`7&?udST[>\XJTEYM/e9F>)A)J
-Q(V69M-QK*OK2GnXA=\$*da;/SY@p'R95;[+fqVTIYi5s@oo_!=e_WnM2>]39M((]FKDO"0SuU,
-W+J#_poFKV?ad$?]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/n_+#*QMK5E?s]sjS_Cl"XfZ^!QWprug/ZL"<mfXT`g0T4g=(DGXcKL.EilHq
-]utAsX`_QJ\(PYJg17=X-C_k7aNZu[_JlW2.b`F*T<4EPIW*oUER)gKXfZuj@9p!tPM4Zk4KZua
-eU^67pt>a>H+)E2ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGn`Bk>T)%LYARi30VWQ$G\$p\GT4#M7k#L2>>MSB'd@OLVk21co\!OGTGdk/=
-a4>FC[sQCh_<#cmk%_B(.&>*Qe(I.,c$$RT/`u#LW4/@tKluM$GM1Vm\$pt:An&6;S*&e@5e#P2
-i.t"XpuVTNJ@=SEli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(nZ2b3G583AJWX;_ri??b?XK;(CgV/[X9!Tmri?3Z?XI[LX<hFbGH@mE?XJAc
-XI`d+N0dmrX']D=UgInlDLu5SQ="m<O'dB!ri?lM?ZN5Y?`U8hQ`Qrh?\YXULgP>,XJu2+"IlKo
-HYrPZ!eVMH[]B\Emap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/n_+#*QMK5:UUYQ7rn7UaG^.3]M0P'Zg&[Y3rn7IXG^,,Fg*M8oQeL0DG^-%<
-g;nM`Z+kONfQ_l!d!1>FMkt[(^3H%![WnK>rn8-CG`^X.GhLfY^Y6tXGcKJ+XE^#ag=H7J"N9$J
-S;R*q!i@9A[b:rFs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGn`Bk>T)%LNXMTIYroOI"It,i-Oai\qjoM3OroO<nIt*X\js>e4TB>:oIt+T_
-k0ng0]?5VrjF;mGgOG6iPHKDIaa^#H^ji@\roOuVJ!fAPJ*#h-b3%E-J$e?M[XXn2k2QAi"OH5m
-UltN8!j<uU[cRe[s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(nZ2bg?Fd-?X+>h4L@;2GUH*IdpoFOR5'cq)!Ha%'X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1KJ_G\/n_+#mGIcE1fqbEnWpeXDcUjA>pt>eP:RV"3!L'Iig'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1YJ`_OGn`Bl/IC\JCjfPY>[.!,Zg.e*`puVXe;kj'L!LpC&jp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7gJZOF(VlU!#B4lkbX95&,B9;ni!cr!sWiQE9map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/VqM7*JqBogg&oEJK"(O/!g8/#WnI[:s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGVre*BM2AJ)joa(hM8AuL!h+t:WoaNOs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(g8k@=HC"N2!LfRgX8n1VX9,)AVlZs(]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g=cV=R_JaS!Q<$fg&SATg&fKee?%@.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg?&ISUWNJs!RB-&joE!jjoX21i2l&Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(g8k?R@$1Dh!Df-7X9!s5jK&>Dr2]sl0V,;H#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/g=cUAHFWt.!nh,%f%L/%ZfKg?9`3TGaZ[YFg'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YJ`_OGg?&HSJAV<J!p+.@f&d":^#\;U;#KGWe3VK`jp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gJZOF(g8k<QQMmm&X$*PcJW,&<I$(M3GB0^bXFkP\EhKL\Ee"(i#ao^gL9.7mEf^'u
-"KP'kEh<93%sr>oXIF72KSZRIQu\R7V#.4pWcE7]X9>8<IS665X9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-#$LBV\D!1KJ_G\/g=cR@^AZb'fhL2SUTpK!S[[>,QBBhRg8:"JOiuIKOeVj/#f;_)WnPm`OgY&>
-"P?plOidUV&"A^0g;T3-W3"O3^lcEpd/2Muf9)?tg'#]`TO5^?g'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YJ`_OGg?&ERaSk6=j\b1&XLkIGV8DBWT:"[$k-(/qR+CDrR&^/J#gJaEZf^,3R(rL[
-"QWs.R+2,t&#>TLk0TLWZ*rSXbF$J?g\^+7j-ZD:jojA)WFaJYjp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gJZOF(g8k<QQMmm3W'IGcGoBg+='M_>EHY]hJ7Wml25,/0G%Z0'W)7_H*3*7eG$11/
-X;@p0<Hb"9X)W!">cO;EJ7DuD6o@1i3gBNC$EA8$XK8C(G%hkcXK2W;map!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1KJ_G\/g=cR@^AZb4e5=rRR3?PrDKFHaOHk+CU4AM16d1dPQ%PR[eRt.o,M.%&Q#XS9
-g)&CJCR*&rfoM&VFk=VkUOINl<^T\U8\=lR$J1P(g=k.tQ%gI%XP*m<s5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1YJ`_OGg?&ERaSk6Ji)]"&Td+e0FF*#-R%AffX,!9N7b=/mSr0?+iGG0;-0'?DSp/?S
-jqm)gELt_Cjd2.%HfNL6XG)27>=VXf9ud(m$KI^@k2tZISrFuBXQB`Qs4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7gJZOF(g8k<QQMmm/AqI+cS4o/GNE_*"C2-=Z5-1iT9rtF=C/STD6)UfcB4cbpX8kBZ
-X9!-bri?Bf2JQu'Aun1,ri?95Kj9R9PkhBd4KPVgNNB3SSZJms]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g=cR@^AZb0Ju%,S`aHGoZ?*!>LPK,p:>4F?@G9G"LM2.j;UjFSJq9ctg&OhC
-g&[&$rn7Xf7#-P0J_EnLrn7O)W-#=\]D:.d9\S3AZeF,?`iRkuir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg?&ERaSk6FM65q&d:L@;]R$k]NfIS7;Wd,fBBJ?HNbsL4<oE-&M28>6joA6S
-joLUAroOL'8</^GLuqWjroOB<Z$X*%`qea&;!-nc^#nHgdB)I7li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(g8k<QQMmm3X$*PcS4o/GNE_3.I!p:+6)^lJ9rr5PI9:$]8Y<)cUMG:ZXJJ;\
-X:8unXJ;k\5C7g)PcR'Kri?95Kj9R9PkhBh4KPVmLTIIESZJofUTgg(]'e2#LXYejeHa-In)qLU
-g-U;~>
-#$LBV\D!1KJ_G\/g=cR@^AZb4fhL2S`aHGoZ?*-NStDIc;q9U4@G6[$T5T24>fk^Rc\S1Hg<rss
-g'rn0g<\Kb:n=5J]@p'4rn7O)W-#=\]D:.h9\S3IX4l-,`nK.mc`l+-ir@lhL=5Yig'>fPmcqOU
-fg1,~>
-#$LBV\^d1YJ`_OGg?&ERaSk6Jj\b1&d:L@;]R%"mVPp62=Q/D\BBGGFW-*gV@FaN&g5i/ok1s2:
-jpdHMk1\t:<2HOg`TC+ZroOB<Z$X*%`qea*;!-nl[-$@RdH9TFg9B]Dli5YgLXYejeHa-In)qLU
-g-U;~>
-#$LBV\^c7gJZOF(g8k<QQMmm3X$*PcCb18oJMa-C@:NN"M-FI\9rr\K@ll]KXAi\>=0,qB@of/s
-X;6Rr@p5t8H=(/fKU3rmQ)plD<Erd.AG`G<WFI,^S?-(->p+!cX?8VLX9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1KJ_G\/g=cR@^AZb4fhL2SM)VCsUI*:iH[Tt>X`Str@G75rI7m/\g1u+bDVBSgI;R%$
-g(p`2I<+&qRs9@(VnXg1]\:h*CNO]7J,@q0f6o2u`S,TcFt&=&g.Y2Eg'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1YJ`_OGg?&ERaSk6Jj\b1&OZKd5X@Cp4JV8<Z[sE^9BBH%?KMP>"k&?!,FQS=2KQGT<
-jqb@OKR)_BUORrEYf\YOa6)8QEI3(PLAU*Cie/q;d,oh2I4LHBk"nmYjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7gJZOF(g8k?RKVSOJ-*'D1XH/(,Kq=!rXGDRmXK7M;L01OYMhRaVWN;bHKqYTHKnYoh
-X9+K;U].>*MhR4nTnS2nXJpo2RZ!PmqlBdure1]SXJLW1QB/,#)j7G,#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1KJ_G\/[email protected];Hg9mp%WQD-hg9%?ag=j$8WGpSFZ)PjEf%S9GWQa)HWN!`/
-g&e^^cMlN.Yc5%abc.Sag=E7,_m.%aqq;&&ri$7Ng<ut,^9u[m,J(,5#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1YJ`_OGg?&HSYhK*=-08:dk.e4OZIH2<k-hS4k2sLcZZbKn]!Bhkio\dsZIe6tZEh^L
-joWB)gA^4F]!B*5f<V^4k2N\VcFV34qrRn>riumbk2!>VahQuB,fHqL#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7gJZOF(g8k@';2+tM!K<05X94Mf>?pTt!.auO!0ZZL!1Wmj!-e+;!K`8DX9Q9(f@>Z*
-nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/g=cV"AuP[^!O9-+g&na)FER$*!2BC5!4hFL!6+kX!1*<3!OoA<g'6R:hV*_4
-o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGg?&I6CpEs$!P?2?jo`AEH@5/C!3?$D!5n-b!7:Xi!2&rH!PuCOjp(/Og!tl,
-nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(`2j'7NK'b%X8nafN<#^=X8o-qN<#<=X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/`7b=;ZEhjFg&T(hZ2i/8g&TS!Z2h\6g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OG`9%0R]Y*%fjoEa*]E$UMjoF68]E$*Jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(]W;3`<)f`GXR`Fs]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/]\3IZC221Jg@Er%ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OG]]K<oE,aZbk47X=li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(]rV?u>*P8OqlBjl4>h\kqlC"5map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/^"NUuF1f0<qq;+p9LFBbqq;86s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG^#fI6H,dkbqrRt2:e-*!qrS+Ks4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(^8qWh4t00YXK52kDuHa;4T;D^Q2XG\WiW:79U1F8#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1KJ_G\/^=imb:,H@Vg=g(FNW%Q29`E`G^&DCCf@nr1@(hBM#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1YJ`_OG^?,a";Dr-kk2pAiPl9_E;#]SWa8TZSj6#K]B#oej#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7gJZOF(^8q[;IoMr7XCdljBn-,`!'L7^$:C>R<N3$3JXfo.M6$ommap!Ee+*=c#KMJc
-kJ6T@6@]~>
-#$LBV\D!1KJ_G\/^=iq@Tk_Tpg4@,\Kq\M"!)3CG$<5$bCtI?lUW.>eM:r0ns5)Iaddm:h#Kq\d
-lFuc@6%A~>
-#$LBV\^d1YJ`_OG^?,dWWGp5?k(q:/N2lm>!)W[W$<ba&EoQ2;XO)74M<5$.s4PqXe+*=c#KMJc
-kJ6T@6@]~>
-#$LBV\^c7gJZOF(]rV6n>lC`+7mnkSri?)^ri?H>6pud2W#7uk4\pp9#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1KJ_G\/^"NLlFoC"r>$!YPrn7?Grn7^2=')EUeK@pp9k9+7#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1YJ`_OG^#f@-Hi<(/?X#ReroO2WroOQE>?eGri?DK1;/1sM#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7gJZOF(]rV6n>lLf-7\?GGHiC)H4T;DlLnph5WMrLTUn3OHXFQRqX9Q9(f@>Z*nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/^"NLlFoL(t=j##nS,V+A9`E`UXj><lf%+0@ccEBFg7l9?g'6R:hV*_4o)%,G
-bCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OG^#[email protected]?.IY9V#KKV;#]Se[bKP=iSn@fgXEdsk,ZO^jp(/Og!tl,nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(^8rH"0d0W"XG/o&7l%0=4V^,LX<B_i?)t&l90GV"XK3:GNN<>qmap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/^=j]p5:LL(g8[qD>!Ufb9cHgFg+#fkFkGE]?VOM(g=dZoNS4Trs5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG^?-Q/67d6@k-Iua?:3l+;&iHZjt0G-I,sG2A5QL@k2mk:NTLH2s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(]r_46riH.#"0AQ)XT#:#XT#:!XT#:#X8u?nN3!5pmap!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1KJ_G\/^=rP=rn@D*"5;G^gA]e*gA]e(gA]e*g&Z%qN7nKqs5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1YJ`_OG^?5CUroX7B"6S_-k5OKBk5OK@k5OKBjoTU5jc/C,li5YgLXYejeHa-In)qLU
-g-U;~>
-#$LBV\^c7gJZOF(TWA0VUl;AZ]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/T\9FVd#?Z_ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGT]Q9lgl1A"li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(]rV:"2-0^X!i)ilmAp>bWr9"#UTC6iX9)E[Q2[ic?`*h(!iS4DUoXd3map!E
-e+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/^"NP#6Z)hV!m]NFmFhTgfDXD)cJ$SCg&c(X]`-UcH.2cH!nBt;UtQ%4s5)Ia
-ddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG^#fC97s"[l!nl_imH+H)j8J*Ag?.)fjoTQna8Y3%J):1e!oZsPUuhmIs4PqX
-e+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(]rV6n>lC`*4K1R4X8u=brN$&aW]^6]!F1T_X9!lbr2]l\UoXd3map!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/^"NLlFoC"q9\*&-g&Z$$rRq<Kf1c.s!HbXHg&[t$r7V-EUtQ%4s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG^#f@-Hi<(.:uYIAjoKM@rT4/[j&#^:!IMHXjoMQ@r8muUUuhmIs4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(]rV6n>lC`G4K1QHXArbi4H-@o4?RbfX*$NeK<1L_1H_>3X?NXHrN$$)N;fmZ
-JS4n^!'I'Y#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/^"NLlFoC#99\*%og1u,C9X<BL9MC](fp#0(VV8s85toJUg/$<orRq9oZMrPY
-UP&Ku!)03B#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG^#f@-Hi<(K:uYI:k&H'e:qYqo:f*\Djd].DYNF.Z6r;Ltk#:;:rT4--]Dgpn
-XGZr<!)TKR#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(]rV6n>lC`@EN4)]XI:SHXDrc(XK6JcF`XXcBRm0aPPqQaF/s<ZX8uRbri?0d
-=/c)!!'I'Y#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/^"NLlFoC#2OP#]Lg;>aog5r%^g=h^SP`jbSKVI1:])C=aOk>cog&Z<$rn7Fe
-DUn^>!)03B#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG^#f@-Hi<(DQfORsk0>o;k*N-,k2r,&S=8U&MlYu\`;Sg"RH0_5joKh@roO:'
-FQ!,[!)TKR#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(]rV6n>kkB)RR!aOXA>8`XT(E^X9=qeXAtJXX8uRbri?0W@B0:-!'I'Y#.j6S
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/^"NLlFnjYp_c"q:g18)"gAakGg'#9'g2+@og&Z<$rn7FUHeA;N!)03B#3,[>
-g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG^#f@-Hhc_-c;rfak%W*>k5S9WjoinCk&SE6joKh@roO9jK&lmm!)TKR#4)<B
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(]rV6n>kkB$RSNj`"+P$dXSm8@X9N?fXAtIcEql^:>`AZ`!J+n]X8kB]X9!c^
-WiQE9map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/^"NLlFnjYk_di]""JLP'g62H!s4R[1U=sFpg5u*`!HbXHg&[t$r7V-ErRq:E
[email protected]@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OG^#f@-Hhc_(c=m4>&?:]Ok*hg0S*&jlWoe??k*Yr+!IMHXjoMQ@r8muUrT4-Z
-LoTSAli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(]rV6n>kkB%<A7/HX:KnF4ER[*F?D[<XK8*e4HfK@!F1T_X9!lbr2]l\ri?0u
-5s;6L#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/^"NLlFnjYlCHQ&)g(1#R9U"/_P>"ZIg=jbV9Y'rP!HbXHg&[t$r7V-Ern7G%
-;GF1F#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG^#f@-Hhc_)EBn19jq"Uk:n6Y/Rnuqbk2t9):rE(j!IMHXjoMQ@r8muUroO:=
-=&Q'\#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(]rV9o-t1l3!b!L9ri?-(NrH*]W(S?6X9+G<U8k:!]'e2#LXYejeHa-In)qLU
-g-U;~>
-#$LBV\D!1KJ_G\/^"NOm1OIm1!dc`/rn7Bn[/Sb\emBs,g&eZIc)TJ%ir@lhL=5Yig'>fPmcqOU
-fg1,~>
-#$LBV\^d1YJ`_OG^#fC.2M0]G!eN;AroO6+^Ad6riFFP>joW:bfrF0=li5YgLXYejeHa-In)qLU
-g-U;~>
-#$LBV\^c7gJZOF(]rV:7SY4`=!hc*`ri?*orN$($SY#h^!NDopX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-#$LBV\D!1KJ_G\/^"NP=a335k!mAX8rn7@trRq>+a3">7!S>_ug'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YJ`_OG^#fCUdb!79!nYl[roO46rT41Cda\9Y!TVt7jp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(frP3oHfhC1<13<Y"c[bpMI/g7X8n^gGQ<crX8o0tGQ<<(X9Q9(f@>Z*nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/g"HIgSEAN+C;TPq"gaT4YBX.2g&T%iQiOMcg&TY%QiNnjg'6R:hV*_4o)%,G
-bCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGg#`=%V<6n@E6Rn8"hgSQ\:7cGjoE^+TE)^ujoF?=TE)(&jp(/Og!tl,nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(frP09jfAKAV=UbmO]ud#3iG=+X9Ft=E,]!EorJ=p5?Ml;GIX^Y]'e2#LXYej
-eHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g"HF"jk9a?dIZ&r\9![@8_$]#g',8INfJ.kp"BSu:iMGIQFPWQir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg#`92jlQTUh=Kb5_KhG^:#T+7jorpbQBld7p#ZG8<Ha[cT=F"fli5YgLXYej
-eHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(frP09ri@#I4?OO`XHH(9EibHCN_iE9-S_]#)jRL"*16`,$Xl.n/$,UM4BA5Y
-4T;EUA#LkM4DLsm<]iKiX>*4.5)65'83BinS?-Ee9:)_BXK5lcXJ/]W=f8?24?OO`XC6mcN`r&Q
-4?S.qKGp(H;ii)#**4&NLH[gIHI&Ys]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g"HF"rn89=9M?V`g:1<[OkRAhZt3[\0g=<),/)]?,JjB5$[YQX2VQSu9Pr)/
-9`Ea>Iap;_9S_?ID+mWlg-/\7:93*[>>/f[`nH,?@)(Dhg=gqRg<FG-ERWWi9M?V`g3]mSZuX9&
-9MD58W$8l[BsoC(,]4aHX%l>CRa9[lir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg#`92roP,P:f&D!k/1P&RHDF3^2%?&1dU8A,ff%\--Q;M$\D2i3Tf1A:ik@Q
-;#]TNK]+n$:la\kF&5]-k!EEP;RGT)?r1ekdH6BaA]a(2k2q<&k1F]NGMhP9:f&@uk(9u&^3S4G
-:f+7UYp77tDnmf@-?LH]Zr9dWUX/',li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(g8k<pG5eQX5GY*2XJ&FXUi(:U8Oo/<RW3PQQVma`&5\aqXC6mcR51jFLnoo.
-X??H_9;jG5X?<S[NhiI4XEmR@Va7(TTWE$5XD)mSPtA#=UmtJYXAk+RLKLWBUnigJXC6[UM-cm<
-Ung,SX>X%MQ(_;t;0>I&7\?K@S^4AA]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g=cRhQN#SQ:XIIig<=*Ed#4(@?!G.a`/g5<^M!Q"&7r]3g3]mS_EZamXO+.d
-g._J!9@Z#Cg.^5I[*[/mg7)O(do+M(bM%kmg4ks@]j9;bd)BkFg1mk=X)Qcgd*SlJg3]UAX`qsu
-d*PG>g-obu^!(GRAsHZD=j#+(a3WHDir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg?&F'T)Rje<8?9:k1==lgln5i@UI=*cBk0ca_h%>&8TJOk(9u&bsUW9[bSE5
-k"u$=9Ar"]k"t3p^>.L>k+cPMhcJNJf&i0>k)H%ha(".,gsC,nk&@oe[!(S2gt]="k(9\i[slrG
-gtY`gk"0OAa4GKuCn5%b?IdiNda.%[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(frP09ri?<_6ptIbS0%Yt"+.+@TDbhm4KL[DX9DFfXK4^crN#uRr^6fiX??H_
-)5og%X?<SX<^]>1XEnccVa6qHXK7LcX@teV6jKbP6q;s4X=F3;'ORr#6ptFaXC3tS<ihij6ps#9
-X??H_$<WBeQV!gN7mp4Ac`@>^map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/g"HF"rn7R]<`XP#`[:[c".\(Nao0op9\N2=g')'(g=fHSrRq68r`0)=g._J!
-):_U<g.^5FD,s\$g7+#Sdo+=ng=iuRg0mbU<X7;J<a)KVg,8k1'R8?;<`XP#g3Z1fD;*$F<`V`E
-g._J!$?3Fc^g5(9>#o7Oce8T_s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGg#`92roOEs>?c[@d4"uu"/P'geG\M2;!(UQjooPDk2o_&rT4)Gr`]GIk"u$=
-)<"TXk"t3mF'Dj8k+e.&hcJ?:k2sL'k%7Nj>6j7_>@+VtjuE?E'S#8X>?cX?k(6*-F6:ni>?ab_
-k"u$=$?j4$b$rl_?X%?jcfPGts4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(frP09ri?T/SXi'JW+(RRMg)-fOJ`#Y!f/CGriB\'8W'CHOBnEJ?EAcmSXj2j
-FEO.FA"G`[VDb67=.NtUVJp(ISNEWWL7L_7XHQkZSR/0OU8VRYXF+oVSRS["SXi'JX&s_EXK7:e
-SRF=PV`(*EXK#*N;2n/4?(%6uI]TVl5LZ\<]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g"HF"rn7it`l:s2eU4L=Ya<p@\'t?1!j"A@rn:r+>d)T0[s#d2GhT$I`l<>Y
-PEa),IE5%2dRDKoDT7;gdZ/h2a%Od-WlA(Xg:MFG`d#p#cII?Gg7=/A`dHKU`l:s2fPm>,g=i]T
-`d9u"dm_:,g=Kr9B!YdUG/D7RT\A+^:t+,&ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg#`92roO]0dEu%XiIeSd\t@qa_;>1R!k(1UroReB@Cb4V_0jYXIcdhldF!O-
-S".mRK[W]Sh+?A?FO>t.hNilXdSJYO[*`*$k/DVnd=0qDg#7Unk,+?id=UM#dEu%XjE@?Rk2s1(
-d=OdDhau5Sk2U9`CqX;uI*ButWTN?2<7Bt6li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(frP09ri?2t91t?FX9W-+?*'>b98EMJ!iJ\UriAXp91so=XGokGOK>O691thW
-XE.$-WbY7iKM-QkHV8lhKi(LDC.j_k@S;/PXK7XZ98\X#ENH6YXK6_@9;ARb91t>IUe=@,ri?u[
-98?<$MG$U+XIi-kH!tf,E(`iAXK83T9%0jG]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g"HF"rn7Hb?XL5?g';n1G1sZ;?`X1[!n1Mgrn9na?XK_bg9Y-n\(]Q1?XLk-
-g6,fMf8!_CVdGhFS6r%-W+TJiL0qIEHs`Obg=j/G?`pV?O4r<Fg=i$'?dIG;?XL4pcX1%Jrn86S
-?`R_AY?tYKg<!]FR<t0LNaH.Pg=jnA?IRU4ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg#`92roO;tAS&XUjp-EJI-/O^A[VO"!oIS/roQasAS&+.k.P>;_<0m\AS'<P
-k*fjmj,[cgY[sKiV.H`KZ#""4Nb-,jJn:p)k2sWoA[o<_QKI=mk2rFMA_Q9^AS&X=gLXrkroP)h
-A[H3`\7K6jk1!siTn8ejQ=XWkk2tGhA(0QEli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(frY4#^T7R4Q'GL@bH(c98Ysn;#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/g"QIr^Y/h9]tJC&bM!$<?.%-T#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGg#i=2^ZG[Pa2`DLbN8lS@bfGp#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(Q)k(B;cB3SX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/Q.c>?BkbPSg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGQ0&1UDf=!jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(_5mX(i2csVT'iZ\U5ktL#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/_:en*i7\4[aR7a_c*a;"#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG_<(a@i8t'se*c?!fY4*B#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(_Q3co@/d5.RtCU?"&r3WP3o=OM-fbS"dMr$Ef_L,XSu&s>4\fqB`:j/T'`TZ
-EU'V0]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/_V,$lHN)V!`23Fd");PS\aA)OY'BNk"heQ*OL?_&g&Th*B)luDg&Qg*B)p$?
-g&R3!g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OG_WCm,Jc=d4c`[6/")r1i_sQRe\:4#2"itPCR(t?:joFNBD#ehPjoC>=D#i&P
-joCb5jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(_Q3cNJc;_ON*Q@`)GZK]-@;hqRtd?4XGWOAL9$JlTq$k(XI4X%rN%o3LRt6A
-VhU/3XI!+VHki\ESVEH3XJU`,S#hm;PD5a3XIFs3N1-iLM2&(4@;;*c=KJU#L5u87*f#K)Tra5@
-QBk%BUP=MpXK.)LS;OD-R>dVmS?/eSlDt3$map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/_V,$BV#K'KZ$$'")Ip@l0UpeM`2UW-g98N?WS+h]bf6Wtg;9YqrRs00X2rQ>
-e>]_,g:q[CSK$3Ta/Qf,g<ut"`S/#8\uEm,g;U&-ZGYDMY,U(-H\T;=E8'$nWO2ZY*il9>bhB@'
-^V<q*c`*nbg=`IL`in+&_Qh%_`nK-?lIlI%s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG_WClUXo@G`]6jP>)JI(01Sj0qca1jXk.&gkZfT*2f[7%Jk00sErT=-e1t1+>
-i3U&Xk/qqjV&\Pmd^.'Xk2!AMd,rBc`O".Xk0UHX][#[%\$P/XJrRm_G37rCZbHG$*ji8[fB0_L
-aiRlOg9\-7k2ir$dCA>Pbe)32dH9RflK/<:s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(_Q3cNJc;_ON*Q@`)F::&OdE/D<FT""XA`\3@VU-5Q]32BXG9PWriB7>@UUm;
-XCG^GI&p#2XK6fM3)a9gQE4G&@T9+P)d6]NXJ8a(<Z[+!FC8QlXD`BcS4p#c?Xd;mXD_NV5C0E#
-9rtEYXBT.C;lQf]F];am@O4Yq87em(4R0!P]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/_V,$BV#K'KZ$$'")H,)=\A-bBCj^*?g1c(TI#"(A^p>Phg8e_.rn:M5I![oG
-g4"EnS_@Mkg=i.O7qm?h^=mj[Hu%'%,'&'Ig<XP^DC2L>PBqV1g5VNS`aINSG^OY1g5UH,:n$+V
-@bTO0g2hXhC"M!5P\PK0HnSh_>CbG]9^:=9ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OG_WClUXo@G`]6jP>)HPeY_TM#nEJ&>\k&6#sK8uTZb.TF4k-SiOroR@HK7Z7a
-k(SG:VWML;k2rQ&95fH*al\,+K5oVF,^=r^k1am.F==W\Rt63Ok*;Y&ct;G&IY3$Nk*:ON<28U%
-BBJ>Qk';T3Dr]nWS8a"MK/$pq@#*n,;!R0Ili5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(_lNp:;4[]f!NDsqX;.Kp4B.rS5B_L"4KO/[S?/Kb9V7_Kri?]g?EC5WC94LY
-M.p1CHp3iiS,KEZ4/8ldL9-knIQ*h!32`i?X@/kcV)bW67X]_`G&LK3<hug(@X`Y`TO)toMQ!VG
-3IZEUXI+Hc0;tsh0r1kGP#$m7JRtpaU["ob]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/_qG1?B?1#*!S>d!g(hq09P_c(:R7Z?9\Q?q`S/Vg@*6>srn7seGhUlEL>(=E
-Y(^tjSPQt.`VnL]9@)=>WS5=aTLQrT8(?6dg/cSSdRi/q=Iu1!Q&TaUD:%!^IA!*#bBKMMY1;7E
-8>)Vig;0GT4Oi)B51%s/\R_gZUk%1QcKa*fir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OG_r_$WCsr=F!TMr7jqZTL:iOqH<1^(];!+r7d,s'AA_#">roOg&IcfdlNTT>l
-\;bg6VGkQJd/E)t:YY#aZf]T5WCkS#9&Jc-k$-U&h+d%@?)OZ>Ss=JuF55o-KW1b>epaHp\DcSr
-9W>"/k00g(5N([e6/1JU_eQW$XbZ'$g?Rf)li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(_Q3cNJbcAOC8n:OH`T+(C'/[]K4Y"_")N?qKDqqUM-d9bH>`\_!Fo%,C'(/(
-S,KE#4KPVnL9+WpC+c'Y4KPVHX??K`"$EZ>4T9($Q#B90<iiB)=T3%LVlX]L>`GhS05>6qXB94P
-.&a4aHiC)MP#dHHK4X5I#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/_V,$BV"r^KL=Y(9S(^7/L'*aqVL\X!",WRuVuGBRY'A[SRu@7!!Ie\\L'#Y/
-`VnL&9\S3JWS2HKL-*E/9\S2og._M""&.FK9`BbP]o??QD;*]_E;kS+eCob6FL0]>4GJU8g2D_#
-1=Y$8SGq4G\S\NoVL[j`#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG_WClUXnh)`NoK2aUuk2HN<>g8YD<)="-KI8Yl<bg\:3T&UQbZ=!JPCiN<7gG
-d/E)=;!-nmZfZUoNBYbP;!-n:k"u'>"&S-d;#ZF[aH^7pF6;V.G5dI8hr^#[HG/Ie5E1ZTk&lZC
-2;mV[V#KK[_fNA:YD;<'#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(_Q3cNJbcAW5tuN0MQE=KG'7)k?q,nMXA5cO8ZSqoO^CD-XK#`QG$p</>BY0m
-S>]G2G#=YVMl9$RXB'LZ)L@>kR@,L^SlKr;.BKRbEctuI9ie?d<hZKpG'6l\7<<WZM6(qZIf?D\
-;KcXfKr[jHN3'+!4+]_G7]H9d!gs7OnZ2r+map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/_V,$BV"r^S;IYr:YM.!6QBlUGH<@0Gg.p6c>hIca\9LoLg=Ue<Q?omhF-`,2
-`n"slQ=dujYgld&g23.1+e#Ym_SS.7aD@/`1YUK9OHtBq@;X`=D9URMQBl=4=H\tqY1f71T`3XW
-BU45iW7bNnZJ+#l9;POX=P!B'!l>5Kn_+3,s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG_WClUXnh)h<bJ"R\`V:]St:5iJ6fM\k"ar)@H?S5_LGXkk2_/cSq4T7HCg^O
-dG]):SnuV0]&6bFk&[,S,GVk0c-82YdrM%*2Wj([R%B&<Aom+_F4]DpSt9rU?(.@7\E9GSWW)#l
-DOu\+Z/oM9]]S@A:Td`r?/b\C!mM"`n`C&As4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(_Q3cNJbcALLR<(:ri??eEH.bTG]A?6X9!p1ri?3^EH-O.X<hn,Lod\SEH.&@
-XIX?NQ^DcKVf@!`U2bX?JV\<5QuRq`P&ZIDri?r[EJ1E5FKDR,TWFi,EKdJ[EH-`7XFP;:ri?^'
-EIrt!X)W-9XK6hiQuSL5W;EXt:Gnj9X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/_V,$CU\WUGXMBpurn7UeOH@fBR#n0Cg&\%Rrn7I^OH?49g*MlCXP2CUOH?p)
-g;f;:^ql,6e<$*Pc&eU&UTKWn^lY\P\ra6mrn83TOJgfoPM4a$b1b($OLj/IOH?Krg7j[trn7t+
-OJJtVfoV;ug=i-[^lZ?nebe&%A4+T2g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OG_WClVXSLu\[EFrEroOI&R$cUiTU;n\joMWproO<sR$arRjs?F_[H?W-R$b\O
-k0fWab0-0\i0^5#fpJ_LXL=M>bF#a#`0e27roP&hR'>_?SEAtOf&kVPR)S3qR$b8Ck,XlEroOgB
-R'!d$jd;FFk2rS/bF$J?iVVa=Bh-eFjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(_5mWI\Z>q3Df8^Fb,bSRn#Q`)map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/_:em<\_728NK%hmb1ZiEn(J!*s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG_<(`O\`O%PPa$:6b2r\Xn)ai?s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZSXJ"/pKjOg_=q]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/J_KnQ"4Wa,\@1)qir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGJ`cai"5ooJ_m\\3li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(WiQ5hPPqQ`O)OTj!K<Y=X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/WnIKi])C=`[Z0k3!O9e8g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGWoa?+`;Sg!^m+EP!P?mMjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(WiQ4pSGfMiRPOH8!Fq2_X9Ef#DNlqYXK2W;map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/WnIJ]`r4Tl_a!_G!IhKLg'*g)MnD;nXP*m<s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGWoa=ndJ`2.c9h*a!JS>]joqA@PK$"5XQB`Qs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(WiQ1_ri?3`@"1<<X:8rQUo\*7X*A$=XDqX>ri@61@!6mtXH-b>XK3sRU._&Y
-Q!e!bXE9#4KPcOHXCbk>]rVFLmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/WnIGHrn7I_H(dq2g'rg_d+WtpfpI'"g5gO#rn8L3H'XuRg9l4$g=eK&c!SKE
-]m4n9g6/4kW/@\1g4=P#^"N\Ms5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGWoa:XroO<uJ>uHFjpdB%[email protected]*LVIroP?IJ=`Ruk.cGJk2n^GfO`Im
-a+/]\k*rH<Z&uHVk(nQI^#fObs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(X/nLV9!#+_=GUW6XJfc[LfpH^=0%E>U9'GJN3'+Q=GUu4X-d%GB7m9J?\h@G
-XB::78?@OaAfYAbVdb76>,8m6#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/X4fbY?J=,NE34dCg=:hIX`;X7DV;HacJ#a4ZJ+$SDlo*?fYMR0K;R?rH*(Gn
-g2O0r>hZ/#JL#\bdsS!oEmVPS#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGX6)UpA*2puG.*>]k2D2q[WgDXFQL;,g#g+Z]B88*FgdYWjNMhVMQl5>J@9%:
-k'"2A@HOm@LaIh$hh/)?Gh]sp#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(X/lGKE3--'ri?MjXH>&9=@-V`=0$Cbri?H3N3'*SS#i]4X#^/](b)OKX?9.H
-XHQag,-7>.PuE]HL,)k54`S3;#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/X4d]ENS<)[rn7cSg:0+]E)_D"DV1):rn7^$ZJ+#@`S0%/fgu*](c9r?g.Ykn
-g:D6B/)&$N]kOioW]tHA9om$B#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGX6'PYQ0.4*roOVck/'3'G$0X>FQAj\roOQ7]B86fd,sJZj\5Ys(cUSRk"oX:
-k/;Fd0':SmaDS_;ZU8nZ;4##Z#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(WiQgqXK56cXIh>NQ:QpqLm4u>MamZH.U7q6XBpdcXI-(aI#sG>X?<S2%%XIh
-OG,0cSP,5HN`qE:NKAm]XK%5T_Q3sQmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/WnJ(Zg=g,Sg;u\8^0InNXLm2#YZ^qY.WhuMg39aSg;)EPT!l)$g.^4j&B<F+
-[\u(;a'ZMoZuWK^ZaQmLg=W^X_V,4Rs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGWoapjk2pI&k0ul_a^Mcr[`.BH\R,6s.XSeik'ji&k0)n$VSL!Hk"t39&CKWG
-^p5r^dU^F:^3RD*]tgttk2a20_WD'gs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(WiQgqXK8F':fSTaXFjDI;i@`Y!d4LD.qL4tJ#o_[:f(8pWE2nm@t>VMRjai/
->YnBAFC?DG-[mP<ISip@OK>2WJASAl]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/WnJ(Zg=k1tAo&iag8AUrBsHCG"-rl>.tKTWU"\4HAnGu7eo,/4I\S-^`&#Ee
-FCo;:PC"jV0q^DITP%kO\(]..UVb^hir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGWoapjk2t]HCiUu#k-/`>Dn>)n".fGR.u62fWoiGpCi"7UicT'RKrcT$cSj25
-HYd[ORt<;q1oNCbWGQHj_<0JPXMX*(li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(WiQY%SZJogQ_9kBXK7nXSc5\kR&0e`/"DrmU9(GoQ^=PMXJD2LVkTNPXIuSp
-VO*pHTUhFGQ_g%JXI5EHXK4cgVo#M>]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/WnIngaP,@p^rsaAg=jK\`r=Zm^s`59/&oB?c.^n#^qe@Og<dXNeBYkSg<8.&
-d_NuGb/_<F^sTsLg;:YHg=fPAe&'fCir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGWoab#e)ofJbLY(mk2t"5dJi8/bME0[/()P`g#hGSbKJ]'k1e)&i7Z<,k1A\V
-hTOEte^DXrbM:;#k0;)uk2ofchnnL[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(WiQ5fOi4=$IDDog]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/WnIKh\A[)$T"s%air@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGWoa?)_SkR:VnhF!li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZR.u!JQNiX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/J_JE'!N<?]g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGJ`b8?!OBDqjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(PcOpNX?Z*R!IAeVX9)ZSK)VhQ:*5kpX9XGkIVu6gW]o:@#.j6SeVDWDqpbql
-KCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/PhH18g/.1j!Lf,?g&cFOV#K'L@jf(`g'=U/T8VFWfM:;W#3,[>g4n&Hqq;:u
-JaVg;nC^*X~>
-#$LBV\^d1YJ`_OGPi`$Ik#Lg2!Mc%PjoTreXo@GaBdq6sjp/2KW0?B+j&=gs#4)<BeVDWDqpbql
-KCA!=nCg3Z~>
-#$LBV\^c7gJZOF(PcOpKX??K`+HAQh@B67f4DV!A9lW:AXK4'&4Gp574-Oe_X/g"u4Jr+Z!GI#^
-X8u1bri?Tb4CbFn=)FBgRB2'PHu/e`!'K,>#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/PhH14g._M"+LFgbI+ctB9ShAg@ZO3Og=eVC9X!0q9=g?ug"D0T9[j!p!J@0G
-g&Yg$rn7j_9Rb[KDi2J,_:kf:SV[:!!)28'#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGPi`$Dk"u'>+ML["K&tic:lj_1B9uGik2nlb:q5Z@:W/c<jlMP":u;36!K4&X
-joK;@roO]u:ke#nFct$HbiZ-aVNCf>!)VP7#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(PcP^4XCSE6M-d9B(6qauXF4lc.<hjdSZI'TrN$K;:ii%LCON:c;4"AcBRp&_
-'2b*tXG(,bKO_*Q0j(MfXHJ$mKDqqQ@>EaA#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/PhHt(g4.i1Y'A[**5-"=g7F,S1mcp'`nHf?rRqa.AWjotLn<>SB><0SK;8D!
-'5#&6g8TMSW.*I=5&]/)g:Er`VZ,9MHE?#X#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGPi`g;k(`$\\:3SP*lr0[k,4:&2kT5DdH7*frT4TACRWJ?O/M.&D9:r&Mlcm>
-'5YhRk-B[&Z%_>d6?VFFk/=74YQ!YbJ[OCt#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(O/rOZS#i]MEH_>_#s>:OXK5'cXE\^_X8uaAri?)^ri?9IENH6TJGlPX;4"Ac
-5rq+j,-77mUA(_i=c_IA#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/O4jeH`S0%NO-]e!#u'&Hg=foRg6dp!g&ZPPrn7?Grn7OBO4r<?U]&mTB#*-S
-;b9YV/)%p1c1fomEOF]X#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGO6-XYd,sK&Q_+3=#uKb\k2p7&k+J%=joL'jroO2WroOBVQfdFgXSq8iCs(o&
-=A;Ug/`tANf_=M/GJE%t#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(O/s4?Ff_ZoM-m?cN`rMHXK5'cXE\]cI]TVZL]4@]>)o\c?\tkcBRp&_$W37l
-XDN<cXF@7?:%kXg4T)8]EK'"\#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/O4kJ7PhOibXa&RRZuXkog=foRg6doST\A+HX8^fZEjXQSGcocSK;8D!$YI3.
-g5;ESg7[0<@eSLU9`3TFO0[m$#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGO6.=KSEAt6[t!Q&^3Jd:k2p7&k+J%&WTN>p[/T1oGeW>&J%+S&Mlcm>$Z*uJ
-k)lM&k,ILhBD1Hf;#KGVQb2AA#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(NiY-\4?R>ZN''4+UN[i(PU'81T2[pjXJ.."Eic@;>!+p+XK5\X0l="n:*hiH
-XK68$4E.B#,u"'7!'L4]!i$]HjfAZtmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/NnQCT9MC/oZ:mr4cBfuF]In$Sb%j\0g<MQ@OP8F6E_K03g=g^/5)\.K@kU9B
-g=hEX9TIhA/n"G-!)3@F!m`'Ajk9pus5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGNoi6h:f*,5]MMFLfq0dd`\;GqeT"ELk1M[]R-*PbGYh5Kk2q(Q6B^KnBei8W
-k2qh':mL0^0kU1B!)WXV!nnoUjlQd5s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZR.u!K^F^X8u@$jK&Qsmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/J_JE'!OctGg&Z&+jOsgts5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGJ`b8?!PimWjoKOBjQ6[4s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZR.u!M?+bX9"fgjK&Qsmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/J_JE'!Qr[cg&].@jOsgts5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGJ`b8?!S,m%joNfcjQ6[4s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(R]HOV:&1k9V2LP=NJjm=Mi4")S;Wo=RZ!f4MjLNHP`(HhXK7J@WL/U;T`'cK
-V8TG>]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/Rb@eX@en_'dBL7:Z`r09Ycu!u`j!J:_m%;.YeSoG]<JNXg=j!>f>4]8bPeXF
-dDX`Cir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGRcXXnBDL[8h7CSf]Xm7d]"6/KdCR`fc+;HY]#j*s`k&b-k2sIjilepbfDW8\
-h8JF[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(S#c[R=?H>[.@_h;X@57PD-^FKQ\HW;XFD@PP[-DQXDp'gK<2.P25PXBOcU\k
->r7AUX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/S([qRDbBiZ.E+,&g/q&%MKO&Z^oAi_g7]t$]QHp%g5nX+VV9a;6dhJR\@*i/
-F[E1Jg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGS)sdhF\hhq.F:"7k$:gFOaMOub-W\*k,KrE`dCVFk*SVHYNFtb7bsmk_SIaM
-HptK^jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK3(Z4?R>YX(a[Y0!%]>7QcF,VPQEMX;O]FDg?8GE3-.:7''1PXHc_cX@[/T
-XK5icri?K^@]ZXnXK4OcP&cZ&X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+>S9MC/nfnE*n3ndqK=\PjLe'Ukag)4=PNL>`mNnW45<n_-$g:_4Sg0BE*
-g=gnSrn7a[I+m:Jg=f6S\WF;=g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC1g:f*/5jc!#453?Bf?;RujhVD$'jr%ciPbOD9Q0.5`>NT\Ek/_H&k$a:K
-k2q9&roOTpKBD;mk2oM&_jJ9Yjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK2q\XK4XbW'IGcIB8PeTr^BUX8kBXX9M@T;flqtG5eQR4KOTHX@o+cN`qWH
-XK5icri?E\@]ZXnXK4?O,/UDc]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+2Wg=fBRePY&STA$e?c.Ykjg&OhAg'1ugBp4L;QN#SK9\Qmog0_kRZuW`n
-g=gnSrn7[YI+m:Jg=f##/Ag*Fir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC%kk2o\&iDo%&Vrkiaf]H$0joA6Qjp#G-DjuuYT)Rj_;!,N:k%2s&]m7S:
-k2q9&roONnKBD;mk2o6C0#H`Tli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2qQ4?OCXXF!&lEibC)XK4P`X8kBXX9M@[email protected]]FC2)MB/i"4
-O/ucFXH6hE@]ZXnXK4LV=I5c#X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+2H9M?GVg71i1OkR<_g=f7"g&OhAg'2!)HtnV%QN#SZ9\S*5PBkj8K1AU)
-[G#u.g9u:,I+m:Jg=f3CE50Z9g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC%\:f&4lk+kgMRHDA.k2oM>joA6Qjp#GEK5[!AT)Rjn;!-eWRt'P^MG$c;
-^ZL-Tk.lMRKBD;mk2oIjG08LVjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK2ppXGn'qWG&B74KOZHXK4P`X8kBXX=R&7X9ig2;QQsKC94Lp:QVZZ4KPW\
-6`a^OXH$J=@]ZXnXK4OcXC-jcQp@:bX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+1Yg9VjNf7_l39\R!og=f7"g&OhAg+6[Og'`kRB\M14LYCIdA[^=H9\S4J
-<SDf#g9bn#I+m:Jg=f6Sg3TjS_,8=qg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC$ik.Mnrj,<'^;!,W:k2oM>joA6Qjt(,kjp[KrD<BuZNooK8C;Auo;!-oq
->3:FDk.Z,IKBD;mk2oM&k('o&bZ<98jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK3+r4Bc0$WB!('O/u2>Rr168N''*bqQ('i3`rJ=K<1n34DLqrX<(cNXCsUV
-Kfh@X3]fGcFfT7>4Jf-43BTDbPcSO>T#du;]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+Ar9QPQ,f1AY0[G#4a`Jd?\YtR\bqUu=j8T3=`VV9Ek9S_=#g)bRog4W!j
-WD#lW8kViNPhCgc9[VRm85)]L]@qoaaN3'>ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC53:jIYDi_<6G^ZK?,d$.5']221$qW81+9m,U*YNFY;:laZ:jrT*9k)2o0
-Z;=7l:/=\^SE5c-:u(3<9MeP\`TE+,e&^YUli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(Q)sk^f;o!0OiOO-]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/Q.l/e!8#iV!CF<:g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGQ0/#'!92Vm!CaoHjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(QE1(^r'(0^S#ch*map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/QJ)>cr(mB1S(\)+s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGQKA2%r)E`<S)sq@s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(RB-CbP,nl!map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/RG%YgP1g-"s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGRH=M)P3)u7s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(R]HO>48Gs'SRm#HBk=?EAS$OrMIh[HKOp73AU^_^G\(HAXK6;NVL`<CPPo%m
-S]%T6]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/Rb@e99DR9ea+0N1Kn.k.J:OQOYCNh1W.;@lJ=kQLR"0^fg=hL9e"_H*])@-Z
-a2H[9ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGRcXXN:\j,udYFIWN/-NTLPN+r\VI]WZ%p0;LT'@tTSJ<1k2qk_hQ2LP`VkPl
-d_t8Pli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK3)6R@0nQXJM>QS#i0US=-CYN+kBLX=9o*1SnDWV-JY*A;?O)R&lQ*S=k'l
-VQ>eMAs]U#CJ(Ri/tSUdK7caO`2j0Smap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/XP+?;_SX^Sg<mdS`S/AX`kpB^Z%YjHg*t??5gadkdWD@`J#gCH_:lR``QFKF
-e(V-7K"p$nLgJZD3loB'VP[V"`7bFTs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGXQC2Sc->),k2";,d,rd1dEU_6]8TP]jsf%[7,362h0Q9.L:#/fbN?i.d++aj
-hWDL]M94oBO(7.e4k%kCYHMED`9%9is4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(XK2qB:/4okW`W"k-EL0";,2'/X8kBXX9M@;B6eE8G5eQR4KN"HXFOucX?:HH
-XK5icri?K^@]ZXnXK4OcH%VL&X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+25@q0H0fPb800\U;)An-i"g&OhAg'1uGK:.[[QN#SK9\Olog7j8Sg.[Nn
-g=gnSrn7a[I+m:Jg=f6SRARg=g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC%HBk_bOjE>6O1Zi[ACh]16joA6Qjp#F`MP??&T)Rj_;!*D:k,XF&k"qA:
-k2q9&roOTpKBD;mk2oM&U9DeZjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK2qoP*.`%WCN,7OK=R6VlW#[X8kBXX9M@^9QG&kG5eQ_4KO`KUJIM`JlROj
-XK5icXJ__G@]ZXnXK4<B+2Y)`]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+2n\[b,YeloVp[bA5neCmUqg&OhAg'1us@$$>/QN#SX9\R*tc=G&NV/*).
-g=gnSg=49FI+m:Jg=eth.)O[Bir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC&/_o#%(iEjF>^uiL>hr[c7joA6Qjp#G9AXJ^LT)Rjl;!,`?g1f(!Y&UdJ
-k2q9&k2=drKBD;mk2o63.`1<Pli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2q><`U?AXGg1\@'#JlXK4P`X8kBXX9M@fGW]naG5eQK4KPV_E+,iL>5hP8
-GcY>/XH$J=@]ZXnXK4OcFG?7&X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+21D/C]Og9PR4H.ocGg=f7"g&OhAg'2!)R8&X%QN#SD9\S37NdKL6ErKng
-R+cnfg9bn#I+m:Jg=f6SPH)O=g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC%DF)rhik.>\UJEF^jk2oM>joA6Qjp#GETi%&AT)RjX;!-nYQ@\2\GlDas
-T]Uj5k.Z,IKBD;mk2oM&S$UDYjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK3+.MKBVsWC2W$9!!A/VjT61U5CX_qQ)9F4b]sZDkgKnMJ7[DXIhnSXHtVu
-TS,4\:2Gf.>)lmGMG^IJ0T(`^Loc^WR`MQ7]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+@pYEKs:elJuX?J:oOeA=AjcEBC8qV!OK:8uqpN6cOJYD&h,g<!C>g;#kT
-bG[h4@u7CNEjKqmY@cM34g2%uXP10-`5pX:ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC4,\XOYYiENk'A*0Unhp"F9fssAZqW9Bc;R5F7PhLAm\W!]Rk1!Vek0$$#
-f!.cVBT]imH+eX:\SUEZ5e4F<[cYFOcH,,Pli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2Sn??CO<Wr?<4R][email protected]!Rd)qQ($o??*'3OK>Ef?@VpT#'m;OI9p6B
-qHaD^XFOV`WN;3[?3He":bnfeX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP*ipGE\M_f`$(&_qKulbG9?f]m"[HqUu:qGECOl\(]DWGG4uh#+=3!Sp,Cf
-qKE1Fg7ie8f%RV3G6Gn=AO"J]g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQB]2I@I%*jSjQ8c/t.:f<'J5aF/JeqW8.3I@00;_<0a*IB*8.#,:8BVgX!1
-qL&UUk,NiXio\)UI0@pZC.$[qjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(QE1(cr.>!-f;o!PUW9G?]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/QJ)>ir1sCtf@g7?cc=`Dir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGQKA2,r3$+3fB**Qg;i=[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(QE1(ar+,kMS#ch*map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/QJ)>fr."d2S(\)+s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGQKA2)r.k?BS)sq@s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(RB-CIP,nl!map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/RG%YGP1g-"s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGRH=L]P3)u7s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(R]HO&3r,j&Ps8HR76diO5<j%eGX$DRDa/f25@ppt><b>nXK5,\UM2rJLAa=:
-Q,Ka.]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/Rb@do9)70d]hie(=&@T#:f*)(R8B7(N)6=S:k79RFAPesg=g"4c@o)qWVoWn
-]u8V/ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGRcXX-:AO#taAdHI>ZBhD<)f(DTi@]IPZ4cr</9VuH;mk4k2p;Ug5T(=Zi*i'
-a2I*Eli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK3),F*!\LXI"!LHE;RWHul0dN.F+eX=:2C6Bub3R8Kr_H>]`EWiW3^X/gnJ
-S#iVsKW;,TKOCm]40,DDWMs3[`2j0Smap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/XP+?0P*3T6g:rf6RbFFCSW_IUZ(t(hg*t]^<5"WU_IqHNRu>okf\4tMf\*03
-`7iggW7]hXVg@(L9%hlif%,&H`7bFTs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGXQC2GR[VC]k/s-]UZSPkV4-9']<+p*jsfD&=NI+sb\Z:uUQab7jQ>N!jQ3UY
-cfX8;Z/k'0Z%1us:Z^\6io5Eq`9%9is4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(XK2q5F`gHZWD7SY19>=6Cirq\X8kBXX9M@<ApJ<7G5eQR4KNXHXD30bX$(KH
-XK5icri?K^@]ZXnXK4O_?^.5%X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+2%Pa#\0f41&05MCuAM3N&[g&OhAg'1uIJshRZQN#SK9\P\og4u<SfM7No
-g=gnSrn7a[I+m:Jg=f6MGe;/;g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC%7S=F9Qib=pQ6KXFZOdp^rjoA6Qjp#FaM5$6%T)Rj_;!+7:k)QD&jAMA:
-k2q9&roOTpKBD;mk2oLuJ&U!Wjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK2r'ChtMuWDIDISZIrTXK4P`X8kBXX9M@f7<!0bG5eQ_4KOuQQ;aNZGXcKt
-XK5icXJ(W.@]ZXnXK4?G+Mt2a]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+3*Lkmh:f4Khpa4e%@g=f7"g&OhAg'2!)=,r6$QN#SX9\RC%^1tsIQs#5$
-g=gnSg<?n'I+m:Jg=etn.DjdCir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC&@OH;?Yj(sg=dcSDgk2oM>joA6Qjp#GE>aCVAT)Rjl;!-&FaD]boTO*^<
-k2q9&k1@;QKBD;mk2o69/&LEQli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2q/I!I0>XHS$Z:ood\XK4P`X8kBXX=R&7O!\dgEic@?6*..jChBcM9mh>6
-@'!dlXH$J=@]ZXnXK4OcNHLDcWh?E6X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+1rSXD=bg:EiGA_OY3g=f7"g&OhAg+6[O[P3Z*OkSO<;VKiEM1OC7@@`sW
-HJ3_Hg9bn#I+m:Jg=f6SZBVoRf?;gfg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC%.VP6$.k/=-oCZ`KUk2oM>joA6Qjt(,k^bV.FRHEYh=6AXhObi/^Au;H"
-J`_Qkk.Z,IKBD;mk2oM&]Uct&j4<;4jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK3+>A6^("W$Ptb>-)0gTnO_PQXh=QqQ('q/8_IJDldV_A6>/sX<'L*XFMO+
-P@,bK3)4!^>*`9$A8&'.,@k=ELocR9QcQ64]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+A/Irus(eLuE%EnYn+c)<2$^jdneqUu=t3/ZE[N7rr7IrN.$g)`rAg7p3K
-\p6&\87R-`EkZIAItZOe/:W.>XP0r[^rY46ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC4AL3k/>iA-.BGijWHfWd*Eb(_R+qW8164-AYuPidmYL3CZ;jrR@]k,^4j
-`IKe"9PK6!H-(5aL5Y3408>3S[cY4&b/i]Lli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2T"KTD=ZX8[b[UTBE-VNun*TS.uPqQ(%"KT<.,SueuGKU)M;#*Q'hP_=^]
-qLf*AXHeHlWiVfjKES*P3_uZpX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP*j'VmX+Gg&@lWcJ#P$d_;WubGV8;qUu;&VmP1$aP,:EVnN&_#.`IA];MRJ
-qPOS8g:aD^f\4FFVZb?"8n?Gmg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQB]>YeS,njo2Ilg#foNhT2qJf!)BaqW8.>YeK8Ne)o_qYfH_)#/fTc`NZSq
-qQL4Kk/X^1jQ=qiYQW_C:28\-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(QE1(`r*05=f;nsk`iKBUmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/QJ)>fr,i!sf@g4b`nCXVs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGQKA2(r-SL-fB*'u`o[Kks4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(QE1(dr/1Q<S#ch*map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/QJ)>jr3674S(\)+s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGQKA2-r42mGS)sq@s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(RB-C0cE%"er2]m>rN$$pI/U,IR#(^B!fU-)ri?-NTDbhmF]FP&X8m>>X8m>?
-X9,A$>PtQ,]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/RG%Y(cIr8]r7V.6rRq:uSc.7C^o[Lg!jZX1rn7CJao0opP\df-g&R<6g&R<7
-g&flBFSshsir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGRH=L<cK5+qr8n!JrT4.7VZ#WXbI.<2!kWHGroO6_eG\M2S8l@DjoCkJjoCkK
-joXO^HMln0li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(S#c[c=??8Z/<qVIX>_f5OZYa3Uj",.XDK86MEFS6XB@,3Eic?0/Ycr)L4gj8
-4=lJnJS4q_!H!2_X9,A+NrH*]VG*``X9,/S8,fRjTLf$_!h<bBri?-Y?2^i*GB!P_!iqMBr2^+6
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/S([qgDbBiZ/A3i8g."3X\4fS>d$HDNg57PXY=r?Xg2T,>OP8Df3R371WMhID
-9K9B4UP&O!!K3HHg&flK[/Sb\dpUH"g&fR'>5m4Vb$=o!!lfYQrn7CWG5^+qQ]D(!!nk.Pr7VA7
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGS)se)F\_bp/B9YIk"7l"_GF'Vgn-?nk)qL#\PQo#k'&pWR-*O64P>TIZ`u8^
-:clAQXGZu=!Ks8XjoXRi^Ad6rhIbF>joX8H?N0'feRAF=!mu[kroO6mI/W1.TU,T>!p.Bkr8n4L
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(XK3)#9hgJGXGKYG=KGkX>>:inQB46(X:.d"L3[]r>cb#b?*$0fX9h"jXDV1%
-XK5icri?Ta@]ZXnXK4OcXC-jcNEc@_!HrM^X8u[brN$#jT`(qmTh#'_!'L1\!HWA^X9"\arN$$O
-B)J_14T)8b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+?$@UcLog9"gnDq]K.FCNPL^:-f2g'hD&WgSgNFkYQRG1oXhg'LI,g5L!Y
-g=gnSrn7j^I+m:Jg=f6Sg3TjSZ?6'!!L8fGg&ZH$rRq9VbPg,qbZau!!)3=E!Kr]Hg&]$$rRq:J
-K)F=&9`3TKir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC2;B4n^9k-nu9Fln4PH=tpnaMC^JjpYj=Z_E\rHfjJ%I-+9)jp=lHk*1))
-k2q9&roO]sKBD;mk2oM&k('o&]R'P=!M,YWjoKt@rT4,gf)=_3fO"O=!)WUU!LfPXjoN\@rT4-_
-M>ZK9;#KG[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2q>S!ugFW'm,E<31fqNLNB9X8kBXX9M@F?[$F.G5eQR4KO9GXAtIcT1ONH
-XK5icri?Wb@]ZXnXK4I64J\pWPZap`X9!rbrN$$?G5\KC@>Ff_!MN$^X8u+brN$$@FT/?CSPu?`
-X9+>eWr9"!4T)8b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+20`5G^-eQ9]-C>,[7ZG]lEg&OhAg'1uUGaFANQN#SK9\QLng2+@Sb$:Wo
-g=gnSrn7m_I+m:Jg=f,o:!hGE]Pu@!g&\($rRq:6Q2TD;H`R,!!R+aGg&Ya#rRq:8PlBA<a(`p"
-g&eR(fDXD'9`3TKir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC%Ccd,hTiEOXSE9=JT]['m_joA6Qjp#FnJ"MsmT)Rj_;!,-:k&SE&eR>J:
-k2q9&roO`tKBD;mk2oC?;;C-m`cp>>joMZ@rT4-JT)IdPJ[PI=!SC`WjoK5@rT4-LSGqXPdVmn>
-joW/Dj8J*?;#KG[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2qs7Re;pW`hk]PcU!KXK4P`X8kBXX9M@f7<!0bG5eQ_4KP2ULfgOUGV)B*
-XK5icXI=Kj@]ZXnXK4Bn.fQLNR9-3`X9"8brN$$KCAk47E-M8^!MN$^X8uRbrN$$@FT/?CTN.W`
-X9+SgW;Wdt4T)8b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+2s=BH`sfQ((r]@sc4g=f7"g&OhAg'2!)=,r6$QN#SX9\R[+X`2_BQoS7o
-g=gnSg;BG\I+m:Jg=f)L2?);2_J[^!g&\I$rRq:FLAfg,O-fh!!R+aGg&Z<$rRq:8PlBA<bA56!
-g&ej*ec"2%9`3TKir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC&4?!SZ5jEY$:`ob-[k2oM>joA6Qjp#GE>aCVAT)Rjl;!->L[W^NiTKQR-
-k2q9&k0Bg0KBD;mk2o<n3<&%Ac#h_>joN)@rT4-[NW%u?QD"3=!SC`WjoKhArT4-LSGqXPeoB4=
-joWJFiVhm=;#KG[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2ptU6I+*X,3RF5cg)LXK4P`X8kBXX=Hu6V@RTtAZVu!;66j9@<\fS5GFmB
-8ZZ?UXH$J=@]ZXnXK4OcVIYRcNEc@_!HrM^X8u[brN$#jT`(qmTh#'_!'L1\!HWA^X9"\arN$$O
-B)J_14T)8b]'e2#LXYJa]a(lrn)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+1^cFc!afr`QF;;/Ntg=f7"g&OhAg+-UNdh@\:JD/_lBA2'sH^<C>:sRA*
-?.sY+g9bn#I+m:Jg=f6SdXSISZ?6'!!L8fGg&ZH$rRq9VbPg,qbZau!!)3=E!Kr]Hg&]$$rRq:J
-K)F=&9`3TKir@lhL=5>`^^%8umcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC$nfu>u0jL<gq<T_/?k2oM>joA6Qjst&jh@u3XM!!jAD<BuDJtM2f<S?'P
[email protected],IKBD;mk2oM&hM/Q&]R'P=!M,YWjoKt@rT4,gf)=_3fO"O=!)WUU!LfPXjoN\@rT4-_
-M>ZK9;#KG[li5YgLXYJa]a(lrn)qLUg-U;~>
-#$LBV\^c7gJZOF(XK3+M5"mD6W#%W]C90uKS8]6nN'8"CqQ('i*)s":DleIQ5#\'PX;sF)XD&G6
-L-$59,;DA<>+SYV5(BYf(-Xo,LocS?rN$$CErE'??]"`_!D&m^X9#"brN#u]r2]p?FT/?BQr![^
-!J4q]X8kB\X9Q9(f@>Z*U%s<En)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+AC:LGu*eK%F]L>#o]`Jkh1Z;2E<qUu=j,APqEN7t"%:MIoLg)Wl@g4^JA
-WCn=//3ZiqEli#k:SHLA)c'6\XP0t%rRq:;Oo<u7Gcq#!!F*bGg&]E$rRq6Fr7V17PlBA;_.ET!
-!Mk>Fg&OhEg'6R:hV*_4TD=$AmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC4V;e7k<i?(usNTO\"d$5WO]2K_OqW81,-#i!_Pif#F;f:+ajrI:\k)CB[
-ZVM]B00rN)H.6b2;l\uc*E,lh[cY5KrT4-ORJl7KJ%,C=!FXLWjoO+@rT4)Vr8n$KSGqXOb\I+=
-!Nh4VjoA6Ujp(/Og!tl,U%s<En)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2T+WiE,#XT#7"XT,:'XK/A%X8]-pXT,:*XK/D'XK&;$rN$4(XK8J&WiPur
-#HOr,WiE/%X8T'uX9!<arN$$/LAn7UVHK2`X9,"kV#IFsQYT+jX9"AbrN$'U9m$B9!I8S]X9!'b
-ri?1$E\.-i"hO-ReVCX/dKTI0_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP*^.fDaD&gA]\0g"P*1g=b*2g&BV"g'ZNbf\5$3g=k01f_sM.f\5'3f@S^P
-f*C!_f[na/g=cGV"52CiQMoM<IB!5"!n2/&rn7FqB@-Y3!l'Oprn7C\E;eJlXC7@mg&[Y$rRq:-
-TDmOGfTA/kg'-L9hV*^ppsoWFlFuc@6%A~>
-#$LBV\^d1YJ`_OGXQBQFj8S*>k5OBHjlYXak2bRajo4<:jpL51jQ>Rck2t^ajSe3FjQ>Ucj5]7t
-is4].jQ#:_k2lR%"6J[4T)IdPK<tR>!oA.AroO:3D;5'P!m6R1roO6rGQ$Y*[:c$/joM3@rT4-@
-W;bo\jI&+-jot)Ng!tkepsK?AkJ6T@6@]~>
-#$LBV\^c7gJZOF(QE1(^r&asXf;nt/r2]mTrN$$tNr?$[T9]AV!gn.iri?-_V#@@rMKYHfX8n+T
-X8n+UX9,DFHMjiK]'e2#LUR6[rWi>Ko]O$Zg-U;~>
-#$LBV\D!1KJ_G\/QJ)>br(I*)f@g5,r7V.QrRq;$[/J\Zb.[c-!l:/,rn7C_ci)Q!Y*Hs)g&S8Q
-g&S8Rg&folRf(kDir@lhL:@3[rWi>Jo]j0[fg1,~>
-#$LBV\^d1YJ`_OGQKA2%r(mB3fB*(Br8n!grT4.<^A[0pe]@^[email protected]\p79\=LqEjoDmg
-joDmhjoXV7U\s6Yli5YgLUR6[rWi>Ko]O$Zg-U;~>
-#$LBV\^c7gJZOF(JZPiP#J0?TeVC*km/5B=P+hU4_!p&EJ,~>
-#$LBV\D!1KJ_G\/J_I*W#NGd?g4lZsn,1lEOe_[9^@9fAJ,~>
-#$LBV\^d1YJ`_OGJ``ro#ODECeVC*km/5B=P+hU4_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#eKHUeVC*Or7Cqu#e>u'p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W#ibm@g4lZYr7q;*#eQ),pZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro#j_NDeVC*Or7Cqu#e>u'p?06\g-U;~>
-#$LBV\^c7gJZOF(JZPiP'Y<_aeVC*:lgNBSd@?c@p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W']T/Lg4lZFm.&f`eXW5JpZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro'^PePeVC*:lgNBSd@?c@p?06\g-U;~>
-#$LBV\^c7gJZOF(JZPiP'Y<_aeVC*:ansrF`.kY4p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W']T/Lg4lZFc2?STaG%.@pZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro'^PePeVC*:ansrF`.kY4p?06\g-U;~>
-#$LBV\^c7gJZOF(JZPiP'Y<_aeVC*:^?k7;Q(Pb'p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W']T/Lg4lZF_sQpHQ(Z"2pZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro'^PePeVC*:^?k7;Q(Pb'p?06\g-U;~>
-#$LBV\^c7gJZOF(JZPiP'Y<_aeVC*:^!c\[N46L6p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W']T/Lg4lZF_UeLfMnHpDpZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro'^PePeVC*:^!c\[N46L6p?06\g-U;~>
-#$LBV\^c7gJZOF(JZPiP"hO-ReVC+&]`R5HT)QD,p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W"lfR=g4l[-_?/eLTDl\2pZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro"mc3AeVC+&]`R5HT)QD,p?06\g-U;~>
-#$LBV\^c7mJ\$EDJ\%hl"i]o]eVC+&]`Pp(Zi7WAp?06\g-U;~>
-#$LBV\D!1OJ`;7?J`<Zg"mH!Cg4l[,_?#G$rk\j5lFuc@6%A~>
-#$LBV\^d1[Ja7mQJa9<$"n2KEeVC+&]`Pp(Zi7WAp?06\g-U;~>
-#$LBV\^cVbJaS*WJaTH("4u(Y_#E<oi7%Ya"oIJunCg3Z~>
-#$LBV\D!M5JcC<$JcDYJ"5_ad_>`Krimdqf"oIT!nC^*X~>
-#$LBV\^dM:JcC<$JcDYJ"524[_#E<oi7%Ya"oIJunCg3Z~>
-"^19U\^f#Wf7DP)f;@1"eH*#Gp[eUK_!p&EJ,~>
-"^19U\D#JahLXO7hPT00g&\PMp\"aP^@9fAJ,~>
-"^19U\^f)Yfn%h-fr!I&eH*#Gp[eUK_!p&EJ,~>
-"'P'S\Ui:^eUc89eH<VVg-U;~>
-"'P'S\:N@bg4@tCg&o(Yfg1,~>
-"'P'S\Ui:^eUc89eH<VVg-U;~>
-"Bk0T\[-jBJVSf3V2#&Wo@3rYnCg3Z~>
-"Bk0T\@$mAJVAZ/V1eoUo@a;\nC^*X~>
-"Bk0T\[-jBJVSf3V2#&Wo@3rYnCg3Z~>
-"^19U\ZptdVuis:`duTidt,u\dfHr+q5=>0nFP04_!p&EJ,~>
-"^19U\?gtcWr^/ZJ^T+tJ^V3Z!P-VRWr^',o@a;\nC^*X~>
-"^19U\ZptdVuis:`duTidt,u\dfHr+q5=>0nFP04_!p&EJ,~>
-"\,r'Q*H8E]`lU<igB'-Jan<]JapMF#3_c/s8V!!r4N-jo^gT8S@G1AJ,~>
-"\?50Qa;SH_?J9GigK31Jb"B_Jb$SH#3hc2s8V*(r5&Kqp@Hu?T=ppKJ,~>
-"]3XiYHa#_]`lU<igB'-Jan<]JapMF#3_c/s8V!!r4N-jo^gT8[ahZ6J,~>
-"Y=h;>Hs+c]a2?fkP"SDR-X0keUc8%e\BW?]n=c4iqE',_#D"Jiq2im"(#V5&:a~>
-"YbLUA[@9n_?e&tl1anHR-jBog4@t/g:u>I^k()9jnJK3`;[USjS&3!")2jY&qB~>
-"[ff-U9TXU]a2?fkP"SDR-X0keUc8%e\BW?]n=c4iqE',_#D"Jiq2im"/W>h,_,~>
-&MS*3=0[[s]uo74nDDcgR-X0keUc8%e\BWD]n=c4e^`UJs5(l2iq2im"(?4P(Ou~>
-&N"lT@^Cs/_Tq0@o&JGrR-jBog4@t/g:u>N^k()9g=kWYs5;/=jS&3!")NI!)Lq~>
-&Oj7;U9TWi]uo74nDDcgR-X0keUc8%e\BWD]n=c4e^`UJs5(l2iq2im"/`]11k5~>
-&MS*3=0[Xmh!k!pf%&<CR-X0keUc8%e\BW:]n=c4rm_5(i:ZHji:QWk"(?4P(Ou~>
-&N"lT@^Cp)hXU@$gY1ARR-jBog4@t/g:u>D^k()9rn7S2jS%rqiqDut")NI!)Lq~>
-&Oj7;U9TTch!k!pf%&<CR-X0keUc8%e\BW:]n=c4rm_5(i:ZHji:QWk"/`]11k5~>
-#r$7+=0[LMLRbsSeH;G2lgB>SJ^o>%^XWG"[email protected]"feH96#=;QJ~>
-#rI$L@^CcZL7GpTg&mt7mI5\\J_G\/^Y/e*J_'hug'"^4LXc%hg&l/@Af?1~>
-#t;D3U9THCLRbsSeH;G2lgB>SJ^o>%^XWG"[email protected]"feH;\\W\f5~>
-&MS*3=0[[sZCHo>`mN>/R-X0keUc8%e\BWD]n=c4e^`'cQ&M<@iq2im"(?4P(Ou~>
-&N"lT@^Cs/[[iABb1>:=R-jBog4@t/g:u>N^k()9g=k)uQ&D9DjS&3!")NI!)Lq~>
-&Oj7;U9TWiZCHo>`mN>/R-X0keUc8%e\BWD]n=c4e^`'cQ&M<@iq2im"/`]11k5~>
-"Yah'=0[\_]a2'=Kq5fIR-X0keUc8%e\BWD]n=c4e[_3)T=;MIiq2im"(?4P(Ou~>
-"Z1UH@^Csk_?d`GKV#lLR-jBog4@t/g:u>N^k()9g:Nl/TY/.YjS&3!")NI!)Lq~>
-"\#u/U9TXU]a2'=Kq5fIR-X0keUc8%e\BWD]n=c4e[_3)T=;MIiq2im"/`]11k5~>
-"Yah'=0[\]]`tj6Nej(gl%-m+a+;:G`s8r'deo8gS[A@/!TNbCeH96#=;QJ~>
-"Z1UH@^Csi_?RK>NeWqgl@I-0bCRjOb6PG+f)1YiT"+a9!T`tGg&l/@Af?1~>
-"\#u/U9TXS]`tj6Nej(gl%-m+a+;:G`s8r'deo8gS[A@/!TNbCeH;\\W\f5~>
-"Yah'=0[\[]`b^9R-:H!K7SZ+K=up;dK-&Lqn3$io^gT8@<,HdJ,~>
-"Z1UH@^Csg_?@BDR-LN!JUrB'J\?U:f$U8'qn`Bpp@Hu?Ck$%8J,~>
-"\#u/U9TXQ]`b^9R-:H!K7SZ+K=up;dK-&Lqn3$io^gT8VRribJ,~>
-"Yah'=0\Rrp&X^]Ja\0YJa^8?!VuB`p&Y'_o@3qOE`a-.~>
-"Z1UH@^Dg(pAsg^JaS*WJaU2=!VuB`pAt0bo@a:_IqBUL~>
-"\#u/U9UNhp&X^]Ja\0YJa^8?!VuB`p&Y'_o@3r?];d]<~>
-"Yah'=2isGkCMfIkGIDBj7Ce'@<,HdJ,~>
-"Z1UH@`dJXl@J5OlDEhHk4@:/Ck$%8J,~>
-"\#u/U;bo=kCMfIkGIDBj7Ce'VRribJ,~>
-">+@t?X*>7!FD:I^k':P^oP6OVeGj6"*.mG4Fd~>
-">Y.?DJ&]\!GS0W^4F"L^8nsKWcRrO"+P>p5C`~>
-"@fN#Z)%2m!N!5U^k':P^oP6O^9.1-"1bh-;1J~>
-"<q2^@VPXY!GAron:C([n>l$Zc$K/*"(PdnVLS~>
-">"/)EHh5.!Hc#+n:C([n>l$Zd>%FG"*/B?VLS~>
-"@n9T[(#kC!OL=-n:C([n>l$ZiP,*!"1>LLVLS~>
-"#h>U:&%fk;5JitJ_G\/X4dTcAGB7/9eV%oJ,~>
-"%+Iq>52\1?E&M/J_>V-X4[NfEVO,J=uV$0J,~>
-"*$Y@RJ<c_UV_T9J_G\/X4dU%Z1t=$R:q<OJ,~>
-s"sg$)YY$J1P%lD6@hJ(630"`p_O#pVYgCD~>
-"%5L-+86ZR1k@rD6%M>&5liqdp_j6!VYgCD~>
-")i0L3qkH24b5qN6@hJ(630A2pbW(MVYgCD~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/megaco_filter.gif b/lib/et/doc/src/megaco_filter.gif
deleted file mode 100644
index bd03929b4c..0000000000
--- a/lib/et/doc/src/megaco_filter.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/megaco_filter.png b/lib/et/doc/src/megaco_filter.png
new file mode 100644
index 0000000000..cdea3a147e
--- /dev/null
+++ b/lib/et/doc/src/megaco_filter.png
Binary files differ
diff --git a/lib/et/doc/src/megaco_filter.ps b/lib/et/doc/src/megaco_filter.ps
deleted file mode 100644
index 19a1fc6bd1..0000000000
--- a/lib/et/doc/src/megaco_filter.ps
+++ /dev/null
@@ -1,1733 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/megaco_filter.ps
-%%CreationDate: Mon Oct 14 17:46:21 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 469 306
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 290.927657 translate
-453.947466 -290.927657 scale
-% Image geometry
-543 348 8
-% Transformation matrix
-[ 543 0 0 348 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 543 string def
-/gstr 543 string def
-/bstr 543 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 99787 ASCII Bytes
-colorimage
-!AQV60nB=U!.b-$!:0^c3<Coq0n9~>
-r'Z)9JH16$JH5$:r'Z&~>
-"DW"!C3+q+JH16$JH5$:r,[A~>
-r]0uYnc&U&JcC<$JcE7[!56GQrr<*T3B;T~>
-r^?bdnc&U'JcC<$JcE7[!5?MRrrE$dJ,~>
-rcA)>nc&U&JcC<$JcE7[!56GQrr<+8F)uj~>
-s"OQTs8VWG!53s6J^o>%\CCSma56ja!WXr0J,~>
-s$Qngs8VWC!5=$8J_#D'\CLYoa4gR]!WYVVJ,~>
-s)S5As8VWG!53s6J^o>%\CCSma56ja!W[:VJ,~>
-!]^8\n(n&XJ^o>%J^q9\!56A.!lY."J,~>
-!^m%gn(IcUJ_#D'J_%?^!5?G+!l=q*J,~>
-!cnAAn(n&XJ^o>%J^q9\!56A.!lY.\J,~>
-!\j]Tn(n&XJ^sYJ!6(hc!6'N>S(.MP`SL[8!',Q~>
-!^m%gn(IcUJ_'_L!QrigecEqAJ_$@B!5?G+!l=q*J,~>
-!cnAAn(n&XJ^sYJ!6(hc!6'N>S(.MP`SL[8!-<Y~>
-!<E/fh>k6dec1lieHNpfe\-<VrfmH5!J>a&eH3F2HiB90eH(;LnC7Q8]n+_AeH!;GhY3Q5hZ',E
-hZ',Dh>s\XJ,~>
-!<E/fg&Sjaf)LlgedTEhf"Q]`R?<W_eq&CUed9'AI@64[f%,D'nC@W6^4FkCec<GIg@q$.gAdT>
-gAdT=g&\>VJ,~>
-!<E/fh>k6dec1lieHNpfe\-<VrfmH5!J>a&eH3F2HiB90eH(;LnC7Q8]n+_AeH!;GhY3Q5hZ',E
-hZ',Dh>s\XJ,~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&iRItJ^$sPQ`P(Qes-2Bj&]K+(eVedneWc<KeUr5!e]#5.eI@F`
-`RU3;e^];!e^_XPo[O#MHc:Qd[abAkkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/tf)M08f)M0:ec<GVdK.4niR.bD[d_]G_RAaXs,l0d&]0+-dZ&[pcB47;dXcttd_`H!dLD1a
-`m0^/daE\tdaH"@o[3fLID19\[aG/ikLTBqp=B21s47.:rRM"P!.Y~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&iRItJ^$sPQ`P(Qes-2Bj&]K+(eVedneWc<KeUr5!e]#5.eI@F`
-`RU3;e^];!e^_XPo[O#MHc:Qd[abAkkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/uhYiuChYiuDh>k7]eH(;LiRIs]HgoPdK6tSf"cJVqeUr5GeHLSPe^];!Zdf)/Hi)=sK6u/!
-K7!4?!L/Lne[F!.^$"8HSG(h6SGh:FX8mb~>
-!<E/uf);$8f);$9ec<GVdf4mWdf4mfdf4m;dKPJmdaE\tqpPLqs3gpuZdSl)qpPLqs3gpuo?mZ)
-M1O*`dK%#Ef(YU+f(YU2ecDoRJ,~>
-!<E/uhYiuChYiuDh>k7]eH(;LiRIs]HgoPdK6tSf"cJVqeUr5GeHLSPe^];!Zdf)/Hi)=sK6u/!
-K7!4?!L/Lne[F!.^$"8HSG(h6SGh:FX8mb~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`VS*mXG_FPMp9eRMgLA`rmh%,"hfP8[+1uOHiM%o
-MgL)`e^]S9]n:[=eYN1ks2>,!H[CCYqUHs`HbIt[XFo&UHe$ZcMgL)`eZ=,:eXV!*eXWGc`J](q
-[+3]bMl_j8eHER4^"&YPHO.lKHe$Z!He"qkHiM%nMgL)`e^]S9XGbV]Hi)@nM\<^UHaL/4HaM>R
-`J](q[+3^GPl5qCe]!c"H],kneZ=[UH]-/!XG_F`XSC<GSGmj@c%CAneUr5!V#G`@`=7`PK='1Z
-Mi4Zpe\-=CJ^q6[!57RPpRLp5q4.B>!NZ9O~>
-!<E/uf)1s9f)1s8ec<G]dK[RNI>+uTU&KH?_YV[gY).RTM9=8LM1(5`rmLh+"hKD=ZI5HGIK..n
-OaVqhdaF,7\qP^@d\6Ygs2"o$JUN6\qU-aZICdkTV1m?KJ^Vu`OaVqhd].`4d[>O#d[?fW_NB8#
-ZI70\NMVX5dKI.0]$d#GI0duHJ^VttJ^U7kIK..mOaVqhdaF,7V2`oSJc!mqN=r[RJZcG8J[3_P
-_NB8#ZI71<Oo9\Bd`.E#I>tthd]SFTI>Q+pY).R`Y5$EFRJqU?b(5,ldXcttU&KK?_@;WUKsK.T
-NK'cod^FS8J^V$U!5@XIpR1^*q3h03!NlEQ~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`VS*mXG_FPMp9eRMgLA`rmh%,"hfP8[+1uOHiM%o
-MgL)`e^]S9]n:[=eYN1ks2>,!H[CCYqUHs`HbIt[XFo&UHe$ZcMgL)`eZ=,:eXV!*eXWGc`J](q
-[+3]bMl_j8eHER4^"&YPHO.lKHe$Z!He"qkHiM%nMgL)`e^]S9XGbV]Hi)@nM\<^UHaL/4HaM>R
-`J](q[+3^GPl5qCe]!c"H],kneZ=[UH]-/!XG_F`XSC<GSGmj@c%CAneUr5!V#G`@`=7`PK='1Z
-Mi4Zpe\-=CJ^q6[!57RPpRLp5q4.B>!NZ9O~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u1UjJ$,[%t[BH^)4.H`YK:K6rNHH\9S^H[EHFK7gk%
-Hc=6^H]+D@K?_A^HbI[^HaLJn^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifVP^CBo
-K6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO/q\M/S9oU@S9on5`IifV
-P^CBoK7h.fK6tkVXM(ufMp8&EMmTje`N4EN]p*lFq9:##H[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^
-H]+]E`I",+c*tpt^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/tdeB1.dK%#Zc3h^FKt<Ot`l<RX_YVP7V1"3+[]7?II?hO3IB(T<JUNBKI>,tdJUPDTJVC\#
-IE'Q`I>OYGL!I\hIDX9dIC?ku^A?,&[XFRhcAACCJUu+hJVC\#IE&jHWm6<HWm61(b(58XQ$pZt
-JUNBOrQZU\IE'RPJUPD\JUu+lJUu+dJUPDTJVC\#IE'Q`I>OfGM2D,T/qJG1Tm_?KTm_X?b(58X
-Q$pZpJVCtdKmh7\Y.h>mM9_rGM6aRi`i=HP^6O,Hq9C)%JUPD\JUu+lJUu+dJUPDTJVC\#IE'Q`
-I>OfG`dOP3cF;(!^?<oERJG82RInr)RJYD5XoNt~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u1UjJ$,[%t[BH^)4.H`YK:K6rNHH\9S^H[EHFK7gk%
-Hc=6^H]+D@K?_A^HbI[^HaLJn^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifVP^CBo
-K6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO/q\M/S9oU@S9on5`IifV
-P^CBoK7h.fK6tkVXM(ufMp8&EMmTje`N4EN]p*lFq9:##H[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^
-H]+]E`I",+c*tpt^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEq98tnHc>s..t`2fc,G$^c-:lf`Q`aVc-:lfc)c8^c)c8n
-c%CA^c$Of^c%CAfc&6q=^%]bsK6tkVHc=6^Hd/X=SB\-^XNc*V`I!6%]mJ#*H^r?^H`YJEHi)%g
-P^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%nK7!=:(k[1Sc$OfVc$Of^XF$J^XF%%MH^r@*K7!UB
-#K=B/K?]$q`Vn$cK6tS^`I!74bnu([c-:lfc-:lfc-:lfc)c8^c)c8nc%CBAblN0UJ^([K!57RG
-!1`l8!1`]3qjdQ6!NZ9O~>
-!<E/sdeT=/dK%#Zc3^Y%TusNdY0MTLq9B%qIDYs..uA\ocGk9hcH^uh`m0-dcH^ulcE;Shb-$/q
-c@LD`c@LPlc@LPlcA?t?_Y;@UJKr=OIDX9\J^1EHTusNdY0MH\`dNQ/_L9S0IA+fdIBLkHIEMK5
-!L8*4cMrIqcMrIqcMrIqcMrG'cE;Shb-$/qc@LDdpWaV,IEKidIEKidJ^1EHTusNdY-NJHcH_,l
-rltbc^4D!`Kmgi:c3B,R`m2SPM>5BrJcF$qJcF$qJcF$qJIBc+IA+fdIBLkHIEMQ7!I^5acF;(!
-^?<oERJG82RInr)RJYD5XoNt~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEq98tnHc>s..t`2fc,G$^c-:lf`Q`aVc-:lfc)c8^c)c8n
-c%CA^c$Of^c%CAfc&6q=^%]bsK6tkVHc=6^Hd/X=SB\-^XNc*V`I!6%]mJ#*H^r?^H`YJEHi)%g
-P^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%nK7!=:(k[1Sc$OfVc$Of^XF$J^XF%%MH^r@*K7!UB
-#K=B/K?]$q`Vn$cK6tS^`I!74bnu([c-:lfc-:lfc-:lfc)c8^c)c8nc%CBAblN0UJ^([K!57RG
-!1`l8!1`]3qjdQ6!NZ9O~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!F=s*O[gs*Oais*Odj$\NfNc%CAfc%CAfV#5QQUs4O=c-:lf
-c-:lfc-=4lH[C[aq998:H`W`qc-:lfc(t8a$`)%*K<1<%K<1!UV#5QAUs4O=qoo/+HiD8#K6tkf
-K6tkfK6tkfK6tk=r-JOAc%CB:bmT/Nc-:lfc-:lfc(t8as.g0PUs7/:Hd06VK8Y)/c$Og8c2W.i
-c2W.cbn#GRc-:lfc-:lfc-:lfc(t8a"/O1oHi;1iH^'*+\'4odr7(e\q4%Gup=0/5q:,J8p!rl.
-r7(hL!.Y~>
-!<E/rdefI0dK%#Zc2a^=I06=kJV!XBs*agj!J,[ucMr=mcMrIqcMrIqcMrFrcDCGe';a!*J^2Pl
-J^2PlJ^2QXQ$n(?^A6%]SUIZ3NR#h#J^1+iI1)msOb'ZtR>%Z#cDCGe"/X:oJc!^nQ$rYWs+13q
-s+13qs+13qs+(3rV>P`DV9XXCp<N\hs3CXqs3CXq!R@P>IK-,SIA+s3Kmh7XKn553L!G*pr6>=o
-IK%OlIJD+fJcF$qJcF$qJcF$qJH=&mr-\[Dc@LQFc2i?YJ^1aM!5ABZ!4quo!4qmP!1EZ2!1EN.
-q3h0/!NlEQ~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!F=s*O[gs*Oais*Odj$\NfNc%CAfc%CAfV#5QQUs4O=c-:lf
-c-:lfc-=4lH[C[aq998:H`W`qc-:lfc(t8a$`)%*K<1<%K<1!UV#5QAUs4O=qoo/+HiD8#K6tkf
-K6tkfK6tkfK6tk=r-JOAc%CB:bmT/Nc-:lfc-:lfc(t8as.g0PUs7/:Hd06VK8Y)/c$Og8c2W.i
-c2W.cbn#GRc-:lfc-:lfc-:lfc(t8a"/O1oHi;1iH^'*+\'4odr7(e\q4%Gup=0/5q:,J8p!rl.
-r7(hL!.Y~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!F=!eYj5rQQ+1Hc=7KH\9SfK6tkfK6tkfK6tkEH^t#Y$%mTL
-c%CAfc%CBAblbq\H\;.=%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?(8Q;rc-:lf
-c-:lfc-:lfc-:lfc)c8^r657pHhP\nK6tkfK6tkfK6tkEH^t&Z&Zg>Lc-:T^c&6qnc%CYnK6t<1
-bm&fI`QcAKKD<\'K6tkfK6tkfK6tkfK6tkEH^t#Y!J>aublYk2S:SqoblGHTeb>U-eGu-8eGu-5
-eb>U4eH)`OJ,~>
-!<E/qdf#U1dK%#Zc2t.sU&<49JbdRmKmg]6c5)7b`m2SPM9aCtJ^2PlJ^2PlJ^1EHU&<49JcF$q
-JcF$qJc3jr`h@g7q9BD[I>rfXcH^ulcE;Shr6>\DI>t)'I>srGY'm#AcMrImc5*+%`m2k\J^2Pl
-J^2PlJ^2PlJ^1EHU&<49JbIChJcF$qJcF$qJHO3#IA-Vb&[$PMcH:]dcAdCtc@pttKmg]6c3B,R
-`m2SPM>5BrJcF$qJcF$qJcF$qJHO3#IA-Sas+10p!lfY^J^1aM!5ABZpR1a'!1EZ2!1EQ/pR2!.
-!NlEQ~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!F=!eYj5rQQ+1Hc=7KH\9SfK6tkfK6tkfK6tkEH^t#Y$%mTL
-c%CAfc%CBAblbq\H\;.=%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?(8Q;rc-:lf
-c-:lfc-:lfc-:lfc)c8^r657pHhP\nK6tkfK6tkfK6tkEH^t&Z&Zg>Lc-:T^c&6qnc%CYnK6t<1
-bm&fI`QcAKKD<\'K6tkfK6tkfK6tkfK6tkEH^t#Y!J>aublYk2S:SqoblGHTeb>U-eGu-8eGu-5
-eb>U4eH)`OJ,~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMqTUjuH\8E5XMq8fPeE<.XNf"BHd0ffHd0ffHaLbEH_e$M
-[*=5Mc-:lfc-:lf[*>DR]sN-Eprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51c%CB?
-boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWnGK6tkfK6tkfK6tkfK6sE$XL,rn
-H_cRHHd.IqXK6bq]rZR5XM(^SXF$2FP^BM,bnu([c-:lfc-:lfc-:lf[)IZEUpR51c%CBBblY8!
-]n+G;blGHTeb>U-eGu-8eGu-5ebu$<ebu$:eH)`OJ,~>
-!<E/pcMs1*c2bTVapZ4CIAOBTZHA#P[`83e1obtXY-t@IWdU/DQ$oLOb(5,db(5,db)(PT_M*E7
-[]ZpYJUttdJUttdM1)hPTsDD<I>RaA,DCPo`lcGTJ]budIAOBTZHBV(IC?_8IC@;<Kmff+Y-Q3$
-Jc!S1\p^a(b(5,db(5,db(5,db)(PT_M*E7[]ZpYJV!gCs,$Wqs+13ms+13ms+)H<`eAi;[]ZpQ
-I=7fGI=97pIB';qID2_0Ks%ka_Q&$L\s7]?pr`Vfs2t@ms2t@ms2kb,IC@"HIAOBTZH@`LrlP;F
-IC=^L\&n]br6G&%p<EZ'q9Au*p<NW%s3CS.rQYGH!.Y~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMqTUjuH\8E5XMq8fPeE<.XNf"BHd0ffHd0ffHaLbEH_e$M
-[*=5Mc-:lfc-:lf[*>DR]sN-Eprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51c%CB?
-boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWnGK6tkfK6tkfK6tkfK6sE$XL,rn
-H_cRHHd.IqXK6bq]rZR5XM(^SXF$2FP^BM,bnu([c-:lfc-:lfc-:lf[)IZEUpR51c%CBBblY8!
-]n+G;blGHTeb>U-eGu-8eGu-5ebu$<ebu$:eH)`OJ,~>
-!<E/feH!;[bmMFSH[CCHc*W+M^&#t]XG_FPMoErBK6r6Prll^@Hd0ffHd0gBK6t;NP^@b0XNcBE
-c-:lfc-<VJHbGYrH[D!rprrl9H^+NS&VGGTc,GooH\8EEc$Of^c$Og:bm;:QH[CCHc%CB>c2W_%
-bnu([c-:lfc-:lfc-<VJHbIC_H[CCHc%CBBblNHDqop^FHd0ffHd0ffHd0gSP^@b0XNdi!K=$8X
-c*W+MS>:M%c)chMH],kfXFkkPXS9sVK6tkfK6tkfK6tkf["E_=`KY^rK<3=MHiD:iMh0-]blGHT
-eH!;YS,g7reb>U,ec20<ec20;eH)`OJ,~>
-!<E/fc2bTUapQ"NJUN6Tb-HSL])'PWWel.PM8%-/KmeZTrlY7ls2t@ms2l=eJUtDLQ%=@;Y0)<H
-b0#9db0%#@J\%+tI=[ZtprWZ3I?FNOs+13m)8_YiI>+iH`dN9Xb'e]Xb0%SdJUN6Tb(5-?b5[J$
-b5[%mb5[%mb5[%mapbS,J\&^`JUN6Tb(5-Cb5[%ib5[%mb5[%mb5[%mas"WeJUN6Tb-$;LZA!kP
-[Y9.#Tm`?OWel.PM8%-/KmeZTpWEMes2t@ms2t@ms2kbUJUtDLQ%=@;Y0)<HrlY8#J]bFD!5ABV
-!4M]g!4MUHpQbEss-<Q.s-<N-!NlEQ~>
-!<E/feH!;[bmMFSH[CCHc*W+M^&#t]XG_FPMoErBK6r6Prll^@Hd0ffHd0gBK6t;NP^@b0XNcBE
-c-:lfc-<VJHbGYrH[D!rprrl9H^+NS&VGGTc,GooH\8EEc$Of^c$Og:bm;:QH[CCHc%CB>c2W_%
-bnu([c-:lfc-:lfc-<VJHbIC_H[CCHc%CBBblNHDqop^FHd0ffHd0ffHd0gSP^@b0XNdi!K=$8X
-c*W+MS>:M%c)chMH],kfXFkkPXS9sVK6tkfK6tkfK6tkf["E_=`KY^rK<3=MHiD:iMh0-]blGHT
-eH!;YS,g7reb>U,ec20<ec20;eH)`OJ,~>
-!<E/feH!;Qc2)be^!4guHN:b0blYk:XMrEbH\:V.qKi4Uk03t/K>iDd[`nfc`74mi!.Y~>
-!<E/fc2bTKb5-Md]$8CoI/pk/ao]G2V8gXZ`dNR+b5-Md]&q-:We&$<b-oFm^;S:tXoNt~>
-!<E/feH!;Qc2)be^!4guHN:b0blYk:XMrEbH\:V.qKi4Uk03t/K>iDd[`nfc`74mi!.Y~>
-!<E/fblGG.`<+#lUrpX\[$7AfMgLu7`;udJJ]5%9!56=q!NZ9O~>
-!<E/faoK/,`WF/oTut@Z[ZRSiNI@M@`W;dIJ]>+;!5?Co!NlEQ~>
-!<E/fblGG.`<+#lUrpX\[$7AfMgLu7`;udJJ]5%9!56=q!NZ9O~>
-!<E/fblGG.`Q,q$]p+.rK;=(;J]7E'!56=q!NZ9O~>
-!<E/faoK/,`lH(&^6*tpKqX(;J]@K)!5?Co!NlEQ~>
-!<E/fblGG.`Q,q$]p+.rK;=(;J]7E'!56=q!NZ9O~>
-!<E/fblGG.`IZ!Z`ONke]u8.rX8mb~>
-!<E/faoK/,`du-\`jj"g^;S.pXoNt~>
-!<E/fblGG.`IZ!Z`ONke]u8.rX8mb~>
-!!%S&JV/N+JV3$9!!%N~>
-!!%S$JUrB'JUum5!!%N~>
-!!%S&JV/N+JV3$9!!%N~>
-!<E0!joD3.s+13$s+14<rro4uk2s>WJ,~>
-!<E0!joD*+s+13$s+14<rro+rk2s5TJ,~>
-!<E0!joD3.s+13$s+14<rro4uk2s>WJ,~>
-!<E0!joD3.s+13$s+14=rs"+Os5rIW!.Y~>
-!<E0!joD*+s+13$s+14=rs"%Js5rIT!.Y~>
-!<E0!joD3.s+13$s+14=rs"+Os5rIW!.Y~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[OeV)KQ
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:8G>!<1^P!!:jS!;tRN!:/A:!9Mr7!:SY;!!_-W!8?-,!.ijTg4\2[
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[OeV)KQ
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[OeV)KQ
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:8G>!<1^P!;Y@K!:8G>!<1^P!9W#8!:SYA!;bFL!<:dQ!.ijTg4\2[
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[OeV)KQ
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[OeX+hd
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*o%O*Drn@APs4[DO
-rn@;Ns4[JQ"53_TgAM$OgA_-Sg&M-DgA_0OgA_-Tg&M-,r;clOr;clOrr</T!!(aO!.ijTg6^On
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[OeX+hd
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%R+;4h"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)TDrW)oN
-rrE)Qrr<;X!!(a,!!(aL!<:dQ!!(aP!!:jS!;"qE!<(XO!"[c`!8?-,!8?-,!8?-,!8@8Ls4[JQ
-J_G\/R+hRk"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%R+;4h"f21\k.LbF~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc89ec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA1d\g&M-,!!(a,!!(^Q!8?-,!:\_A!<:dQ!<:dQ
-!;tRN!!(aP!<:dQ!;tRN!<:dQ!;"qB!#!uc!87DQg=cN,g=cN,g=cN,gAV*PgAV)'g4@tCgAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc89ec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^p+;s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo@j3Ern@AP$JGI[g&M-,g&M-,qZ-*=rVurPqZ-ZMqu?fP
-!!*#PrrDuNrrE)QrrDZErrE#Orr<>Y!!(a,!!(a,qZ$]O!!)rNrW%N'J_HIEs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^p+;s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^p.<s+:KN
-s5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQn(RdArn@AP%,([]g&M-,g&M-,!!)KArrE&Prr<,S!!)rN
-rrE)Qrr<,S!!*#PrrDuNrrE)QrrDZErrE#Orr<D[!!(a,!!(a,!!)rNrrDrMrW%N'J_HLFs+(?I
-s5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^p.<s+:KN
-s5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc8<ec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)WErrE&P
-rr<Va!!(a,!!(^Q!8?-,!87DQrn@APs4[JQ#20%Wg=cN,o@j3ErS%8O#MK.Xg=cN,gAV*PgA_-S
-g&M-PgA_0QgA_/(g4@tFgAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc8<ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%Qdu+g"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*n_3m@rn@;Nrn@>O
-!8@AOrS%2Ms4[JQs4[JQo@j3ErS%8O!nmVSrn@APs4[DOs4[JQrS%2MJ_G\/QeMIj"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%Qdu+g"f21\k.LbF~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g4@uGg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eUl?>K*Kl%s5rIW!.Y~>
-!<E0!joD*+g4@t/g4J&HJHji%s5rIT!.Y~>
-!<E0!joD3.eUc8%eUl?>K*Kl%s5rIW!.Y~>
-!<E0!joV@/eU_IdC4U,TCAucPK*VG,V#TT>]`<Q~>
-!<E0!joV71g4=g+JUrB-Jc=BlJHu5/U&X9;\c@6~>
-!<E0!joV@/eU`X0Mh-eAMuM8qK*VG,V#TT>]`<Q~>
-!<E0!joV@/eU_IdC4U,UC&m]$ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!joV71g4=g+JUrB.JH5`LgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!joV@/eU`X0Mh-eBMZEeVec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc!:bs+1$`s8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc*Cbs8RZI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMX8o@#!;rqs!.h5&XI60imf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g&Tk*!;tRL!.ijTg6p[ps8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:joFQB!;u!X!.j9`k*bB3s8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gPsq>gMrrW)hsquHbuquHAjquHYrq>^MsrW)r!rVur"q>^MsquH#`
-!!)u!!!*#"!!)u!!!%SOJZP<As6fm:s+C9`s8W,Ls+C6_s8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/qZ-TKq>gQLq>gNKrW)iLquHcNquHBCquHZKq>^NLrW)rOrVurPq>^NLquH$9
-!!)uO!!*#P!!)uO!!%T(J_HRHs8W)Ps+1-cs8W,Qs+1*bs8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@JqZ-TWq>gQXq>gNWrW)iXquHcZquHBOquHZWq>^NXrW)r[rVur\q>^NXquH$E
-!!)u[!!*#\!!)u[!!%T4J``E`s8W)Ks+C9`s8W,Ls+C6_s8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!#lq'.!3E7%XK2F"X8i7rX8i7tX8i7iX8i7rX8i8!X9/I(
-X8r1"!!*#"!!)u!!!*#"!!)5a!!)u!!!*#"!!)u!!!%SOJZP<As6fm:s+C9`s8W)Ks+C9`s8N;R
-V#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO#lr]5!8?-,g=cQ)g&M-Kg&M-Mg&M-Bg&M-Kg&M-Og&h?/
-g&V')!!*#P!!)uO!!*#P!!)6:!!)uO!!*#P!!)uO!!%T(J_HRHs8W)Ps+1-cs8W)Ps+1-cs8N;W
-U&X9;\c@6~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[#ls,M!9WDDk2l[Ajo>DWjo>DYjo>DNjo>DWjo>D[joYVG
-joG>A!!*#\!!)u[!!*#\!!)6F!!)u[!!*#\!!)u[!!%T4J``E`s8W)Ks+C9`s8W)Ks+C9`s8N;R
-V#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!#lq'.!3E7%XK2F#X9&C'!;`bs!;iht!:[&i!;W\r!<&u$
-!3E7%r2]kuri?)"rN#u!ri?)"poOJqo;holrN#u!ri?)"rN#u!JZOF(R]QPWrmh%$rk8@3rRLq#
-rOr72#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO#lr]5!8?-,g=cQ*g&_9.!;bCL!;kIM!:\\B!;Y=K!<(UR
-!8?-,r7V,Nrn7>PrRq5Orn7>PptG`Jo@a0ErRq5Orn7>PrRq5OJ_G\/RbIfArn@C'rke^8rS%:&
-rPJU7#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[#ls,M!9WDDk2l[BjoPPF!;bgX!;kmY!:]+N!;YaW!<)$^
-!9WDDr8mtZroO1\rT4([roO1\pu_SVoB$#QrT4([roO1\rT4([J`_OGRcaYMrmh%$rk8@3rRLq#
-rOr72#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;`bu!3?1sX8i7tX8i7iX8i7rX9/I(X8r1"!!*#"
-!!)u!!s#F(!;rnu!;NYq!:m5i!<&u!!<&u!!.h5&XI?6jmf(c:KDrRas8:FIKDrRars%#Ls5rIW
-!.Y~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;bCN!87GLg&M-Mg&M-Bg&M-Kg&h?/g&V')!!*#P
-!!)uO!s%'/!;tON!;P:J!:nkB!<(UO!<(UO!.ijTg7$aqs8LaPJc<Ods8:UNJc<Odrs%2Ns5rIT
-!.Y~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;bgZ!9O:Xjo>DYjo>DNjo>DWjoYVGjoG>A!!*#\
-!!)u[!s%KG!;tsZ!;P^V!:o:N!<)$[!<)$[!.j9`k*kH4s8LRKKDrRas8:FIKDrRars%#Ls5rIW
-!.Y~>
-!<E0!jp.^4eS8j#X8r1"!!*#"r;c\q!!)nt!!*#"!!)nt!!)nt!!)Mi!!)hrr;cbs!!*#"!!)u!
-r;cbs!!)5a!!)u!!!*#"!!)u!!!%SOJZP<As6fm:s+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V')!!*#Pr;c]J!!)oM!!*#P!!)oM!!)oM!!)NB!!)iKr;ccL!!*#P!!)uO
-r;ccL!!)6:!!)uO!!*#P!!)uO!!%T(J_HRHs8W)Ps+13es8VuMs+10ds8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG>A!!*#\r;c]V!!)oY!!*#\!!)oY!!)oY!!)NN!!)iWr;ccX!!*#\!!)u[
-r;ccX!!)6F!!)u[!!*#\!!)u[!!%T4J``E`s8W)Ks+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;ikq!;iht!;iht!<&u!!;3Dn!<&u!!<0&%!3E7%
-qlBi!X8r1"!s#F(!;rnu!<&u!!:?if!<&u!!<0&"!<&u!!.h5&XI?6jmf(c:KE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;kLJ!;kIM!;kIM!<(UO!;5%G!<(UO!<1[S!8?-,
-qq;)Og&V')!s%'/!;tON!<(UO!:AJ?!<(UO!<1[P!<(UO!.ijTg7$aqs8LaPJcEUes8(ILJcEUe
-rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;kpV!;kmY!;kmY!<)$[!;5IS!<)$[!<2*_!9WDD
-qrRq[joG>A!s%KG!;tsZ!<)$[!:AnK!<)$[!<2*\!<)$[!.j9`k*kH4s8LRKKE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)u!!W];%r2]kurN#u!ri?)"rN#u!mAp9frN#u!ri?)"rN#u!JZOF(R]QPWrmh%$!knX6
-q:5Lts1SI4#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)uO!W^pSr7V,NrRq5Orn7>PrRq5OmFhO?rRq5Orn7>PrRq5OJ_G\/RbIfArn@C'!lG!;
-q:bk"s2+g9#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)u[!W_?_r8mtZrT4([roO1\rT4([mH+BKrT4([roO1\rT4([J`_OGRcaYMrmh%$!knX6
-q:5Lts1SI4#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)qu!!)nt!!)u!!!*#"!!)u!!!)u!rrDYl!!)u!!!*#"!!)u!!!%SOJZP<As6fm:s+:Bd
-s8VlEs+:Wks8UWFs5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)rN!!)oM!!)uO!!*#P!!)uO!!)uOrrDZE!!)uO!!*#P!!)uO!!%T(J_HRHs8W)Ps+(6g
-s8VlJs+(Kns8UfHs5rIT!.Y~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)rZ!!)oY!!)u[!!*#\!!)u[!!)u[rrDZQ!!)u[!!*#\!!)u[!!%T4J``E`s8W)Ks+:Bd
-s8VlEs+:Wks8UWFs5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gMrquHbur;Zi!r;cl!quHbuq#L/jq#LGrq>gGp!!)quq>^Msq#LAp
-rrDVkr;cbsr;_DMJZP9@s6fm:s+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!joqI4g4=h/qZ-TKq>gNKquHcNr;ZiOr;clOquHcNq#L0Cq#LHKq>gHI!!)rNq>^NLq#LBI
-rrDWDr;ccLr;_E&J_HOGs8W)Ps+14MommFds8UfHs5rIT!.Y~>
-!<E0!joqR2eVf@JqZ-TWq>gNWquHcZr;Zi[r;cl[quHcZq#L0Oq#LHWq>gHU!!)rZq>^NXq#LBU
-rrDWPr;ccXr;_E2J``B_s8W)Ks+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCf*LKE(u%V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJb/mJJcGc(U&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCf*LKE(u%V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXGX(Z!.h5(XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g5=Sa!.ijVgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k)/:$!.j9bk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqR2eS8j#quHVqrW)ktqZ-Vsq>^MsquEau!!':*rW)/`!W];%r2fnuJZOL*s6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/quHWJrW)lMqZ-WLq>^NLquEbN!!':XrW)09!W^pSr7_/NJ_Gb1s8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@JquHWVrW)lYqZ-WXq>^NXquEbZ!!':drW)0E!W_?_r9""ZJ`_UIs8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7pX8i7tX8i8!X8i8"X8i8!X8i8"X8i7!X8i7(X8i7aX9&C'!<&u#!3?0O
-XFmVSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Ig&M-Mg&M-Og&M-Pg&M-Og&M-Pg&M,Og&M,Vg&M-:g&_9.!<(UQ!87F(
-g4S,Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DUjo>DYjo>D[jo>D\jo>D[jo>D\jo>C[jo>Cbjo>DFjoPPF!<)$]!9O94
-k(Dgrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&"!<&u!!<0&"!;NYq!48j*!<'#!!<9/#!<'"t
-!<0)"!!',"!;rqr!;3Gn!<9/#!;rqt!<0)"!!',"!;`bs!<'"u!<9/"!;*>o!3?1tX8i6OXFmVS
-mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[P!<(UO!<1[P!;P:J!4:JX!<(XO!<:dQ!<(XM
-!<1^P!!(aP!;tRK!;5(G!<:dQ!;tRM!<1^P!!(aP!;bCL!<(XN!<:dP!;+tH!87GMg&M,(g4S,Z
-s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*\!<)$[!<2*\!;P^V!4:nd!<)'[!<;3]!<)'Y
-!<2-\!!)0\!;u!W!;5LS!<;3]!;u!Y!<2-\!!)0\!;bgX!<)'Z!<;3\!;,CT!9O:Yjo>C4k(Dgr
-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&%!3E7%r2]kupoOJqZ`F-,q5ai%X8o?'!3E7%
-rN#u!riH,"ri?)"ri?)"rN#u!oW/2rX8o?'!<0&"!<0&"!<0)"!<0&"!;iht!;rnu!<&u!!;*Aj
-!;rnu!.h5(XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[S!8?-,r7V,NptG`JZe>BZq:Z)Sg&Tj\!8?-,
-rRq5Orn@APrn7>Prn7>PrRq5Oo\'HKg&Tj\!<1[P!<1[P!<1^P!<1[P!;kIM!;tON!<(UO!;,"C
-!;tON!.ijVgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*_!9WDDr8mtZpu_SVZfV5fq;qq_joFQ+!9WDD
-rT4([roX4\roO1\roO1\rT4([o]?;WjoFQ+!<2*\!<2*\!<2-\!<2*\!;kmY!;tsZ!<)$[!;,FO
-!;tsZ!.j9bk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i7rX8i8"X8i8!XS`(sXSi.sX8i7!X8i7rXT&:oX8i8"X8i8!X8i8"X8i7h
-XT&:tX8i7uX9/I(X8r1"!!)qu!!)qu!!)u!!!)Vl!W];%qlBbtJZOL*s6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Kg&M-Pg&M-OgACsLgAM$Lg&M,Og&M-KgA_0Hg&M-Pg&M-Og&M-Pg&M-A
-gA_0Mg&M-Ng&h?/g&V')!!)rN!!)rN!!)uO!!)WE!W^pSqq;#MJ_Gb1s8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!johL1eVf@bjo>DWjo>D\jo>D[k555Xk5>;Xjo>C[jo>DWk5PGTjo>D\jo>D[jo>D\jo>DM
-k5PGYjo>DZjoYVGjoG>A!!)rZ!!)rZ!!)u[!!)WQ!W_?_qrRkYJ`_UIs8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8"XS`(sX8i8!X8i8"X9/I(X8r1"!!)u!!!'.&!!)hr!!)hrquH_t
-!!)u!!!)u!r;cGj!!)ksq>gPs!!)qu!!)qu!!)nt!s#F(!;!;i!;rnu!.h5(XT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&M-PgACsLg&M-Og&M-Pg&h?/g&V')!!)uO!!'.T!!)iK!!)iKquH`M
-!!)uO!!)uOr;cHC!!)lLq>gQL!!)rN!!)rN!!)oM!s%'/!;"qB!;tON!.ijVgAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[jo>D\k555Xjo>D[jo>D\joYVGjoG>A!!)u[!!'.`!!)iW!!)iWquH`Y
-!!)u[!!)u[r;cHO!!)lXq>gQX!!)rZ!!)rZ!!)oY!s%KG!;#@N!;tsZ!.j9bk5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!'.&!!)hr!!)ks
-!!)u!!!*#"!!)u!!!)hr!!)Ym!!)ks!!)hr!!)qu!!)qu!!)nt!s#F(!:m2m!3?1tX8i6OXFmVS
-mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!'.T!!)iK!!)lL
-!!)uO!!*#P!!)uO!!)iK!!)ZF!!)lL!!)iK!!)rN!!)rN!!)oM!s%'/!:nhF!87GMg&M,(g4S,Z
-s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!'.`!!)iW!!)lX
-!!)u[!!*#\!!)u[!!)iW!!)ZR!!)lX!!)iW!!)rZ!!)rZ!!)oY!s%KG!:o7R!9O:Yjo>C4k(Dgr
-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)u!rrBC,!!*#"
-!!)u!!!)ks!!*#"rrE&"!!)u!!!*#"!!)u!!!)Ym!!)hr!!)u!"9>O)!!*#"!!)nt!!)ksrrDSj
-!W];%qlBbtJZOL*s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)uOrrBCZ!!*#P
-!!)uO!!)lL!!*#PrrE&P!!)uO!!*#P!!)uO!!)ZF!!)iK!!)uO"9@00!!*#P!!)oM!!)lLrrDTC
-!W^pSqq;#MJ_Gb1s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)u[rrBCf!!*#\
-!!)u[!!)lX!!*#\rrE&\!!)u[!!*#\!!)u[!!)ZR!!)iW!!)u["9@TH!!*#\!!)oY!!)lXrrDTO
-!W_?_qrRkYJ`_UIs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!joqR2eS8j#q#CDrr;Zi!r;Zi!qZ-Vsq>^Msq#LAprrB@+rW)nur;c_rrW!&%!!',"!<9/"
-!<9.u!;*Ak!;`eq!<0&#!3H/"r2ferqlBbtnZ2clX8r4#quD;LKrk=Brmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!joqI4g4=h/q#CEKr;ZiOr;ZiOqZ-WLq>^NLq#LBIrrB@YrW)oNr;c`KrW!&S!!(aP!<:dP
-!<:dN!;,"D!;bFJ!<1[Q!8@DPr7_&Kqq;#Mn_+$Eg&V**quD<%L"cS,rn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!joqR2eVf@Jq#CEWr;Zi[r;Zi[qZ-WXq>^NXq#LBUrrB@erW)oZr;c`WrW!&_!!)0\!<;3\
-!<;3Z!;,FP!;bjV!<2*]!9X7\r9!nWqrRkYn`BlQjoGABquD<1L$&F8rmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8iMXLYD4!:Hog!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g:>o;!:JP@!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k.0US!:JtL!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXLYD4!:Hog!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g:>o;!:JP@!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k.0US!:JtL!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXLbM3!:m5i!.h5&XQchdmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g:H#:!:nkB!.ijTg?I>ks8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k.9^R!:o:N!.j9`k3;%.s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMnsXSW"qXSi.uXSr5!XSr3`X8i7EX8i7rX8i6OXF[J0XT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1dLgA:mJgAM$NgAV*OgAV)9g&M,sg&M-Kg&M,(g4@u7gAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#&Xk5,/Vk5>;Zk5GA[k5G@Ejo>D*jo>DWjo>C4k(2[Ok5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!)u!!!*#"rrE&"rrA4`!!(6E!!)hr!!%SOJZR_0
-s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!)uO!!*#PrrE&PrrA59!!(6s!!)iK!!%T(J_Ju7
-s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!)u[!!*#\rrE&\rrA5E!!(7*!!)iW!!%T4J`bhO
-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!s#F(!;ii%!3E7%X8o@$!<'#!!33."!!95%!<0(u!<'"s
-!;iks!<0)!!<0)!!<9/!!<0)!!<9/"!;<Ml!<'"s!.h5&XPp8\mf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!s%'/!;kIS!8?-,g&Tk+!<(XO!34cP!!:jS!<1^N!<(XL
-!;kLL!<1^O!<1^O!<:dO!<1^O!<:dP!;>.E!<(XL!.ijTg>Uccs8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!s%KG!;km_!9WDDjoFQC!<)'[!352\!!;9_!<2-Z!<)'X
-!;kpX!<2-[!<2-[!<;3[!<2-[!<;3\!;>RQ!<)'X!.j9`k2GJ&s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8juX9/I(X8r4#!!)u!!s#F(!;ii(!3E7%X8o=%X8r4#rrB+$!!*#"rrE&"!!)u!
-!!)u!!!)hr!!*#"!!*#"!!)qu!s#F(!<&u!!<0&"!<&u!!;*>m!;W\r!.h5&XPU&Ymf(c:KE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&h?/g&V**!!)uO!s%'/!;kIV!8?-,g&Th,g&V**rrB+R!!*#PrrE&P!!)uO
-!!)uO!!)iK!!*#P!!*#P!!)rN!s%'/!<(UO!<1[P!<(UO!;+tF!;Y=K!.ijTg>:Q`s8LaPJcGcD
-gAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjoYVGjoGAB!!)u[!s%KG!;kmb!9WDDjoFNDjoGABrrB+^!!*#\rrE&\!!)u[
-!!)u[!!)iW!!*#\!!*#\!!)rZ!s%KG!<)$[!<2*\!<)$[!;,CR!;YaW!.j9`k2,8#s8LRKKE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juXSi.tX8i8"X8i8"X8i7tX9em.X8o?'!3E7%VQ9atr2]kuq5aPrrN#u!qQ'Ys
-r2^2)XK2E'X8o?'!;`bs!<0&"!<&u!!;*>m!;W\r!.h5&XPU&Ymf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hSgAM$Mg&M-Pg&M-Pg&M-Mg'Ic5g&Tj\!8?-,VV2"Mr7V,Nq:YfKrRq5OqUtoL
-r7VGWg=cP\g&Tj\!;bCL!<1[P!<(UO!;+tF!;Y=K!.ijTg>:Q`s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@bk5>;Yjo>D\jo>D\jo>DYjp;%MjoFQ+!9WDDVWIjYr8mtZq;qYWrT4([qW7bX
-r8n:ck2l[+joFQ+!;bgX!<2*\!<)$[!;,CR!;YaW!.j9`k2,8#s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8juX9/I(X8r4#r;cet!!)nt#lq'.!3E7%XK2E!X8i7uX8i8!XS`(sX8i7sXSMqs
-X9J[+X8o?'!<0(t!<&u$!3E7%o;holq5aPrJZOF(hQ6bFrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&h?/g&V**r;cfM!!)oM#lr]5!8?-,g=cP(g&M-Ng&M-OgACsLg&M-LgA1gL
-g'.Q2g&Tj\!<1^M!<(UR!8?-,o@a0Eq:YfKJ_G\/hV/#0rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjoYVGjoGABr;cfY!!)oY#ls,M!9WDDk2lZ@jo>DZjo>D[k555Xjo>DXk5#)X
-jothJjoFQ+!<2-Y!<)$^!9WDDoB$#Qq;qYWJ`_OGhWFk<rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7sX8i8"X8i8"X8i7tX9/I(X8r1"!!&mt!!)qu!!*#"!!)u!!!)u!!!)ks
-!!)eq"9>M'X8r7$!!)u!!!)u!!s#F(!;!8l!;W\r!.h5&XPU&Ymf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Pg&M-Pg&M-Mg&h?/g&V')!!&nM!!)rN!!*#P!!)uO!!)uO!!)lL
-!!)fJ"9@-Ug&V-+!!)uO!!)uO!s%'/!;"nE!;Y=K!.ijTg>:Q`s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@bjo>DXjo>D\jo>D\jo>DYjoYVGjoG>A!!&nY!!)rZ!!*#\!!)u[!!)u[!!)lX
-!!)fV"9@QajoGDC!!)u[!!)u[!s%KG!;#=Q!;YaW!.j9`k2,8#s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8juX8i7sX8i8!X8i8"X8i8!X8i8"X8i7uX8i8!XT&:$X8i8"XT&;"X8i8"XT&;!
-X8i8"X8i8!X8i8!X8i8"XT&8%X8i8"X8i8"XT&:uXT&:kX8i8"X8i8!X8i8"X8i6OXF[J4XT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Lg&M-Og&M-Pg&M-Og&M-Pg&M-Ng&M-OgA_/Rg&M-PgA_0Pg&M-PgA_0O
-g&M-Pg&M-Og&M-Og&M-PgA_-Sg&M-Pg&M-PgA_0NgA_0Dg&M-Pg&M-Og&M-Pg&M,(g4@u;gAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DXjo>D[jo>D\jo>D[jo>D\jo>DZjo>D[k5PF^jo>D\k5PG\jo>D\k5PG[
-jo>D\jo>D[jo>D[jo>D\k5PD_jo>D\jo>D\k5PGZk5PGPjo>D\jo>D[jo>D\jo>C4k(2[Sk5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSi.tXSr4uX8i8"XSi.uXSr5!XSr5!XT&:#XSr2#X8r4#rW!#$!!)u!rW)hs
-r;cetrr<,%!!)u!rW!#$!!)qu!!)PjrW)hsrW%MNJZRh3s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp%O5g4=h/gAM$MgAV*Ng&M-PgAM$NgAV*OgAV*OgA_/QgAV'Qg&V**rW!#R!!)uOrW)iL
-r;cfMrr<,S!!)uOrW!#R!!)rN!!)QCrW)iLrW%N'J_K):s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp%X3eVf@Jk5>;Yk5GAZjo>D\k5>;Zk5GA[k5GA[k5PF]k5G>]joGABrW!#^!!)u[rW)iX
-r;cfYrr<,_!!)u[rW!#^!!)rZ!!)QOrW)iXrW%N3J`bqRs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXSf."!7._H!.h5&XMh4?mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gAKY)!70@!!.ijTg;M_Fs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k5=?A!70d-!.j9`k/?E^s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXSo4#!7%YG!.h5&XMh4?mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gAT_*!7'9u!.ijTg;M_Fs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k5FEB!7'^,!.j9`k/?E^s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXSi.FXSi.tXS;dHXF[J$XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+gAM#tgAM$Mg@tZ!g4@u+gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k5>;+k5>;Yk4eq-k(2[Ck5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMqrXSi-MXS&Xp!9^H_!;iks!.h5&XNmpImf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!jp%O5g4=h/gA1gKgAM#&g@a/"!9`)8!;kLL!.ijTg<SFPs8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!jp%X3eVf@Jk5#)Wk5>:2k4Rj:!9`MD!;kpX!.j9`k0E,hs8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i6OXS/^q!9L9^!;W\r!.h5&XNmpImf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M,(g@j5#!9Mo7!;Y=K!.ijTg<SFPs8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>C4k4[p;!9N>C!;YaW!.j9`k0E,hs8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!jq"9<eS8j#X8o?'!3E7%X8r.!!!)u!rrACerVuu#!<0(u!<0)"!!',"!<'"s!<'#!!<9/#
-!<'"t!;`bs!;W\r!;`er!<'#!!<9/#!.h5&XQ$>]mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jq"0>g4=h/g&Tj\!8?-,g&V$(!!)uOrrAD>rVuuQ!<1^N!<1^P!!(aP!<(XL!<(XO!<:dQ
-!<(XM!;bCL!;Y=K!;bFK!<(XO!<:dQ!.ijTg>^ids8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jq"9<eVf@JjoFQ+!9WDDjoG;@!!)u[rrADJrVuu]!<2-Z!<2-\!!)0\!<)'X!<)'[!<;3]
-!<)'Y!;bgX!;YaW!;bjW!<)'[!<;3]!.j9`k2PP's8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i8!XT&9fX8i8"XT&;#X8i8!X8i8"XT&;"X8i8!X8i7rX9\g-
-!3E7%XK2F#X8i7tX8i7rX8i7tX8i8"X8i8!X9AU*!3E7%JZOF(j/i:Krmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M-OgA_/?g&M-PgA_0Qg&M-Og&M-PgA_0Pg&M-Og&M-Kg'@]4
-!8?-,g=cQ*g&M-Mg&M-Kg&M-Mg&M-Pg&M-Og'%K1!8?-,J_G\/j4aP5rn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>D[k5PFKjo>D\k5PG]jo>D[jo>D\k5PG\jo>D[jo>DWjp1tL
-!9WDDk2l[Bjo>DYjo>DWjo>DYjo>D\jo>D[jokbI!9WDDJ`_OGj6$CArmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX8i7uX9&C'!;ii"!3E7%rN#u!rN#u!q5jSrr2]kuqlBbt
-r2]kuq5aPrr2]kur2]kuriH,"JZOF(hlQkGrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g&M-Ng&_9.!;kIP!8?-,rRq5OrRq5Oq:biKr7V,Nqq;#M
-r7V,Nq:YfKr7V,Nr7V,Nrn@APJ_G\/hqJ,1rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjo>DZjoPPF!;km\!9WDDrT4([rT4([q<%\Wr8mtZqrRkY
-r8mtZq;qYWr8mtZr8mtZroX4\J`_OGhrat=rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX8i7sX8i7tX9/I(X8r4#!!)u!!!)hr!!)nt!!)nt!!)qu
-!!)hr!!)quq>gMr!!%SOJZR_0s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g&M-Lg&M-Mg&h?/g&V**!!)uO!!)iK!!)oM!!)oM!!)rN
-!!)iK!!)rNq>gNK!!%T(J_Ju7s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjo>DXjo>DYjoYVGjoGAB!!)u[!!)iW!!)oY!!)oY!!)rZ
-!!)iW!!)rZq>gNW!!%T4J`bhOs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX8i7sX8i7tX9/I(X8r4#!!)u!!!)hr!!)nt!!)nt!!)qu
-!!)hr!!)qu!!)eq!!%SOJZR_0s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g&M-Lg&M-Mg&h?/g&V**!!)uO!!)iK!!)oM!!)oM!!)rN
-!!)iK!!)rN!!)fJ!!%T(J_Ju7s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjo>DXjo>DYjoYVGjoGAB!!)u[!!)iW!!)oY!!)oY!!)rZ
-!!)iW!!)rZ!!)fV!!%T4J`bhOs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i7uXT&9fX8i8!X9/I(X8r4#!!*#"!!)u!!!)u!!!*#"!!)u!
-!!)ks!!)u!!!)nt!!)hr!!)nt!!)u!!!*#"!!%SOJZR_0s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-NgA_/?g&M-Og&h?/g&V**!!*#P!!)uO!!)uO!!*#P!!)uO
-!!)lL!!)uO!!)oM!!)iK!!)oM!!)uO!!*#P!!%T(J_Ju7s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>DZk5PFKjo>D[joYVGjoGAB!!*#\!!)u[!!)u[!!*#\!!)u[
-!!)lX!!)u[!!)oY!!)iW!!)oY!!)u[!!*#\!!%T4J`bhOs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXS`(sXSi.rXT&9eXSi.tXSi.uXSr5"XSr4uXSr4uXSi.rXSi.sXS`(sXS`(r
-XSi.uXSi-MXF[J2XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSgACsLgAM$KgA_/>gAM$MgAM$NgAV*PgAV*NgAV*NgAM$KgAM$LgACsLgACsK
-gAM$NgAM#&g4@u9gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bk555Xk5>;Wk5PFJk5>;Yk5>;Zk5GA\k5GAZk5GAZk5>;Wk5>;Xk555Xk555W
-k5>;Zk5>:2k(2[Qk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMX8o@#!;rqs!;rqs!;rqs!:m2k!;`eq!:m2k!;NYq!:m2k!;`ep!;*Ak!;rqs
-!;!;j!:m2k!;`eq!<'"r!;rqt!;`es!;rqs!.h68XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g&Tk*!;tRL!;tRL!;tRL!:nhD!;bFJ!:nhD!;P:J!:nhD!;bFI!;,"D!;tRL
-!;"qC!:nhD!;bFJ!<(XK!;tRM!;bFL!;tRL!.ikfgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:joFQB!;u!X!;u!X!;u!X!:o7P!;bjV!:o7P!;P^V!:o7P!;bjU!;,FP!;u!X
-!;#@O!:o7P!;bjV!<)'W!;u!Y!;bjX!;u!X!.j:rk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSMnsXSr5!XSr2"XSMnsXSr5"XSr5"XSMqjXSMqrXSr2#X8p>C!!)u!!!*#"
-!!)u!!!*#"!!)u!!!*#"!!)u!!!)YmrrDqt!!)u!!!)YmrrDkr!W];%o;qrlqQ'YsnZ2]jrN#u!
-ri?)"rN#u!orJ,nrN#u!oW8&mqlBbtrN#u!ri?)"rN#u!rN#u!poFMsX8r4#!!)u!!!%SOl)apQ
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gA1dLgAV*OgAV'PgA1dLgAV*PgAV*PgA1gCgA1gKgAV'Qg&T4J!!)uO!!*#P
-!!)uO!!*#P!!)uO!!*#P!!)uO!!)ZFrrDrM!!)uO!!)ZFrrDlK!W^pSo@j3EqUtoLn_*sCrRq5O
-rn7>PrRq5Op"BBGrRq5Oo\0<Fqq;#MrRq5Orn7>PrRq5OrRq5Opt>cLg&V**!!)uO!!%T(l.Z1;
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5#&Xk5GA[k5G>\k5#&Xk5GA\k5GA\k5#)Ok5#)Wk5G>]joEKb!!)u[!!*#\
-!!)u[!!*#\!!)u[!!*#\!!)u[!!)ZRrrDrY!!)u[!!)ZRrrDlW!W_?_oB-&QqW7bXn`BfOrT4([
-roO1\rT4([p#Z5SrT4([o]H/RqrRkYrT4([roO1\rT4([rT4([puVVXjoGAB!!)u[!!%T4l/r$G
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!"9>O)!!*#"!!*#""ota+!3E7%p8eQ#XK2E'
-X8o?'!<0)"!6D5A!<&u!!<0&"!<&u!!<0&"!<&u!!<0&"!<&u!!;3Dp!3?1tX8i8!X8i7nX9&C'
-!;W\t!3?1mX9&C'!;`bs!:6ce!;W\r!;3Dn!<&u!!;3Dp!3?1tX8i8!X8i7rX8i8"X8i7pX9&C'
-!<&u!!<&u!!.h69XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO"9@00!!*#P!!*#P"p!B2!8?-,p=]fQg=cP\
-g&Tj\!<1^P!6Ejo!<(UO!<1[P!<(UO!<1[P!<(UO!<1[P!<(UO!;5%I!87GMg&M-Og&M-Gg&_9.
-!;Y=M!87GFg&_9.!;bCL!:8D>!;Y=K!;5%G!<(UO!;5%I!87GMg&M-Og&M-Kg&M-Pg&M-Ig&_9.
-!<(UO!<(UO!.ikggAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u["9@TH!!*#\!!*#\"p!fJ!9WDDp>uY]k2l[+
-joFQ+!<2-\!6F:&!<)$[!<2*\!<)$[!<2*\!<)$[!<2*\!<)$[!;5IU!9O:Yjo>D[jo>DSjoPPF
-!;YaY!9O:RjoPPF!;bgX!:8hJ!;YaW!;5IS!<)$[!;5IU!9O:Yjo>D[jo>DWjo>D\jo>DUjoPPF
-!<)$[!<)$[!.j:sk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!#QUs-!3?1%X8r7$"ota+!3E7%p8eQ#XK2E'
-X8o?'!<&u!!;rqu!6VAC!<0&"!<&u!!<0&"!<&u!!;W\r!;!8l!;iht!<&u!!;!8l!;`c!!3E7%
-nuMfkqQ'Ysm&U0eq5aProrJ,nrN#u!o;holqlBbtrN#u!qQ'YsrN#u!poFPtXK2EsX8i6OXQchd
-mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO#QWT4!87G,g&V-+"p!B2!8?-,p=]fQg=cP\
-g&Tj\!<(UO!;tRN!6X!q!<1[P!<(UO!<1[P!<(UO!;Y=K!;"nE!;kIM!<(UO!;"nE!;bCO!8?-,
-o%F'DqUtoLm+MF>q:YfKp"BBGrRq5Oo@a0Eqq;#MrRq5OqUtoLrRq5Opt>fMg=cQ%g&M,(g?I>k
-s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[#QX#L!9O:DjoGDC"p!fJ!9WDDp>uY]k2l[+
-joFQ+!<)$[!;u!Z!6XF(!<2*\!<)$[!<2*\!<)$[!;YaW!;#=Q!;kmY!<)$[!;#=Q!;bg[!9WDD
-o&]oPqW7bXm,e9Jq;qYWp#Z5SrT4([oB$#QqrRkYrT4([qW7bXrT4([puVYYk2l[=jo>C4k3;%.
-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX9/I(X8r1"!!*#"!!)u!!s#F(!<&u&!3?1%X8r.!!!)Mi!!)qu!!)bprrC6D
-!!)u!!!)u!!!*#"!!)u!!!)ks!!)Sk!!)nt!!)u!!!)Vl!!)ks!s#F(!:m2k!;`eq!:m5j!;iks
-!;*>m!<&u!!;!8l!;iht!<&u!!;`bs!<&u"!3H/"r2]u#XK2EtX8i6OXQZbcmf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&h?/g&V')!!*#P!!)uO!s%'/!<(UT!87G,g&V$(!!)NB!!)rN!!)cIrrC6r
-!!)uO!!)uO!!*#P!!)uO!!)lL!!)TD!!)oM!!)uO!!)WE!!)lL!s%'/!:nhD!;bFJ!:nkC!;kLL
-!;+tF!<(UO!;"nE!;kIM!<(UO!;bCL!<(UP!8@DPr7V5Qg=cQ&g&M,(g?@8js8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjoYVGjoG>A!!*#\!!)u[!s%KG!<)$`!9O:DjoG;@!!)NN!!)rZ!!)cUrrC7)
-!!)u[!!)u[!!*#\!!)u[!!)lX!!)TP!!)oY!!)u[!!)WQ!!)lX!s%KG!:o7P!;bjV!:o:O!;kpX
-!;,CR!<)$[!;#=Q!;kmY!<)$[!;bgX!<)$\!9X7\r8n(]k2l[>jo>C4k31t-s8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juXSi.sX8i8"X8i8!XSi.tX9AU*X8o=%qlBbtn>lTiqlK_r`2iq=r2]kurN#u!
-ri?)"rN#u!qlBbtr2fbqr2]kuqlBbtrN#u!riGtsr2]kuqlBbtri?)"nuMfkp8e5on>lTiq5aPr
-orJ,nrN#u!o;holqlBbtrN#u!qQ'YsrN-#!ri?)"ri?)"ri?)"qQ'YsJZS%9s6fm:s+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSgAM$Lg&M-Pg&M-OgAM$Mg'%K1g&Th,qq;#MnCdjBqqCuK`7b1kr7V,NrRq5O
-rn7>PrRq5Oqq;#Mr7_#Jr7V,Nqq;#MrRq5Orn@5Lr7V,Nqq;#Mrn7>Po%F'Dp=]KHnCdjBq:YfK
-p"BBGrRq5Oo@a0Eqq;#MrRq5OqUtoLrS%8Orn7>Prn7>Prn7>PqUtoLJ_K;@s8W)Ps+14Mp=fOt
-s8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bk5>;Xjo>D\jo>D[k5>;YjokbIjoFNDqrRkYnE']Nqr[hW`9%%"r8mtZrT4([
-roO1\rT4([qrRkYr9!kVr8mtZqrRkYrT4([roX(Xr8mtZqrRkYroO1\o&]oPp>u>TnE']Nq;qYW
-p#Z5SrT4([oB$#QqrRkYrT4([qW7bXrT=+[roO1\roO1\roO1\qW7bXJ`c.Xs8W)Ks+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX9/I(X8r.!!W];%r2]u#XK2F#X9AU*X8o=%qlBbtn>lTipT+>p`iK.?qlBbt
-rN#u!ri?)"rN#u!r2]kun>lTiqlBbtrN#u!o;holqlBbtri?)"nuMfkp8e5on>lTiq5aProrJ,n
-rN#u!o;holqlBbtrN#u!qlBbtr2]kurN#u!ri?)"ri?)"qlBbtJZS"8s6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johC3g4=hSg&h?/g&V$(!W^pSr7V5Qg=cQ*g'%K1g&Th,qq;#MnCdjBpY#TI`nCCmqq;#M
-rRq5Orn7>PrRq5Or7V,NnCdjBqq;#MrRq5Oo@a0Eqq;#Mrn7>Po%F'Dp=]KHnCdjBq:YfKp"BBG
-rRq5Oo@a0Eqq;#MrRq5Oqq;#Mr7V,NrRq5Orn7>Prn7>Pqq;#MJ_K8?s8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!johL1eVf@bjoYVGjoG;@!W_?_r8n(]k2l[BjokbIjoFNDqrRkYnE']NpZ;GU`o[7$qrRkY
-rT4([roO1\rT4([r8mtZnE']NqrRkYrT4([oB$#QqrRkYroO1\o&]oPp>u>TnE']Nq;qYWp#Z5S
-rT4([oB$#QqrRkYrT4([qrRkYr8mtZrT4([roO1\roO1\qrRkYJ`c+Ws8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!;rnu!<&u$!3E7%riH,"qlBbtn>lTir2]kurN#u!a/f7@
-qQ'YsrN#u!ri?)"rN#u!rN#u!n#QKhqlBbtrN#u!o;holqlKYpo;holp8e5on>lTiq5aProrJ,n
-rN#u!o;holqlBbtrN#u!qlBbtr2]kurN#u!riGtsrN#u!JZRt7s6fm:s+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!;tON!<(UR!8?-,rn@APqq;#MnCdjBr7V,NrRq5Oa4^Ln
-qUtoLrRq5Orn7>PrRq5OrRq5On(IaAqq;#MrRq5Oo@a0EqqCoIo@a0Ep=]KHnCdjBq:YfKp"BBG
-rRq5Oo@a0Eqq;#MrRq5Oqq;#Mr7V,NrRq5Orn@5LrRq5OJ_K5>s8W)Ps+14Mp=fOts8N;WU&X9;
-\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!;tsZ!<)$^!9WDDroX4\qrRkYnE']Nr8mtZrT4([a6!@%
-qW7bXrT4([roO1\rT4([rT4([n)aTMqrRkYrT4([oB$#Qqr[bUoB$#Qp>u>TnE']Nq;qYWp#Z5S
-rT4([oB$#QqrRkYrT4([qrRkYr8mtZrT4([roX(XrT4([J`c(Vs8W)Ks+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johL1eS8juX8i8!X8i7uX8i7tX8i8!X9/I(X8r7$rrDqt!!)Mi!!)qurrE&"!!)qurrCBH
-!!)u!!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)Vl!!)nt!!)u!!!)Vl!!)bp!!)Sk!!)nt!!)u!
-!!)qurrDtu!!)u!!!*#"!!)u!!!)qurrDtu!!)u!!!)qurrDns!!)nt!!)u!!!)nt!!)nt!!*#"
-!!)ks!!)u!!!)u!!!%SOl)apQrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&M-Ng&M-Mg&M-Og&h?/g&V-+rrDrM!!)NB!!)rNrrE&P!!)rNrrCC!
-!!)uO!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)WE!!)oM!!)uO!!)WE!!)cI!!)TD!!)oM!!)uO
-!!)rNrrDuN!!)uO!!*#P!!)uO!!)rNrrDuN!!)uO!!)rNrrDoL!!)oM!!)uO!!)oM!!)oM!!*#P
-!!)lL!!)uO!!)uO!!%T(l.Z1;rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[jo>DZjo>DYjo>D[joYVGjoGDCrrDrY!!)NN!!)rZrrE&\!!)rZrrCC-
-!!)u[!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)WQ!!)oY!!)u[!!)WQ!!)cU!!)TP!!)oY!!)u[
-!!)rZrrDuZ!!)u[!!*#\!!)u[!!)rZrrDuZ!!)u[!!)rZrrDoX!!)oY!!)u[!!)oY!!)oY!!*#\
-!!)lX!!)u[!!)u[!!%T4l/r$Grmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp%X3eS8j#XSMqpX8i7uXSMnsXSr5!X8i8!XS`(jXS`(tX8r=&rW)hsrrCBHqZ-Srr;cbs
-r;cetqZ-;jquHYrr;cJkquHSprW)VmquHYrr;c_rrrDqtr;cbsr;c_rrrDqtr;c_rrrDtuquHYr
-r;c\q!!)ksrW)errW)r!qZ)2Kl)apQrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gA1gIg&M-NgA1dLgAV*Og&M-OgACsCgACsMg&V3-rW)iLrrCC!qZ-TKr;ccL
-r;cfMqZ-<CquHZKr;cKDquHTIrW)WFquHZKr;c`KrrDrMr;ccLr;c`KrrDrMr;c`KrrDuNquHZK
-r;c]J!!)lLrW)fKrW)rOqZ)3$l.Z1;rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5#)Ujo>DZk5#&Xk5GA[jo>D[k555Ok555YjoGJErW)iXrrCC-qZ-TWr;ccX
-r;cfYqZ-<OquHZWr;cKPquHTUrW)WRquHZWr;c`WrrDrYr;ccXr;c`WrrDrYr;c`WrrDuZquHZW
-r;c]V!!)lXrW)fWrW)r[qZ)30l/r$Grmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jJXS;dHXF[I(XMV(=mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=h(g@tZ!g4@t/g;;SDs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@7k4eq-k(2ZGk/-9\s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMX8o@#!;rqs!;rqs!;rqs!:m2k!;`eq!:m2k!;NYq!:m2k!;`ep!;*Ak!;rqs
-!;!;j!:m2k!;`eq!;`es!;rqs!;rqr!;rnu!.h66XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g&Tk*!;tRL!;tRL!;tRL!:nhD!;bFJ!:nhD!;P:J!:nhD!;bFI!;,"D!;tRL
-!;"qC!:nhD!;bFJ!;bFL!;tRL!;tRK!;tON!.ikdgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:joFQB!;u!X!;u!X!;u!X!:o7P!;bjV!:o7P!;P^V!:o7P!;bjU!;,FP!;u!X
-!;#@O!:o7P!;bjV!;bjX!;u!X!;u!W!;tsZ!.j:pk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSMnsXSW"qXSr4rXSr2%X8o?'q>g5jq>gMrrVuu#!6D5A!<&u!!<0&"!<&u!
-!<0&"!<&u!!<0&"!<&u!!;*Am!;iht!<&u!!;*Am!;W\t!3?1lXT&:sX8i7jX8i8!X8i8"X8i8!
-X8i7nX8i8!X8i7mXT&:tX8i8!X8i7uX9&C'!<&u!!<&u!!<&u!!;W_r!.h66XT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1dLgA:mJgAV*KgAV'Sg&Tj\q>g6Cq>gNKrVuuQ!6Ejo!<(UO!<1[P!<(UO
-!<1[P!<(UO!<1[P!<(UO!;,"F!;kIM!<(UO!;,"F!;Y=M!87GEgA_0Lg&M-Cg&M-Og&M-Pg&M-O
-g&M-Gg&M-Og&M-FgA_0Mg&M-Og&M-Ng&_9.!<(UO!<(UO!<(UO!;Y@K!.ikdgAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#&Xk5,/Vk5GAWk5G>_joFQ+q>g6Oq>gNWrVuu]!6F:&!<)$[!<2*\!<)$[
-!<2*\!<)$[!<2*\!<)$[!;,FR!;kmY!<)$[!;,FR!;YaY!9O:Qk5PGXjo>DOjo>D[jo>D\jo>D[
-jo>DSjo>D[jo>DRk5PGYjo>D[jo>DZjoPPF!<)$[!<)$[!<)$[!;YdW!.j:pk5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i7tX8i7tX8i8"XT&;"X8i8!X8i7oX9em.X8o?'!3E7%
-riH,"aK,@ArN#u!ri?)"rN#u!ri?)"rN#u!ri?)"rN#u!orJ2pX8r.!!!)u!!!)\n!W];%q5aVt
-X8qmo!W];%qQ'Ysm&U0eq5aProrJ,nrN#u!orJ2pX8r.!!!)u!!!)qu!W];%rN#u!rN#u!rN#u!
-qQ'_uX8mgQk,eUNrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M-Mg&M-Mg&M-PgA_0Pg&M-Og&M-Hg'Ic5g&Tj\!8?-,
-rn@APaP$UorRq5Orn7>PrRq5Orn7>PrRq5Orn7>PrRq5Op"BHIg&V$(!!)uO!!)]G!W^pSq:YlM
-g&Ud!!W^pSqUtoLm+MF>q:YfKp"BBGrRq5Op"BHIg&V$(!!)uO!!)rN!W^pSrRq5OrRq5OrRq5O
-qUtuNg&Q]Xk1]k8rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>DYjo>DYjo>D\k5PG\jo>D[jo>DTjp;%MjoFQ+!9WDD
-roX4\aQ<I&rT4([roO1\rT4([roO1\rT4([roO1\rT4([p#Z;UjoG;@!!)u[!!)]S!W_?_q;q_Y
-joG&9!W_?_qW7bXm,e9Jq;qYWp#Z5SrT4([p#Z;UjoG;@!!)u[!!)rZ!W_?_rT4([rT4([rT4([
-qW7hZjoBtpk2u^Drmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i7uX9&C'!<&u!!;rnu!<0&"!<&u!!;<K#!3E7%XK2E'
-X8r4#!!)qurrC3C!!*#"!!)u!!!*#"!!)u!!!)hr!!)Vl!!)nt!!)u!!!)Vl!!)ks!s#F(!:m2k
-!;`bs!:6ce!;W\r!;3Dn!<&u!!;!8l!;iht!<&u!!<&u$!3E7%rN#u!rN#u!rN#u!poFGqJZS"8
-s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M-Ng&_9.!<(UO!;tON!<1[P!<(UO!;>+Q!8?-,g=cP\
-g&V**!!)rNrrC3q!!*#P!!)uO!!*#P!!)uO!!)iK!!)WE!!)oM!!)uO!!)WE!!)lL!s%'/!:nhD
-!;bCL!:8D>!;Y=K!;5%G!<(UO!;"nE!;kIM!<(UO!<(UR!8?-,rRq5OrRq5OrRq5Opt>]JJ_K8?
-s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>DZjoPPF!<)$[!;tsZ!<2*\!<)$[!;>O]!9WDDk2l[+
-joGAB!!)rZrrC4(!!*#\!!)u[!!*#\!!)u[!!)iW!!)WQ!!)oY!!)u[!!)WQ!!)lX!s%KG!:o7P
-!;bgX!:8hJ!;YaW!;5IS!<)$[!;#=Q!;kmY!<)$[!<)$^!9WDDrT4([rT4([rT4([puVPVJ`c+W
-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i7uX9&C'!<&u!!;NVt!3E7%nZ2]jr2]kupT4ApbH([DrN#u!
-rN#u!ri?)"rN#u!qQ'YsnuMfkqlBbtrN#u!o;holqQ'c!XK2EmX8i7sXSi.iXSr4sXSr4lX8i8!
-X8i7lX8i7tX8i8!X8i8!X9/I(X8r1"r;cbsr;c_r!!%SOk,eUNrmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-Ng&_9.!<(UO!;P7M!8?-,n_*sCr7V,NpY,WIbLuprrRq5O
-rRq5Orn7>PrRq5OqUtoLo%F'Dqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-LgAM$BgAV*LgAV*Eg&M-O
-g&M-Eg&M-Mg&M-Og&M-Og&h?/g&V')r;ccLr;c`K!!%T(k1]k8rn@C's8VfHs+14M#25dNk2s5T
-J,~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>DZjoPPF!<)$[!;P[Y!9WDDn`BfOr8mtZpZDJUbN8d)rT4([
-rT4([roO1\rT4([qW7bXo&]oPqrRkYrT4([oB$#QqW7k[k2l[7jo>DXk5>;Nk5GAXk5GAQjo>D[
-jo>DQjo>DYjo>D[jo>D[joYVGjoG>Ar;ccXr;c`W!!%T4k2u^Drmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johL1eS8jsX8i7uX8i8"X8i7uX8i8"X8i8"X8i7qXSi.hX8i7tXSi.;X8i7uX8i8!X8i8"
-X8i8!X8i7tX8i7uXSW"qX8i7tX8i8!X8i8"XSW"qX8i7tX8i8"X8i7kX8i7oX8i7iX8i7rX8i7n
-X8i8!X8i7lX8i7tX8i8!X8i8"X8i8"X8i8!X8i8!X8i7rX8i7uX8i6OXQHVamf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hQg&M-Ng&M-Pg&M-Ng&M-Pg&M-Pg&M-JgAM$Ag&M-MgAM#ig&M-Ng&M-Og&M-P
-g&M-Og&M-Mg&M-NgA:mJg&M-Mg&M-Og&M-PgA:mJg&M-Mg&M-Pg&M-Dg&M-Hg&M-Bg&M-Kg&M-G
-g&M-Og&M-Eg&M-Mg&M-Og&M-Pg&M-Pg&M-Og&M-Og&M-Kg&M-Ng&M,(g?.,hs8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@`jo>DZjo>D\jo>DZjo>D\jo>D\jo>DVk5>;Mjo>DYk5>:ujo>DZjo>D[jo>D\
-jo>D[jo>DYjo>DZk5,/Vjo>DYjo>D[jo>D\k5,/Vjo>DYjo>D\jo>DPjo>DTjo>DNjo>DWjo>DS
-jo>D[jo>DQjo>DYjo>D[jo>D\jo>D\jo>D[jo>D[jo>DWjo>DZjo>C4k2th+s8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i7uXSi.rXS`(tX8i7qX9/I(X8qdl!!)bp!!($?!!)nt!!)u!!!*#"!!)u!
-!!)qu!!)Mi!!)nt!!)u!!!)Vl!!)nt!!*#"!!)Sk!!)_o!!)Mi!!)hr!!)\n!!)u!!!)Vl!!)nt
-!!)u!!!*#"!!*#"!!)u!!!)u!!!)hr!!)qu!!%SOk,eUNrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hQg&M-NgAM$KgACsMg&M-Jg&h?/g&UZs!!)cI!!($m!!)oM!!)uO!!*#P!!)uO
-!!)rN!!)NB!!)oM!!)uO!!)WE!!)oM!!*#P!!)TD!!)`H!!)NB!!)iK!!)]G!!)uO!!)WE!!)oM
-!!)uO!!*#P!!*#P!!)uO!!)uO!!)iK!!)rN!!%T(k1]k8rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@`jo>DZk5>;Wk555Yjo>DVjoYVGjoFr6!!)cU!!(%$!!)oY!!)u[!!*#\!!)u[
-!!)rZ!!)NN!!)oY!!)u[!!)WQ!!)oY!!*#\!!)TP!!)`T!!)NN!!)iW!!)]S!!)u[!!)WQ!!)oY
-!!)u[!!*#\!!*#\!!)u[!!)u[!!)iW!!)rZ!!%T4k2u^Drmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jsX8i7uX8i8"X8i8!X8i7uX9/I(X8r$s!!)u!!!)Vl!!)qu!!)u!!!('@!!)ks
-!!)u!!!*#"!!)u!!!)u!!!)Jh!!)nt!!)u!!!)Vl!!)ntqZ-5h!!)_o!!)Mi!!)hr!!)\n!!)u!
-!!)Vl!!)nt!!)u!!!*#"qZ-Vs!!)u!!!)hr!!)qu!!%SOk,eUNrmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johC3g4=hQg&M-Ng&M-Pg&M-Og&M-Ng&h?/g&Up%!!)uO!!)WE!!)rN!!)uO!!('n!!)lL
-!!)uO!!*#P!!)uO!!)uO!!)KA!!)oM!!)uO!!)WE!!)oMqZ-6A!!)`H!!)NB!!)iK!!)]G!!)uO
-!!)WE!!)oM!!)uO!!*#PqZ-WL!!)uO!!)iK!!)rN!!%T(k1]k8rn@C's8VfHs+14M#25dNk2s5T
-J,~>
-!<E0!johL1eVf@`jo>DZjo>D\jo>D[jo>DZjoYVGjoG2=!!)u[!!)WQ!!)rZ!!)u[!!((%!!)lX
-!!)u[!!*#\!!)u[!!)u[!!)KM!!)oY!!)u[!!)WQ!!)oYqZ-6M!!)`T!!)NN!!)iW!!)]S!!)u[
-!!)WQ!!)oY!!)u[!!*#\qZ-WX!!)u[!!)iW!!)rZ!!%T4k2u^Drmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i8"X8i7uX8i8"X8i8!X8i8"X8i8!X8i7lX8i7uXT&;"X8i7u
-XT&:HX8i8!X8i8"X8i8!X8i8"X8i8!X8i8"X8i8!X8i7lX8i7tX8i8!X8i7lX8i7pX8i7kX8i7t
-X8i8!X8i7uXT&:uX8i8!X8i8"X8i8!X8i7uXT&:uX8i8!X8i7uXT&:sX8i7tX8i8!X8i7sX8i8!
-X8i8!X8i8"X8i8!X8i7uX8i6OXQHVamf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-Pg&M-Ng&M-Pg&M-Og&M-Pg&M-Og&M-Eg&M-NgA_0Pg&M-N
-gA_0!g&M-Og&M-Pg&M-Og&M-Pg&M-Og&M-Pg&M-Og&M-Eg&M-Mg&M-Og&M-Eg&M-Ig&M-Dg&M-M
-g&M-Og&M-NgA_0Ng&M-Og&M-Pg&M-Og&M-NgA_0Ng&M-Og&M-NgA_0Lg&M-Mg&M-Og&M-Lg&M-O
-g&M-Og&M-Pg&M-Og&M-Ng&M,(g?.,hs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>D\jo>DZjo>D\jo>D[jo>D\jo>D[jo>DQjo>DZk5PG\jo>DZ
-k5PG-jo>D[jo>D\jo>D[jo>D\jo>D[jo>D\jo>D[jo>DQjo>DYjo>D[jo>DQjo>DUjo>DPjo>DY
-jo>D[jo>DZk5PGZjo>D[jo>D\jo>D[jo>DZk5PGZjo>D[jo>DZk5PGXjo>DYjo>D[jo>DXjo>D[
-jo>D[jo>D\jo>D[jo>DZjo>C4k2th+s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juXS`(uXSr4uX8r=&r;Zi!r;chur;chuq>g2iquH_t!<B5#!;ikt!7.bD!<'"t
-!;rqs!<'"r!;3Gk!;rqs!;*Aj!;`er!;3Gk!;rqs!;ikt!;ikr!;rqs!;ikt!;ikr!;ikt!;rqr
-!;rqs!;`er!<'"t!;rqs!<'"s!.h68XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSgACsNgAV*Ng&V3-r;ZiOr;ciNr;ciNq>g3BquH`M!<CjQ!;kLM!70Br!<(XM
-!;tRL!<(XK!;5(D!;tRL!;,"C!;bFK!;5(D!;tRL!;kLM!;kLK!;tRL!;kLM!;kLK!;kLM!;tRK
-!;tRL!;bFK!<(XM!;tRL!<(XL!.ikfgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bk555Zk5GAZjoGJEr;Zi[r;ciZr;ciZq>g3NquH`Y!<D9]!;kpY!70g)!<)'Y
-!;u!X!<)'W!;5LP!;u!X!;,FO!;bjW!;5LP!;u!X!;kpY!;kpW!;u!X!;kpY!;kpW!;kpY!;u!W
-!;u!X!;bjW!<)'Y!;u!X!<)'X!.j:rk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jJXS;dHXF[I(XMV(=mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=h(g@tZ!g4@t/g;;SDs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@7k4eq-k(2ZGk/-9\s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSr2#X8r7$r;churW)u"rW)u"q>gPsq>^MsrW)u"rW)u"q>gMrrVuu#!.h5&
-XF[J$XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hRgAV'Qg&V-+r;ciNrW)uPrW)uPq>gQLq>^NLrW)uPrW)uPq>gNKrVuuQ!.ijT
-g4@u+gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@ak5G>]joGDCr;ciZrW)u\rW)u\q>gQXq>^NXrW)u\rW)u\q>gNWrVuu]!.j9`
-k(2[Ck5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8"XT&;#X8i8!X8i8"XT&;"X8i8"X9J[+X8o?'!<0&"!<&u%!3E7%!<0&"
-!<0&+!3E7%XK2E'X8r7$rr@VOJZOF(d]EK:rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-PgA_0Qg&M-Og&M-PgA_0Pg&M-Pg'.Q2g&Tj\!<1[P!<(US!8?-,!<1[P
-!<1[Y!8?-,g=cP\g&V-+rr@W(J_G\/db=a$rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D\k5PG]jo>D[jo>D\k5PG\jo>D\jothJjoFQ+!<2*\!<)$_!9WDD!<2*\
-!<2*e!9WDDk2l[+joGDCrr@W4J`_OGdcUT0rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!W];%qlC&'XK2E'!3E7%ri?;(XK2E'X8r7$!!)u!#QUs-!3?1%X8r7$
-#lq'.!3E7%XK2F#X8i7uXT&9OXF[I(XP']Tmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V')!W^pSqq;;Ug=cP\!8?-,rn7PVg=cP\g&V-+!!)uO#QWT4!87G,g&V-+
-#lr]5!8?-,g=cQ*g&M-NgA_/(g4@t/g=b3[s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG>A!W_?_qrS.ak2l[+!9WDDroOCbk2l[+joGDC!!)u[#QX#L!9O:DjoGDC
-#ls,M!9WDDk2l[Bjo>DZk5PF4k(2ZGk1Snss8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3?1%X8r.!!!)nt!s#F(!<&u&!3?1%X8r.!!!)qu!!)bp
-rr@VOJZOF(frY5Armh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!87G,g&V$(!!)oM!s%'/!<(UT!87G,g&V$(!!)rN!!)cI
-rr@W(J_G\/g"QK+rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9O:DjoG;@!!)oY!s%KG!<)$`!9O:DjoG;@!!)rZ!!)cU
-rr@W4J`_OGg#i>7rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)ntr;cet"TYX*!3?1tX8i7tXSi-MXF[I(
-XO4-Lmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oMr;cfM"T[91!87GMg&M-MgAM#&g4@t/
-g<nXSs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oYr;cfY"T[]I!9O:Yjo>DYk5>:2k(2ZG
-k0`>ks8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)nt!s#F(!<&u&!3E7%X8r.!!!)bp!!%SO
-JZOF(d]EK:rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oM!s%'/!<(UT!8?-,g&V$(!!)cI!!%T(
-J_G\/db=a$rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oY!s%KG!<)$`!9WDDjoG;@!!)cU!!%T4
-J`_OGdcUT0rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r*u!!)nt!s#F(!<0)"!;iht!;iht!<&u$!3E7%riH,"qlBbtr2]kurN#u!
-JZOF(JZR;$s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM!s%'/!<1^P!;kIM!;kIM!<(UR!8?-,rn@APqq;#Mr7V,NrRq5O
-J_G\/J_JQ+s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY!s%KG!<2-\!;kmY!;kmY!<)$^!9WDDroX4\qrRkYr8mtZrT4([
-J`_OGJ`bDCs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!*#"rrDqt!!)nt!!)u!!s#F(!<0)"!;iht!;rqu
-!<0&"!;rqu!.h5&XF[J+XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!*#PrrDrM!!)oM!!)uO!s%'/!<1^P!;kIM!;tRN
-!<1[P!;tRN!.ijTg4@u2gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!*#\rrDrY!!)oY!!)u[!s%KG!<2-\!;kmY!;u!Z
-!<2*\!;u!Z!.j9`k(2[Jk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jtXSi.tXSi.uXSr5!X8i8!XS`(tXSMnsXSr5!X8i8!XS`(tX8r=&rW)hsrr@VO
-JZOF(frY5Armh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hRgAM$MgAM$NgAV*Og&M-OgACsMgA1dLgAV*Og&M-OgACsMg&V3-rW)iLrr@W(
-J_G\/g"QK+rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@ak5>;Yk5>;Zk5GA[jo>D[k555Yk5#&Xk5GA[jo>D[k555YjoGJErW)iXrr@W4
-J`_OGg#i>7rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i7gX8i6OXF[I(XR*%gmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M-@g&M,(g4@t/g?dPns8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>DLjo>C4k(2ZGk3V71s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#qZ,o_rW(QOrrDMh!!%SOJZOF(l`C-Srmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/qZ,p8rW(R(rrDNA!!%T(J_G\/le;C=rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JqZ,pDrW(R4rrDNM!!%T4J`_OGlfS6Irmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)8b!!(ZQ!W];%n#QKhJZOF(JZS1=s6fm:s+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!jp.U6g4=h/g&V**!!)9;!!([*!W^pSn(IaAJ_G\/J_KGDs8W)Ps+14Mp=fOts8N;WU&X9;
-\c@6~>
-!<E0!jp.^4eVf@JjoGAB!!)9G!!([6!W_?_n)aTMJ`_OGJ`c:\s8W)Ks+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!jp.^4eS8j#X8r4#!!)qurW)r!rr<&#rW)er!!)u!rW)u"rW(rZ!!)Jh!!%SOJZOF(l`C-S
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)rNrW)rOrr<&QrW)fK!!)uOrW)uPrW(s3!!)KA!!%T(J_G\/le;C=
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)rZrW)r[rr<&]rW)fW!!)u[rW)u\rW(s?!!)KM!!%T4J`_OGlfS6I
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!*#"!!*#"rrE&"!!)nt!!)qu!!)u!!!)\nq>g/h!!)Jh!!%SO
-JZOF(l`C-Srmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!*#P!!*#PrrE&P!!)oM!!)rN!!)uO!!)]Gq>g0A!!)KA!!%T(
-J_G\/le;C=rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!*#\!!*#\rrE&\!!)oY!!)rZ!!)u[!!)]Sq>g0M!!)KM!!%T4
-J`_OGlfS6Irmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r7$!!)u!!!)qu!s#F(!;rnu!;rnu!;rnu!<&u!!9(!Z!:[&i!.h5&XF[J<
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V-+!!)uO!!)rN!s%'/!;tON!;tON!;tON!<(UO!9)W3!:\\B!.ijTg4@uC
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoGDC!!)u[!!)rZ!s%KG!;tsZ!;tsZ!;tsZ!<)$[!9*&?!:]+N!.j9`k(2[[
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSi.sXSMqsX8i7uX8i7uX8i7tX9/I(X8qmoq>g/h!!)Jh!!%SOJZOF(l`C-S
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gAM$LgA1gLg&M-Ng&M-Ng&M-Mg&h?/g&Ud!q>g0A!!)KA!!%T(J_G\/le;C=
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5>;Xk5#)Xjo>DZjo>DZjo>DYjoYVGjoG&9q>g0M!!)KM!!%T4J`_OGlfS6I
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r7$!!)u!!!)hr!!)qu!!)qu!!)nt!s#F(!8spY!:Quh!.h5&XF[J=XT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V-+!!)uO!!)iK!!)rN!!)rN!!)oM!s%'/!8uQ2!:SVA!.ijTg4@uDgAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoGDC!!)u[!!)iW!!)rZ!!)rZ!!)oY!s%KG!8uu>!:T%M!.j9`k(2[\k5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!"9>O)!!*#"!!)nt!!)ksrrCrX!!)Jh!!%SOJZOF(l`C-S
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO"9@00!!*#P!!)oM!!)lLrrCs1!!)KA!!%T(J_G\/le;C=
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u["9@TH!!*#\!!)oY!!)lXrrCs=!!)KM!!%T4J`_OGlfS6I
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!joqR2eS8j#rW)nu!!)u!r;chu!<B5#!;rqr!;iht!9($W!:d,j!.h5&XF[J=XT._fec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqI4g4=h/rW)oN!!)uOr;ciN!<CjQ!;tRK!;kIM!9)Z0!:ebC!.ijTg4@uDgAh3PgAca(
-s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!joqR2eVf@JrW)oZ!!)u[r;ciZ!<D9]!;u!W!;kmY!9*)<!:f1O!.j9`k(2[\k5YJ\ec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jdX8i7gX8i7DX8i6OXF[I(XQutfmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hBg&M-@g&M,rg&M,(g4@t/g?[Jms8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Qjo>DLjo>D)jo>C4k(2ZGk3M10s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jdX8i7gX8i7CX8i6OXF[I(XR*%gmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hBg&M-@g&M,qg&M,(g4@t/g?dPns8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Qjo>DLjo>D(jo>C4k(2ZGk3V71s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jeXSi.iXSi-MXF[I(XL5/0mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hCgAM$BgAM#&g4@t/g9oZ7s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Rk5>;Nk5>:2k(2ZGk-a@Os8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXN.CB!.h5&XN%@Amf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g;hnI!.ijTg;_kHs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k/ZTa!.j9`k/QQ`s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,XSr2#X8qUg!!)2`!!(0C!!%SOJZQhls6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g_gAV'Qg&UKn!!)39!!(0q!!%T(J_J)ss8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?nk5G>]joFc1!!)3E!!(1(!!%T4J`ar6s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8j-X8i8"XT&:eX8i7`X8i7CX8i6OXF[IlXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g`g&M-PgA_0>g&M-9g&M,qg&M,(g4@tsgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?ojo>D\k5PGJjo>DEjo>D(jo>C4k(2[6k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8j.X8i7uX8i8"XSi.uXT&8#XSr4uXS`(qXSr4uXSr2"XSr5"XS`(CX8i6OXF[Il
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=gag&M-Ng&M-PgAM$NgA_-QgAV*NgACsJgAV*NgAV'PgAV*PgACrqg&M,(g4@ts
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?pjo>DZjo>D\k5>;Zk5PD]k5GAZk555Vk5GAZk5G>\k5GA\k555(jo>C4k(2[6
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8j.X8i7rX8i8!X8i8"XT&;"X8i8!X8i7rX8i8"X8i8!X8i8"X8i8!X8i7jXSMqU
-X8i6OXF[IlXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=gag&M-Kg&M-Og&M-PgA_0Pg&M-Og&M-Kg&M-Pg&M-Og&M-Pg&M-Og&M-CgA1g.
-g&M,(g4@tsgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?pjo>DWjo>D[jo>D\k5PG\jo>D[jo>DWjo>D\jo>D[jo>D\jo>D[jo>DOk5#):
-jo>C4k(2[6k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8j.X8i7sX8i7tX9/I(X8r4#!!)u!!!)ks!!)qu!!)u!!W];%r2]kuhlQ\To;hol
-JZOF(`2s",rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=gag&M-Lg&M-Mg&h?/g&V**!!)uO!!)lL!!)rN!!)uO!W^pSr7V,NhqIr-o@a0E
-J_G\/`7k7krn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf?pjo>DXjo>DYjoYVGjoGAB!!)u[!!)lX!!)rZ!!)u[!W_?_r8mtZhrae9oB$#Q
-J`_OG`9.+"rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8j.X8i7sX8i7tX9/I(X8r4#!!)u!!!)ksq>gGp!!)nt!!)Pjq>fKU!!%SOJZQhl
-s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=gag&M-Lg&M-Mg&h?/g&V**!!)uO!!)lLq>gHI!!)oM!!)QCq>fL.!!%T(J_J)s
-s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?pjo>DXjo>DYjoYVGjoGAB!!)u[!!)lXq>gHU!!)oY!!)QOq>fL:!!%T4J`ar6
-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8j.X8i7sX8i7tX9/I(X8r4#!!)u!!!)ks!!)bp!W];%r2]kub,bRCJZOF(`N9+-
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=gag&M-Lg&M-Mg&h?/g&V**!!)uO!!)lL!!)cI!W^pSr7V,Nb1ZgqJ_G\/`S1@l
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf?pjo>DXjo>DYjoYVGjoGAB!!)u[!!)lX!!)cU!W_?_r8mtZb2r[(J`_OG`TI4#
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8j-X8i8!X9/I(X8r4#!!*#"!!)u!!!)u!!!*#"!!)u!!!)u!!!*#"!!*#"!!)u!
-!!*#"!!(<G!!%SOJZQhls6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g`g&M-Og&h?/g&V**!!*#P!!)uO!!)uO!!*#P!!)uO!!)uO!!*#P!!*#P!!)uO
-!!*#P!!(<u!!%T(J_J)ss8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?ojo>D[joYVGjoGAB!!*#\!!)u[!!)u[!!*#\!!)u[!!)u[!!*#\!!*#\!!)u[
-!!*#\!!(=,!!%T4J`ar6s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8j,XSi.tXSi.uXSr5"XSr4uXSr4sXSi.uXSr2"XSr4uXSr4EX8i6OXF[IlXT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g_gAM$MgAM$NgAV*PgAV*NgAV*LgAM$NgAV'PgAV*NgAV)sg&M,(g4@tsgAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?nk5>;Yk5>;Zk5GA\k5GAZk5GAXk5>;Zk5G>\k5GAZk5GA*jo>C4k(2[6k5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXN7IC!.h5&XMq:@mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g;qtJ!.ijTg;VeGs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k/cZb!.j9`k/HK_s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXN.CB!.h5&XN%@Amf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g;hnI!.ijTg;_kHs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k/ZTa!.j9`k/QQ`s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXN7IC!91*[!/[cW!.h6/XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g;qtJ!92`4!/]D0!.ik]gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k/cZb!93/@!/]h<!.j:ik5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXR<1h!!0/$i2cnYkcFa`"KVU)X8nin!!)Gg!!%SOhQ6bFrmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g@!\o!!1dRi7\/2kh?"9"PNk0g&R_u!!)H@!!%T(hV/#0rn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k3hC2!!23^i8t">kiVjE"Qf^HjoD"8!!)HL!!%T4hWFk<rmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXRE4j!<0)"!6;/@!<0)"!<9,#!1p7l!:Hog!.h6.XT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johC3g4=g+g@*_q!<1^P!6<dn!<1^P!<:aQ!1qmE!:JP@!.ik\gAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!johL1eVf?:k3qF4!<2-\!6=4%!<2-\!<;0]!1r<Q!:JtL!.j:hk5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johL1eS8iMXRE4j!<&u!!;rqt!<'#!!<9/#!<9/"!<9/"!<0)!!;`er!!0/$rN,turN#u!
-r2^#$XK2E'rW)ktr;churr<&#rW)ktrW!#$!!)u!rW(rZrrE)#rrE#!r;cbsr;cetquH8g!!%SO
-hQ6bFrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g@*_q!<(UO!;tRM!<(XO!<:dQ!<:dP!<:dP!<1^O!;bFK!!1dRrS%5NrRq5O
-r7V8Rg=cP\rW)lMr;ciNrr<&QrW)lMrW!#R!!)uOrW(s3rrE)QrrE#Or;ccLr;cfMquH9@!!%T(
-hV/#0rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k3qF4!<)$[!;u!Y!<)'[!<;3]!<;3\!<;3\!<2-[!;bjW!!23^rT=(ZrT4([
-r8n+^k2l[+rW)lYr;ciZrr<&]rW)lYrW!#^!!)u[rW(s?rrE)]rrE#[r;ccXr;cfYquH9L!!%T4
-hWFk<rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXRE4j!;NVq!<0&"!<&u)!3?1%X8o?'!<&u!!;iht!;iht!<0)"!<0&"!<0&"
-!<0&"!;W_r!<0&"!<0&"!<&u!!<0)"!<0&"!<0&"!<0)"!<&u!!<0&"!;3Gi!;3E!!3?1%X8o?'
-!<&u!!<0&"!<&u!!<&u!!:Hog!.h6.XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g@*_q!;P7J!<1[P!<(UW!87G,g&Tj\!<(UO!;kIM!;kIM!<1^P!<1[P!<1[P
-!<1[P!;Y@K!<1[P!<1[P!<(UO!<1^P!<1[P!<1[P!<1^P!<(UO!<1[P!;5(B!;5%O!87G,g&Tj\
-!<(UO!<1[P!<(UO!<(UO!:JP@!.ik\gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3qF4!;P[V!<2*\!<)$c!9O:DjoFQ+!<)$[!;kmY!;kmY!<2-\!<2*\!<2*\
-!<2*\!;YdW!<2*\!<2*\!<)$[!<2-\!<2*\!<2*\!<2-\!<)$[!<2*\!;5LN!;5I[!9O:DjoFQ+
-!<)$[!<2*\!<)$[!<)$[!:JtL!.j:hk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXR<1g!<&u!!;rnu!<0)"!;iht!<&u!!;iht!;rnu!;ro#!3E7%r2]u#XK2Et
-X8i8!X8i7rX8i8"X8i8!X9/I(X8r1"!!*#"!!)qu!!)&\rrDtu!!)nt!W];%qlBbtri?)"n#QKh
-JZR\/s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g@!\n!<(UO!;tON!<1^P!;kIM!<(UO!;kIM!;tON!;tOQ!8?-,r7V5Qg=cQ&
-g&M-Og&M-Kg&M-Pg&M-Og&h?/g&V')!!*#P!!)rN!!)'5rrDuN!!)oM!W^pSqq;#Mrn7>Pn(IaA
-J_Jr6s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k3hC1!<)$[!;tsZ!<2-\!;kmY!<)$[!;kmY!;tsZ!;ts]!9WDDr8n(]k2l[>
-jo>D[jo>DWjo>D\jo>D[joYVGjoG>A!!*#\!!)rZ!!)'ArrDuZ!!)oY!W_?_qrRkYroO1\n)aTM
-J`beNs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXQlke!<0(r!<0&"!;W\u!3E7%qQ'Ysr2]kuq5jDms/Z2#q5aPrrN#u!rN,ns
-ri?)"rN$)$XK2F"X8i8"XSMqjXSMqiX8i7tX8i7tX9&C'!;iht!<0&"!:Hog!.h6.XT._fec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g?RAl!<1^K!<1[P!;Y=N!8?-,qUtoLr7V,Nq:bZFs4RGQq:YfKrRq5OrS%/L
-rn7>PrRq>Rg=cQ)g&M-PgA1gCgA1gBg&M-Mg&M-Mg&_9.!;kIM!<1[P!:JP@!.ik\gAh3PgAca(
-s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3D(/!<2-W!<2*\!;YaZ!9WDDqW7bXr8mtZq<%MRs5j:]q;qYWrT4([rT="X
-roO1\rT41^k2l[Ajo>D\k5#)Ok5#)Njo>DYjo>DYjoPPF!;kmY!<2*\!:JtL!.j:hk5YJ\ec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXRE4j!<&u!!<0&"!;NVq!;W\u!3E7%qQ'Ysr2]kuq5aPrq5aPrq5aPrrN#u!
-ri?)"rN#u!ri?)"rN$)$XK2F"X8i8"X8i7VX8i7tX8i7tX9&C'!;iht!<0&"!:Hog!.h6.XT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g@*_q!<(UO!<1[P!;P7J!;Y=N!8?-,qUtoLr7V,Nq:YfKq:YfKq:YfKrRq5O
-rn7>PrRq5Orn7>PrRq>Rg=cQ)g&M-Pg&M-/g&M-Mg&M-Mg&_9.!;kIM!<1[P!:JP@!.ik\gAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3qF4!<)$[!<2*\!;P[V!;YaZ!9WDDqW7bXr8mtZq;qYWq;qYWq;qYWrT4([
-roO1\rT4([roO1\rT41^k2l[Ajo>D\jo>D;jo>DYjo>DYjoPPF!;kmY!<2*\!:JtL!.j:hk5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXRE7j!<0&"!<&u!!<&u!!<0&"!;NYq!;W\r!;iht!<&u!!<0&"!<&u!!<0&"
-!<&u$!3E7%rN#u!ri?)"riH,"ri?)"rN#u!ri?)"riH,"rN#u!rN#u!j/`4\qQ'YsrN#u!ri?)"
-rN#u!rN#u!ri?)"nuMfkJZR_0s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g@*bq!<1[P!<(UO!<(UO!<1[P!;P:J!;Y=K!;kIM!<(UO!<1[P!<(UO!<1[P
-!<(UR!8?-,rRq5Orn7>Prn@APrn7>PrRq5Orn7>Prn@APrRq5OrRq5Oj4XJ5qUtoLrRq5Orn7>P
-rRq5OrRq5Orn7>Po%F'DJ_Ju7s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k3qI4!<2*\!<)$[!<)$[!<2*\!;P^V!;YaW!;kmY!<)$[!<2*\!<)$[!<2*\
-!<)$^!9WDDrT4([roO1\roX4\roO1\rT4([roO1\roX4\rT4([rT4([j5p=AqW7bXrT4([roO1\
-rT4([rT4([roO1\o&]oPJ`bhOs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXRE4k!3H/"qlK_rriH%uqQ0\sqlK\qr2fhsr2fhsr2fhss/c2"s/c2"riH)!
-"0;J&XSr5"XSr5!XSr2#X8r1"r;blZr;c_rr;cbsr;c_rrW)Ji!!%SOhQ6bFrmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g@*_r!8@DPqqCuKrn@;NqV(rLqqCrJr7_)Lr7_)Lr7_)Ls4[GPs4[GPrn@>O
-"53_TgAV*PgAV*OgAV'Qg&V')r;bm3r;c`Kr;ccLr;c`KrW)KB!!%T(hV/#0rn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k3qF5!9X7\qr[hWroX.ZqW@eXqr[eVr9!qXr9!qXr9!qXs5s:\s5s:\roX1[
-"6KR`k5GA\k5GA[k5G>]joG>Ar;bm?r;c`Wr;ccXr;c`WrW)KN!!%T4hWFk<rmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXG<kW!33+#!.h6.XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g5"A^!34`Q!.ik\gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(i(!!35/]!.j:hk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXGEqX!2ut!!.h6/XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g5+G_!3"TO!.ik]gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(r."!3##[!.j:ik5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXGj7Z!.h5)XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g5Oba!.ijWgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k)AI$!.j9ck5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[GRX8pbO!!%SO]<)&#rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g4@rYg&TXV!!%T(]A!;brn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k(2XqjoEon!!%T4]B9.nrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXJW)u!!0/$i2cnYeZ8`NJZQGas6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g8<U'!!1dRi7\/2e_1!'J_I]hs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k,.;?!!23^i8t">e`Hi3J`aQ+s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXJ`-"!<0)"!4/a,!.h5_XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g8EX)!<1^P!41AZ!.ik8gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k,7>A!<2-\!41ef!.j:Dk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXJ`-"!<&u!!;rqt!<'#!!<9/#!<9/"!<9/"!<0)!!;`er!!0/$rN,tur2fer
-nuMfkJZQGas6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g8EX)!<(UO!;tRM!<(XO!<:dQ!<:dP!<:dP!<1^O!;bFK!!1dRrS%5Nr7_&K
-o%F'DJ_I]hs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k,7>A!<)$[!;u!Y!<)'[!<;3]!<;3\!<;3\!<2-[!;bjW!!23^rT=(Zr9!nW
-o&]oPJ`aQ+s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXJ`-"!;NVq!<0&"!<&u)!3?1%X8o?'!<&u!!;iht!;iht!<0)"!<0&"!<0&"
-!<0&"!<&u!!:m2k!.h5_XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g8EX)!;P7J!<1[P!<(UW!87G,g&Tj\!<(UO!;kIM!;kIM!<1^P!<1[P!<1[P
-!<1[P!<(UO!:nhD!.ik8gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k,7>A!;P[V!<2*\!<)$c!9O:DjoFQ+!<)$[!;kmY!;kmY!<2-\!<2*\!<2*\
-!<2*\!<)$[!:o7P!.j:Dk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXJW)t!<&u!!;rnu!<0)"!;iht!<&u!!;iht!;rnu!;ro#!3E7%r2]u#XK2Ei
-X8i6OXLYG4mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8<U&!<(UO!;tON!<1^P!;kIM!<(UO!;kIM!;tON!;tOQ!8?-,r7V5Qg=cPp
-g&M,(g:>r;s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,.;>!<)$[!;tsZ!<2-\!;kmY!<)$[!;kmY!;tsZ!;ts]!9WDDr8n(]k2l[3
-jo>C4k.0XSs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJ2cr!<0(r!<0&"!;W\u!3E7%qQ'Ysr2]kuq5jDmriH%unZ2]jJZQGas6fm:
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g7m:$!<1^K!<1[P!;Y=N!8?-,qUtoLr7V,Nq:bZFrn@;Nn_*sCJ_I]hs8W)P
-s+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k+^u<!<2-W!<2*\!;YaZ!9WDDqW7bXr8mtZq<%MRroX.Zn`BfOJ`aQ+s8W)K
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXJ`-"!<&u!!<0&"!;NVq!;W\u!3E7%qQ'Ysr2]kuq5aProW/#mnuMfkJZQGa
-s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g8EX)!<(UO!<1[P!;P7J!;Y=N!8?-,qUtoLr7V,Nq:YfKo\'9Fo%F'DJ_I]h
-s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k,7>A!<)$[!<2*\!;P[V!;YaZ!9WDDqW7bXr8mtZq;qYWo]?,Ro&]oPJ`aQ+
-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXJ`0"!<0&"!<&u!!<&u!!<0&"!;NYq!;W\r!;iht!<&u!!<0&"!<&u$!3E7%
-rN#u!nuMfkJZQGas6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g8E[)!<1[P!<(UO!<(UO!<1[P!;P:J!;Y=K!;kIM!<(UO!<1[P!<(UR!8?-,
-rRq5Oo%F'DJ_I]hs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k,7AA!<2*\!<)$[!<)$[!<2*\!;P^V!;YaW!;kmY!<)$[!<2*\!<)$^!9WDD
-rT4([o&]oPJ`aQ+s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXJ`-#!3H/"qlK_rriH%uqQ0\sqlK\qr2fhsr2fhsriH"tnZ2]jJZQGas6fm:
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g8EX*!8@DPqqCuKrn@;NqV(rLqqCrJr7_)Lr7_)Lrn@8Mn_*sCJ_I]hs8W)P
-s+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k,7>B!9X7\qr[hWroX.ZqW@eXqr[eVr9!qXr9!qXroX+Yn`BfOJ`aQ+s8W)K
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[J%X8i6OXLbM5mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@u,g&M,(g:H#<s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[Djo>C4k.9^Ts8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[J$X8i6OXLkS6mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@u+g&M,(g:Q)=s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[Cjo>C4k.BdUs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I^XT&9OXOjQRmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@tegA_/(g=P'Ys8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[(k5PF4k1Abqs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[J2XSr5!XSr4eXS`(oX8i8"XSMqjXSMq*X8i7`XSr4sXSr4]XT._fec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u9gAV*OgAV*>gACsHg&M-PgA1gCgA1fXg&M-9gAV*LgAV*6gAh3PgAca(
-s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Qk5GA[k5GAJk555Tjo>D\k5#)Ok5#(djo>DEk5GAXk5GABk5YJ\ec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[J1XT&;"XT&:cX8i7pX8i8"X9J[+X8o?'!;<Ju!3E7%XK2E1X8i7^X8i7r
-X8i7^XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u8gA_0PgA_0<g&M-Ig&M-Pg'.Q2g&Tj\!;>+N!8?-,g=cP8g&M-7g&M-K
-g&M-7gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Pk5PG\k5PGHjo>DUjo>D\jothJjoFQ+!;>OZ!9WDDk2lZPjo>DCjo>DW
-jo>DCk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[J1X9/I(!3H/"riH)!!iuA%rN,tu!NZ;!X8i7tXSr2#X8r7$"ota+!3E7%
-riH%urN$P1XK2E'X8o?'!!'+%!!'+%rW)u"rW(rZrVuu#!<0(u!<0)"!!',"!<'"s!<'#!!<9/#
-!<'"t!;`bs!;W\r!;`er!<'#!!<9/#!;W_rmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@u8g&h?/!8@DPrn@>O!nmVSrS%5N!SRPOg&M-MgAV'Qg&V-+"p!B2!8?-,
-rn@;NrRqe_g=cP\g&Tj\!!(a,!!(a,rW)uPrW(s3rVuuQ!<1^N!<1^P!!(aP!<(XL!<(XO!<:dQ
-!<(XM!;bCL!;Y=K!;bFK!<(XO!<:dQ!;Y@Ks8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[PjoYVG!9X7\roX1[!p0I_rT=(Z!TjC[jo>DYk5G>]joGDC"p!fJ!9WDD
-roX.ZrT4Xkk2l[+joFQ+!!)0D!!)0DrW)u\rW(s?rVuu]!<2-Z!<2-\!!)0\!<)'X!<)'[!<;3]
-!<)'Y!;bgX!;YaW!;bjW!<)'[!<;3]!;YdWs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[J1X9em.!3?1%!3E7%riH,"rN#u!riH,"r2]kur2]kuriH,"qlBbtr2]ku
-rN#u!qlBbtqlC&'X8o?'!3E7%rN#u!orRuiorJ,nriH,"s/Z2#rN#u!riH,"ri?)"rN#u!q5ai%
-X8o?'!3E7%rN#u!qlBbtq5aPrqlBbtri?)"rN$/&X8o?'!;`esmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=g+g4@u8g'Ic5!87G,!8?-,rn@APrRq5Orn@APr7V,Nr7V,Nrn@APqq;#Mr7V,N
-rRq5Oqq;#Mqq;;Ug&Tj\!8?-,rRq5Op"K6Bp"BBGrn@APs4RGQrRq5Orn@APrn7>PrRq5Oq:Z)S
-g&Tj\!8?-,rRq5Oqq;#Mq:YfKqq;#Mrn7>PrRqDTg&Tj\!;bFLs8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf?:k(2[Pjp;%M!9O:D!9WDDroX4\rT4([roX4\r8mtZr8mtZroX4\qrRkYr8mtZ
-rT4([qrRkYqrS.ajoFQ+!9WDDrT4([p#c)Np#Z5SroX4\s5j:]rT4([roX4\roO1\rT4([q;qq_
-joFQ+!9WDDrT4([qrRkYq;qYWqrRkYroO1\rT47`joFQ+!;bjXs8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8iMXF[J1X9\g-X8o?'!3?1uX8i8"X8i7uX8i7uX8i8!X8i7uX8i7tX8i8!X8i7t
-X8i7uX8i7tXT&:tX8i8!X8i7\X8i7uX9&C'!;ii"!3E7%rN#u!rN#u!q5jSrr2]kuqlBbtr2]ku
-q5aPrr2]kur2]kuriH,"p8n;^rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g4@u8g'@]4g&Tj\!87GNg&M-Pg&M-Ng&M-Ng&M-Og&M-Ng&M-Mg&M-Og&M-M
-g&M-Ng&M-MgA_0Mg&M-Og&M-5g&M-Ng&_9.!;kIP!8?-,rRq5OrRq5Oq:biKr7V,Nqq;#Mr7V,N
-q:YfKr7V,Nr7V,Nrn@APp=fQHrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k(2[Pjp1tLjoFQ+!9O:Zjo>D\jo>DZjo>DZjo>D[jo>DZjo>DYjo>D[jo>DY
-jo>DZjo>DYk5PGYjo>D[jo>DAjo>DZjoPPF!;km\!9WDDrT4([rT4([q<%\Wr8mtZqrRkYr8mtZ
-q;qYWr8mtZr8mtZroX4\p?)DTrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[J1X9\g-X8o?'!3?1uX8i8"X8i7oX8i8!X8i7uX8i7tX8i8!X8i7tX8i7u
-X8i7tX8i7rX9/I(X8qmoq>g5j!!)ks!!)nt!s#F(!<&u!!<&u!!;W\r!;iht!;iht!;rnu!;W\r
-!;rqp!<0&"!;3Gnmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@u8g'@]4g&Tj\!87GNg&M-Pg&M-Hg&M-Og&M-Ng&M-Mg&M-Og&M-Mg&M-N
-g&M-Mg&M-Kg&h?/g&Ud!q>g6C!!)lL!!)oM!s%'/!<(UO!<(UO!;Y=K!;kIM!;kIM!;tON!;Y=K
-!;tRI!<1[P!;5(Gs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[Pjp1tLjoFQ+!9O:Zjo>D\jo>DTjo>D[jo>DZjo>DYjo>D[jo>DYjo>DZ
-jo>DYjo>DWjoYVGjoG&9q>g6O!!)lX!!)oY!s%KG!<)$[!<)$[!;YaW!;kmY!;kmY!;tsZ!;YaW
-!;u!U!<2*\!;5LSs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[J1X8i7uX9&C'!;rnu!<0&"!;<Jo!<&u!!;rnu!;iht!<&u!!;iht!;rnu
-!;iht!;W\u!3E7%iiE+[qQ'YsqlBl"XK2F#X8i8!X8i7rX8i7tX8i7tX8i7uX8i7rX8i7uX8i7q
-X8i7nXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u8g&M-Ng&_9.!;tON!<1[P!;>+H!<(UO!;tON!;kIM!<(UO!;kIM!;tON
-!;kIM!;Y=N!8?-,in=A4qUtoLqq;,Pg=cQ*g&M-Og&M-Kg&M-Mg&M-Mg&M-Ng&M-Kg&M-Ng&M-J
-g&M-GgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Pjo>DZjoPPF!;tsZ!<2*\!;>OT!<)$[!;tsZ!;kmY!<)$[!;kmY!;tsZ
-!;kmY!;YaZ!9WDDioU4@qW7bXqrRt\k2l[Bjo>D[jo>DWjo>DYjo>DYjo>DZjo>DWjo>DZjo>DV
-jo>DSk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[J1X8i7uX9/I(X8r7$rrE#!!!)u!!!)qu!!)qu!!*#"rrDqt!!)qu!!)u!
-!!)nt!!)nt!!)eqrrCuY!!)u!!s#F(!<&u!!<0&"!<&u!!<&u!!<0&"!<&u!!;`bs!<&u!!;iht
-!;W\r!;iht!<&u!!<0&"!;3Gnmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@u8g&M-Ng&h?/g&V-+rrE#O!!)uO!!)rN!!)rN!!*#PrrDrM!!)rN!!)uO
-!!)oM!!)oM!!)fJrrD!2!!)uO!s%'/!<(UO!<1[P!<(UO!<(UO!<1[P!<(UO!;bCL!<(UO!;kIM
-!;Y=K!;kIM!<(UO!<1[P!;5(Gs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[Pjo>DZjoYVGjoGDCrrE#[!!)u[!!)rZ!!)rZ!!*#\rrDrY!!)rZ!!)u[
-!!)oY!!)oY!!)fVrrD!>!!)u[!s%KG!<)$[!<2*\!<)$[!<)$[!<2*\!<)$[!;bgX!<)$[!;kmY
-!;YaW!;kmY!<)$[!<2*\!;5LSs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[J2XSr5!XSr5"XSr2#X8r1"r;cetquH\srW!#$!!*#"quH\sr;cbsquH_t
-r;cYp!!(oXr;cetr;churW)u"rW)nurW)nur;c_rr;cbsquH\squHYrr;chur;cSns6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g4@u9gAV*OgAV*PgAV'Qg&V')r;cfMquH]LrW!#R!!*#PquH]Lr;ccLquH`M
-r;cZI!!(p1r;cfMr;ciNrW)uPrW)oNrW)oNr;c`Kr;ccLquH]LquHZKr;ciNr;cTGs8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k(2[Qk5GA[k5GA\k5G>]joG>Ar;cfYquH]XrW!#^!!*#\quH]Xr;ccXquH`Y
-r;cZU!!(p=r;cfYr;ciZrW)u\rW)oZrW)oZr;c`Wr;ccXquH]XquHZWr;ciZr;cTSs8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[J#X8i76X8i6OXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u*g&M,dg&M,(gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Bjo>Cpjo>C4k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[J$X8i75X8i6OXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u+g&M,cg&M,(gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Cjo>Cojo>C4k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[J(XSi.4XSi-NXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u/gAM#bgAM#'gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Gk5>:nk5>:3k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJW'!!.h5&XQQ\bmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8<R(!.ijTg?72is8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,.8@!.j9`k3(n,s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJDot!.h5&XQchdmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8*F&!.ijTg?I>ks8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k+q,>!.j9`k3;%.s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJW'!!.h5&XQQ\bmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8<R(!.ijTg?72is8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,.8@!.j9`k3(n,s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJW'!!.h5&XQQ\bmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8<R(!.ijTg?72is8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,.8@!.j9`k3(n,s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJDot!.h5&XQchdmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8*F&!.ijTg?I>ks8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k+q,>!.j9`k3;%.s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJW'!!.h5&XQQ\bmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8<R(!.ijTg?72is8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,.8@!.j9`k3(n,s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j-X8i6OXF[I(XOjQRmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g`g&M,(g4@t/g=P'Ys8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?ojo>C4k(2ZGk1Abqs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j+X8i6OXF[I(XP']Tmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g^g&M,(g4@t/g=b3[s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?mjo>C4k(2ZGk1Snss8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uDKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcBJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uDKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8j-X8i6OXF[I(XOjQRmf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g`g&M,(g4@t/g=P'Ys8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?ojo>C4k(2ZGk1Abqs8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i6OXF[I(XH0I_mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M,(g4@t/g5jtfs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>C4k(2ZGk)\[)s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i6OXF[I(XHBUamf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hQg&M,(g4@t/g6(+hs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@`jo>C4k(2ZGk)ng+s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i6OXF[I(XH0I_mf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M,(g4@t/g5jtfs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>C4k(2ZGk)\[)s8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:K)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJH3RZrs=8Vs4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKK)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:K*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJHE^gs7k=JJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKK*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcEUes7tCKJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcEUes8(ILJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc<Ods81OMJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc<Ods8:UNJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc3Ics8C[OJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc3Ics8LaPJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc*Cbs8UgQJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc!:as8ITI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJbm7`Jc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMmXaeWmYUB2ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+s+13$s,$dTgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:s+13$s,$dTec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!jo_F0eS9['JaS*WM!k8ms+Bh@#1]OLk2s>WJ,~>
-!<E0!jo_=2g4=hTJcC<$M#[J.s+0\>#25dNk2s5TJ,~>
-!<E0!jo_F0eVf"YJcC<$M#[J)s+Bh@#1]OLk2s>WJ,~>
-!<E0!joD3.eUc8%eUl<OKCAgEeYN6-k.LbF~>
-!<E0!joD*+g4@t/g4J#YJa`UCg7eQ/k.1PC~>
-!<E0!joD3.eUc8%eUl<OKCAgEeYN6-k.LbF~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g4@uGg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g4@uGg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joM:.JV/N+JV/Z/ldZ07s5rIW!.Y~>
-!<E0!joM10JUrB'JUrN+le2N9s5rIT!.Y~>
-!<E0!joM:.JV/N+JV/Z/ldZ07s5rIW!.Y~>
-!<E0!joM:.JV/N+JV/]0!<;B8"f21\k.LbF~>
-!<E0!joM10JUrB'JUrQ,!<;B="ektYk.1PC~>
-!<E0!joM:.JV/N+JV/]0!<;B8"f21\k.LbF~>
-!<E0!jo_F0K7id/!WTias+13$s/H#"^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_=2JV!F0!WU#fs+13$s/H#"_Z0Z._Z0Z%g'+2Mk2s5TJ,~>
-!<E0!jo_F0K7id/!WTias+13$s/H#"^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+13MrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<E0!jo_=2JV!L2s8N+N_L_`<s+13MrrI\frVuT.s8VE="ektYk.1PC~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+13MrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<Bh3S-%5nKD3(Ys8R]Q^&S+`eUc8%eZIC%K)iU^s7j;-s6J2=S@tG_!!%N~>
-!<B_0R0))nJbR%\s8RWO_Z0Xeg4@t/g9'*/JH3Ras7jJ2s6JABRC\fS!!%N~>
-!<Bh3S-%5nKD3(Ys8R]Q^&S+`eUc8%eZIC%K)iU^s7j;-s6J2=S@tG_!!%N~>
-!!)uB".[noKDE4Zrrpr*K>%<bJ^o>%J^pmQs+:Hfs8UX"rVu`-s8VE8"e<iN]po(Q~>
-!!)u?".@koJbd1]rrq,-J\qHeJ_G\/J_I6[s+(<is8Ug,rVu`2s8VE="e!NE\sWPK~>
-!!)uB".[noKDE4Zrrpr*K>%<bJ^o>%J^pmQs+:Hfs8UX"rVu`-s8VE8"e<iN]po(Q~>
-!<CCD]`XeTK7j'7rVulIs+:Bds8RZ#J^o>%Xk!H(!knX6rRLlHr4W.1ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!^8rVulNs+(6gs8RZ(J_G\/XkNf+!lG!;rS%5Mr5/L6le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j'7rVulIs+:Bds8RZ#J^o>%Xk!H(!knX6rRLlHr4W.1ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j-9rVufGs+:Bds8RZ#J^o>%Xk!H(!knX6qpkZFrk8@3ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!d:rVufLs+(6gs8RZ(J_G\/XkNf+!lG!;qqD#Krke^8le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j-9rVufGs+:Bds8RZ#J^o>%Xk!H(!knX6qpkZFrk8@3ldZ0/c+Uf\!.Y~>
-!<CCD]`jqVK7gkNrVu`Es+:Bds8RZ#J^o>%Xk!H(!knX6q:5HD!knX6ldZ0/c+Uf\!.Y~>
-!<C:A\cnMUJUt\TrVu`Js+(6gs8RZ(J_G\/XkNf+!lG!;q:bfI!lG!;le2N1b.>0P!.Y~>
-!<CCD]`jqVK7gkNrVu`Es+:Bds8RZ#J^o>%Xk!H(!knX6q:5HD!knX6ldZ0/c+Uf\!.Y~>
-!<CCD]`FYRqh+[os+:Bds8RZ#J^o>%Xk!H(!knX6pso=qs8VE8"e<iN]po(Q~>
-!<C:A\cJ5QqgnOrs+(6gs8RZ(J_G\/XkNf+!lG!;ptG[ts8VE="e!NE\sWPK~>
-!<CCD]`FYRqh+[os+:Bds8RZ#J^o>%Xk!H(!knX6pso=qs8VE8"e<iN]po(Q~>
-!<CCD]`jqVK7gkNrIasss+:Bds8RZ#J^o>%Xk!H(!knX6q:5Fr!knX6ldZ0/c+Uf\!.Y~>
-!<C:A\cnMUJUt\TrIOh!s+(6gs8RZ(J_G\/XkNf+!lG!;q:bdu!lG!;le2N1b.>0P!.Y~>
-!<CCD]`jqVK7gkNrIasss+:Bds8RZ#J^o>%Xk!H(!knX6q:5Fr!knX6ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j-9rIb$us+:Bds8RZ#J^o>%Xk!H(!knX6qpkXtrk8@3ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!d:rIOn#s+(6gs8RZ(J_G\/XkNf+!lG!;qqD""rke^8le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j-9rIb$us+:Bds8RZ#J^o>%Xk!H(!knX6qpkXtrk8@3ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j'7rIb+"s+:Bds8RZ#J^o>%Xk!H(!knX6rRLk!r4W.1ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!^8rIOt%s+(6gs8RZ(J_G\/XkNf+!lG!;rS%4$r5/L6le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j'7rIb+"s+:Bds8RZ#J^o>%Xk!H(!knX6rRLk!r4W.1ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j!5rIY:(K7gl;s+/^OeUc8Qec17)^&S,_ebt-s^&S,ueHMJf]tKp9J,~>
-!<C:A\c\ASJV!X6rIG.+JUt]<s+/mTg4@t[gAc^,_Z0YigAQU!_Z0Z%g'*ne]"4:0J,~>
-!<CCD]`XeTK7j!5rIY:(K7gl;s+/^OeUc8Qec17)^&S,_ebt-s^&S,ueHMJf]tKp9J,~>
-!<CCD]`XeTK7ip3r.>'as8RZ#J^o>%Xk!H(!knX6rIamYs8VE8"e<iN]po(Q~>
-!<C:A\c\ASJV!R4r.+pds8RZ(J_G\/XkNf+!lG!;rIOa\s8VE="e!NE\sWPK~>
-!<CCD]`XeTK7ip3r.>'as8RZ#J^o>%Xk!H(!knX6rIamYs8VE8"e<iN]po(Q~>
-!<CCD]`XeTK7ij1rdt9cs8RY&JV/N+X+LPgs8R_(p:^M+ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!L2rdb-fs8RY$JUrB'X+:Djs8RY$p;6k0le2N1b.>0P!.Y~>
-!<CCD]`XeTK7ij1rdt9cs8RY&JV/N+X+LPgs8R_(p:^M+ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7id/!e\2dJV/N+JV0tT!knVdoY(;)ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!F0!eJ5gJUrB'JUshP!lFtgoYUY.le2N1b.>0P!.Y~>
-!<CCD]`XeTK7id/!e\2dJV/N+JV0tT!knVdoY(;)ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7eaTJcC<$L]?\j"e<iN]po(Q~>
-!<C:A\c\ASJUrCPJcC<$L]?\o"e!NE\sWPK~>
-!<CCD]`XeTK7eaTJcC<$L]?\j"e<iN]po(Q~>
-!<CCD]`O_SK7X&Rs+13)s6J2=SB\a\S,e'~>
-!<C:A\cS;RJV!iPs+13)s6JABREE+PR/ha~>
-!<CCD]`O_SK7X&Rs+13)s6J2=SB\a\S,e'~>
-!<CCD]`=RReUc8%eUc9=eHMJf]tKp9J,~>
-!<C:A\cA.Lg4@t/g4@uGg'*ne]"4:0J,~>
-!<CCD]`=RReUc8%eUc9=eHMJf]tKp9J,~>
-!<CCC^%%VDUk,=mUlM5N^%.Znc2PBWS,e'~>
-!<C:@]()2>Tn/ngToPfH](26hb5SsQR/ha~>
-!<CCC^%%VDUk,=mUlM5N^%.Znc2PBWS,e'~>
-!\j]"rOqgI!53s`JcC<$NrSXork/B'!&9!~>
-!^m%2rOVUC!4ma]JcC<$NrSXlrji0!!(;>~>
-!bq_[rOqgI!53s`JcC<$NrSXork/B'!-<Y~>
-!\j]"n%A^kJ`_OGJ``!T!6suG!h96NJ,~>
-!^m%2n%&LeJ`_OGJ``!T!6XcA!gs$VJ,~>
-!cn@dn%A^kJ`_OGJ``!T!6suG!h973J,~>
-s#C,\S=K,_!1\W&J`_OGNog>dn\+sm!WY58J,~>
-s$QngR@3TV!1AE#J`_OGNog>an[eag!WYVVJ,~>
-s)S5AS=K,_!1\W&J`_OGNog>dn\+sm!W[:_J,~>
-">Mnk!!)MYJ\?WJJ\@&VnXTUZs"OL6J,~>
-r^?bdn<nj=J\$EDNOnYJrrE$dJ,~>
-rcA)>n=5'CJ\?WJNP4kPrrE%>J,~>
-rAaj4JH16$JH16$li7#?r]'s5J,~>
-r'Z)9JH16$JH5$:r'Z&~>
-r,[DhJH16$JH5$:r,[A~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/megaco_tracer.gif b/lib/et/doc/src/megaco_tracer.gif
deleted file mode 100644
index cc4f747f03..0000000000
--- a/lib/et/doc/src/megaco_tracer.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/megaco_tracer.png b/lib/et/doc/src/megaco_tracer.png
new file mode 100644
index 0000000000..b4b65a9f47
--- /dev/null
+++ b/lib/et/doc/src/megaco_tracer.png
Binary files differ
diff --git a/lib/et/doc/src/megaco_tracer.ps b/lib/et/doc/src/megaco_tracer.ps
deleted file mode 100644
index da1e1b6ba0..0000000000
--- a/lib/et/doc/src/megaco_tracer.ps
+++ /dev/null
@@ -1,2508 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/megaco_tracer.ps
-%%CreationDate: Mon Oct 14 17:35:19 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 443 516
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 501.599409 translate
-428.031496 -501.599409 scale
-% Image geometry
-512 600 8
-% Transformation matrix
-[ 512 0 0 600 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 512 string def
-/gstr 512 string def
-/bstr 512 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 143198 ASCII Bytes
-colorimage
-">Mns0fadbJH16$MZ<c<1&a1`~>
-r'Z)9JH16$MZEZCJ,~>
-rc8*TF+F=B!.b-.!;png~>
-"?A1s!!)Qh!53s`JcC<$fDbiaa8c/>!\l\qJ,~>
-r^?bdnc&U'JcC<$JcF@%!5?MRrrE$dJ,~>
-rcA)>nc&U&JcC<$JcF@%!56GQrrE%>J,~>
-">Mn:s8VWG!53s6J^o>%f@9l7a56ja!WY58J,~>
-s$Qngs8VWC!5=$8J_#D'f@Br9a4gR]!WYVVJ,~>
-s)S5As8VWG!53s6J^o>%f@9l7a56ja!W[:VJ,~>
-!]^8\n(n&XJ^o>%J^rB&!56A.!lY."J,~>
-!^m%gn(IcUJ_#D'J_&H(!5?G+!l=q*J,~>
-!cnAAn(n&XJ^o>%J^rB&!56A.!lY.\J,~>
-!\j]Tn(n&XJ^qcj!6(hc!6'N>n'qEO`SL[8!',Q~>
-!^m%gn(IcUJ_%il!QrigecEqAJ_'>A!5?G+!l=q*J,~>
-!bq`8n(n&XJ^qcj!6(hc!6'N>n'qEO`SL[8!-<Y~>
-!<E/fh>k6HeH(;L`75%1Ut*/*HiB90eH(;LYLN]fH[GaVs4%.&HgoPdUqMW8!57RPpRLp5s.'&E
-s.'#D!NZ9O~>
-!<E/fg&SjEf)L<>edTEhf"Q]`R?<W_eq&CUed9'AI@64[f%,D'nC@W6^5:D@^?=5ERJ#;6RJkk>
-RJbb>XoNt~>
-!<E/fh>k6HeH(;L`75%1Ut*/*HiB90eH(;LYLN]fH[GaVs4%.&HgoPdUqMW8!57RPpRLp5s.'&E
-s.'#D!NZ9O~>
-!<E/thZ',ChZ',Eh>k7dec0srMuM6.UjIaFeH*Y&eCFGC!/(-u!J>a^eI9ELe^_X/K6r6@c./'U
-HNBA]r-JI&^&-=l`I"uBMgNFnPa'_KK6u/!`P&V.%?#SPeWc<KeUr5!e]#5oeH3+)`JW1G^$"8H
-SG(h<SH%IESGh:FX8mb~>
-!<E/tf)M08f)M0:ec<G]df4^qNW.?-Tm_XGdK.4neC">Jr-\R!qU5CpkL'dQL!nDhR>$'CS]]BG
-qgAO.dXh@F!K"PfdLj?I[aL.``m0^/daE\tdaH"@ZdK;BIE'QpOj_[/J^Vu`[e.uL[XGlIdK%#E
-f(YU+f);$:f);$8ecDoRJ,~>
-!<E/thZ',ChZ',Eh>k7dec0srMuM6.UjIaFeH*Y&eCFGC!/(-u!J>a^eI9ELe^_X/K6r6@c./'U
-HNBA]r-JI&^&-=l`I"uBMgNFnPa'_KK6u/!`P&V.%?#SPeWc<KeUr5!e]#5oeH3+)`JW1G^$"8H
-SG(h<SH%IESGh:FX8mb~>
-!<E/uhYiuChYiuDh>k7dec'n!c.1?sH\9o"!J>aKec1!o^&$7[K6ue3)l0"S`IiN=]qg"-c,IB0
-H[EH>`RT<^]tL4gKDX1&Mj2cBK7!LG"bV0PeUr4TeH(;Lqpbk&He$Z!Hh5bgP`(FL!57RPpRLs6
-pRM3=!NZ9O~>
-!<E/uf);$8f);$9ec<G]df+Xub0n^lI>-8#s+/\J!J,[t\cBJ@df4m]dMo$Rd`-idV7NLOL!%9D
-\p]"<]#)mHJ\&FdI>RjL"c8MmdXcuHdf4mudf4m)df4mqdf4mudf4midK,ViMUDL=kLTBqp=Au+
-rRM"P!.Y~>
-!<E/uhYiuChYiuDh>k7dec'n!c.1?sH\9o"!J>aKec1!o^&$7[K6ue3)l0"S`IiN=]qg"-c,IB0
-H[EH>`RT<^]tL4gKDX1&Mj2cBK7!LG"bV0PeUr4TeH(;Lqpbk&He$Z!Hh5bgP`(FL!57RPpRLs6
-pRM3=!NZ9O~>
-!<E/uhY`oDhY`oCh>k7deJ!:^HaM>BH\6t$e]!GnK='1Z`K^=J'\10eH[C[ie^^aZH[C[qeZ=[U
-Mlcg+!2TU@*lX%qXGb&^H[C[ie^^aZH[C[qe]!GnK='1ZMi4Zpo[WtgqUPV((T`PFK6u.fP^@b8
-`RWLsMnOai[+3^GPl5t.eHLlEeWbE^rm_(GH^t)cs*O^ps*Oaqs*O[o"MK/qeXZVc#gJ!Ke^];!
-eYN1ks2>D)H\8]UeVf?eMq*H,qpk_)'"rpE['YI4[+3^GMgL)`e^_X'rHf7/`KY^rMoF5sXG_FP
-Mp9eRMgLA`psfA7rd+pqK6u/!K6u.Erd4[a%?#Rc[+3]bMl_ie]mIGNeH!;GhY3Q5hYE]>h>s\X
-J,~>
-!<E/uf)1s9f)1s8ec<G]dM%%_IBq;<JUrO'd__,pKsK.T_NFeF'[k!`JUNNldaG:TI=6spd]SFT
-M6?a(!29C?*l<nrV2`KWJUNNldaG:TI=6spd__,pKsK.TNK'coo[3bkIJVClN>JFNdXctt`fYh#
-NP<ihNK(N'J[3_P_NFeFrmCt0]$cjlY5ZiNV1"p6dK+oIrR1^srmLgpr6b_ZICdjprd>'pJUu7t
-JUu7CrdFg`%$>slZI70\NMVW_JV!^Hs,@Z"Kn6D8Kn6PXd__,pKsK.T_NFeF'[k!`JUNNldaG:T
-I=6spd]SFTM6?X%!1Eh7#g.^LdaE\td\6Ygs2#5-I>+uTdZ'6_NRG7`\r4u:^?=)ARJ#/,RJbV:
-XoNt~>
-!<E/uhY`oDhY`oCh>k7deJ!:^HaM>BH\6t$e]!GnK='1Z`K^=J'\10eH[C[ie^^aZH[C[qeZ=[U
-Mlcg+!2TU@*lX%qXGb&^H[C[ie^^aZH[C[qe]!GnK='1ZMi4Zpo[WtgqUPV((T`PFK6u.fP^@b8
-`RWLsMnOai[+3^GPl5t.eHLlEeWbE^rm_(GH^t)cs*O^ps*Oaqs*O[o"MK/qeXZVc#gJ!Ke^];!
-eYN1ks2>D)H\8]UeVf?eMq*H,qpk_)'"rpE['YI4[+3^GMgL)`e^_X'rHf7/`KY^rMoF5sXG_FP
-Mp9eRMgLA`psfA7rd+pqK6u/!K6u.Erd4[a%?#Rc[+3]bMl_ie]mIGNeH!;GhY3Q5hYE]>h>s\X
-J,~>
-!<E/teb>U4eH!;[bq4:4H^)dNP_4V5`IifVP^CBoK7h.fK6tkVXM(ufMp8&EMmTje`N4EN]p*lF
-r66G)H[EHNK6rNP]r\oSH]-.EH],8<UrC<*K>!Lr`Qa$^Mkp!is*O^XrlldBH]+]EK6tkVXM(uf
-Mp9M!H]+D@K?_YnK>l)fHd0gSHd0f^Hc?!/!kir5rltIirQY@hs31V@H].gH,+O#!c,G$V^!21V
-c-:lfc,G$V]u>VV]p*l_c%CA$Us4gMqopaGH]+D@H]+D@K?_AfK>!Lr`Qa$f`Qa$^c+U3l[!R_U
-UjJ$,[%t[BH^)4.H`[%f+2rSR^!21Vc-:lfc,G$V]u>VV]p*l_c%CA$Us6l*S;YVl^$!oGSGC\8
-SFkA/SGUh;X8mb~>
-!<E/tdeB1.dK%#Yc7OI8I?i*SR>$@?b(58XQ$pZpJVCtdKmh7\Y.h>mM9_rGM6aRi`i=HP^6O,H
-r6?M+JUPD\JUNBO^952YI>Q7GI>P8<WlE24Kt<Ot`m0-`M5Bji!J,[t\gbeIc@LD#V9XXCcG$Hq
-[XF"Xc@LD#Tm_X?b(58`c@p\lcGkFXc@(,\rltS^I>.[G!J,[tcMrFucH;u3Oo3KKTmar+`drQT
-c@LPlc@LPl`drQT`driTQ$pZtJUNBOcA@DTc7XZrNM1cKNM1cScH:]l\s7]`b(58`c@p\l^952Y
-I>Q7GI>P8<WlD&eQ+iN3Wqjp^`drQTc@LPlc@LPl`drQT`driTQ$pZtJUNBOcGk:+Mp;=:kL'?u
-q9f82o[<W)qpGMJ!.Y~>
-!<E/teb>U4eH!;[bq4:4H^)dNP_4V5`IifVP^CBoK7h.fK6tkVXM(ufMp8&EMmTje`N4EN]p*lF
-r66G)H[EHNK6rNP]r\oSH]-.EH],8<UrC<*K>!Lr`Qa$^Mkp!is*O^XrlldBH]+]EK6tkVXM(uf
-Mp9M!H]+D@K?_YnK>l)fHd0gSHd0f^Hc?!/!kir5rltIirQY@hs31V@H].gH,+O#!c,G$V^!21V
-c-:lfc,G$V]u>VV]p*l_c%CA$Us4gMqopaGH]+D@H]+D@K?_AfK>!Lr`Qa$f`Qa$^c+U3l[!R_U
-UjJ$,[%t[BH^)4.H`[%f+2rSR^!21Vc-:lfc,G$V]u>VV]p*l_c%CA$Us6l*S;YVl^$!oGSGC\8
-SFkA/SGUh;X8mb~>
-!<E/sebPa5eH!;[bnk`&P^CZ5["F"UXF$J^XF%%MH^r@*K7!UB#K=B/K?]$q`Vn$cK6tS^`I!77
-blr`Hc-:lfrQPSd]n:s^K6tT9bmCIuSB\-^XNcBEqoo5=H[CDCc22hj^!4fSHiD7jK7!UB)o]LC
-K?_YnHc=6VHd/X=SB]<2Hd0g:Pg.I"Hi;1j`Hut2c2W.hc2;nhMoGV=!L.s1bnu([c-:lfc-:lf
-c-:lfc)c8^c)c8nc%CB:bnu([`Q`aV`Q`aVc)c8^c)c8nXF$J^c%CBBbm25$K7hF$Hc>s.#(q9A
-c,G$^prsY.Hd0ffHd0ffHd0ffHd/X=SB\-^XNcBErQP@iP`*cd^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/sdeT=/dK%#Yc51o*Ob(Z3ZA""XY'm"dY'mIYI@\[/KmisG#K"3+L!GC#_YqaaM1*Ch`dN^@
-cMrIqc2rQFb5TZk_S1STc@p\`rQYbQIA+fdIBLkHIEMK5"/UEoM>YX!Jc'p&^<Y#TIEKj\JV!gG
-)oB=?L!ItpIE'Q`J^1QLS^,N7IEp-@Q-RO#IJqFmb'e^;c2iKErQYCorI"^'_Yh[[Q$rYWs+13q
-s+13qs+13qs+(R'Y'm"dY'mIuJUP]8c5;+\b0GQdb0GQhcE;Shb-$/qZ@/:hc@p]Gc3M5#JVDC'
-IDYs.#)RcJcGk9hps/njs3CXqs3CXqs3CXq$dPo'TusNdY0MTHb5TZeI?f`9!5@XE!1EZ2!1EK-
-qjI?0!NlEQ~>
-!<E/sebPa5eH!;[bnk`&P^CZ5["F"UXF$J^XF%%MH^r@*K7!UB#K=B/K?]$q`Vn$cK6tS^`I!77
-blr`Hc-:lfrQPSd]n:s^K6tT9bmCIuSB\-^XNcBEqoo5=H[CDCc22hj^!4fSHiD7jK7!UB)o]LC
-K?_YnHc=6VHd/X=SB]<2Hd0g:Pg.I"Hi;1j`Hut2c2W.hc2;nhMoGV=!L.s1bnu([c-:lfc-:lf
-c-:lfc)c8^c)c8nc%CB:bnu([`Q`aV`Q`aVc)c8^c)c8nXF$J^c%CBBbm25$K7hF$Hc>s.#(q9A
-c,G$^prsY.Hd0ffHd0ffHd0ffHd/X=SB\-^XNcBErQP@iP`*cd^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/rebbm6eH!;[bmJfnXF$aic%CYnV#5T>U^qgJc-:lfc+Sa^MgL*$H[G\8s*Oais*OXf&;,>S
-c%CAfc+Sa^MgL*$H[G\8!2TO>"/O1oHi)%i`P&t(r6>7gqTT%nHiD85K6tkVK7f)/K?_YnHd0ff
-Hd/@5Us7/:Hd0g"XNf":Hc?!/!kir5rltIirQY@hs0MdFqTT&*HiD8#K6tkfK6tkfK6tkfK6tk=
-r-JOAc%CB:bmT/Nc-:lfc-:lfc(t8as.g0PUs7/:Hd06VK8Y)/c$Og8c2W.ic2W.cbn#GRc-:lf
-c-:lfc-:lfc(t8a"/O1oHi;1iH^'H5!58<\!582u!58*V!1`l8!1``4q4.B5!NZ9O~>
-!<E/rdefI0dK%#Yc3eurY'm<ub(YPpV>PcAV%8!JcH_,lcFS^\NI?N+I=;%=!J,[ucMr=icMrIq
-cMrIqc3V"8JW5)3c@(-=c2a^=I06=kJV!^D!6Y;Xr6>=oIJV7hJc<spJKN1KKn553L!ItpJ^2Pl
-J^1*?U!Cr;IEp-#Y0P=@IE)93!lBA>rltOqIJqIkJcE:]_YVOYQ$rYWs+13qs+13qs+13qs+(3r
-V>P`DV9XXCp<N\hs3CXqs3CXq!R@P>IK-,SIA+s3Kmh7XKn553L!G*pr6>=oIK%OlIJD+fJcF$q
-JcF$qJcF$qJH=&mr-\[Dc@LQFc2i?YMp;=:r6bSVq3_5op<ir/q9f82p!WZ(r6bVK!.Y~>
-!<E/rebbm6eH!;[bmJfnXF$aic%CYnV#5T>U^qgJc-:lfc+Sa^MgL*$H[G\8s*Oais*OXf&;,>S
-c%CAfc+Sa^MgL*$H[G\8!2TO>"/O1oHi)%i`P&t(r6>7gqTT%nHiD85K6tkVK7f)/K?_YnHd0ff
-Hd/@5Us7/:Hd0g"XNf":Hc?!/!kir5rltIirQY@hs0MdFqTT&*HiD8#K6tkfK6tkfK6tkfK6tk=
-r-JOAc%CB:bmT/Nc-:lfc-:lfc(t8as.g0PUs7/:Hd06VK8Y)/c$Og8c2W.ic2W.cbn#GRc-:lf
-c-:lfc-:lfc(t8a"/O1oHi;1iH^'H5!58<\!582u!58*V!1`l8!1``4q4.B5!NZ9O~>
-!<E/qebu$7eH!;[bm\rp`Hurrc%CYnXF$K9bn7%(SB]<*Hd.Iqc-:lnc%CAVrQPP!Hc=7KH\;4?
-&VGGTc%CAfc&6qnc%CYnK6t<1blXtnSG^V4K7!16s*OUe!J>auboq^dc&6qnc%CYnc%CAfc%CAf
-XF$J^c$Of^c$RFSc'3RVrlkM?H^t)[s*O^hs*OLb(8Q;rc-:lfc-:lfc-:lfc-:lfc)c8^r657p
-HhP\nK6tkfK6tkfK6tkEH^t&Z&Zg>Lc-:T^c&6qnc%CYnK6t<1bm&fI`QcAKKD<\'K6tkfK6tkf
-K6tkfK6tkEH^t#Y!J>aublYk2S;YVl^&6FTSG(J5SGC\8SG(M-SGgt=X8mb~>
-!<E/qdf#U1dK%#Yc4#,t`dN9#c@pttY'm#Bc4R4-REis+IEmh'b0G]pc@p\\rQYV(IE'RPI>RjH
-s+13qs+13q$&sMYc@pttKmg]6c2t.sU&<49Jb%(eJURC?s+10ps+)9;NIf6tKn[gtJUu+lJUu+L
-I@8C'JUPhdIE'RXQ$o\3c2s\fRJtJ4JURLBs+0pi(86/rcH^ulcH^ulcH^ulcH^ulcE;Shr6G=n
-p<N\hs3CXqs3CXq"4"&tU&E7KY'l_`b(4udNIf6tKn[g+ID5[*#)RcJcGk9hps/njs3CXqs3CXq
-s3CXq"4"&tU&<49Jc<pr`dOP=c2bTVdeB1'dK#^2dK#^/deB1.dK-KNJ,~>
-!<E/qebu$7eH!;[bm\rp`Hurrc%CYnXF$K9bn7%(SB]<*Hd.Iqc-:lnc%CAVrQPP!Hc=7KH\;4?
-&VGGTc%CAfc&6qnc%CYnK6t<1blXtnSG^V4K7!16s*OUe!J>auboq^dc&6qnc%CYnc%CAfc%CAf
-XF$J^c$Of^c$RFSc'3RVrlkM?H^t)[s*O^hs*OLb(8Q;rc-:lfc-:lfc-:lfc-:lfc)c8^r657p
-HhP\nK6tkfK6tkfK6tkEH^t&Z&Zg>Lc-:T^c&6qnc%CYnK6t<1bm&fI`QcAKKD<\'K6tkfK6tkf
-K6tkfK6tkEH^t#Y!J>aublYk2S;YVl^&6FTSG(J5SGC\8SG(M-SGgt=X8mb~>
-!<E/pec208eH!;[bq4:<c&6qMc%CYnc%CA=[&gXRH[DQHH[F"qH`X;qHbHM-K<2bf`N4EN]p*lF
-qop48HaM%MHd0fnH`X;qHbHM-K<2bf`Qa$^UpR51c%CB6c2W.g[/\AOK7!UB)hWL^MgMP,H[EHN
-K6tkfK6tk^H[DQHH[F#EMuLs,]mG+%[%r&$`W"-^Hi;4hHhYc*]mI-2c%CAfc%CAfc%CAfc%CAM
-`IiN5[&gXZK7!UB!K2U-bq=Wqc-:lfc-:lfc-:lfUpR51`Hus-MgKfqMgMP,H[EH-H\8E5XMq8f
-PeE<.XSC$WK6tkfK6tkfK6tkfK6suEK6sE$XL-6)HiD7k[!TKEblGHTeb>U-eGu-8eGu-5ebu$<
-ebu$:eH)`OJ,~>
-!<E/pcMs1*c2bTUat8%8b)(PLb(YPl`eAi;[]ZpQI=7fGI=97pIB';qID2_0Ks%ka_Q&$L\s7]?
-qoU";[email protected]]c,lIB';qID2_0Ks%ka_T%:XV7*P4b(5-7aoR'Ar3?FEb(5-Cb5[#1b)(PHWdT<0
-b(5,db(5,d_L6j+M1'fpZAJS'#ekk<TsCA?J\qE/!J,[tb5[%earS'AY0+n<J]c,dJ]c,dJ]c,l
-IC@"HIAOBTZH@`LrlY7tqo\qis2t@ms2t@m,g+,\IAOBTZGM$<To"2Gb)(PHWdT<0WdTT([]73E
-I?hC/IAQ_]s+13ms+13ms+13m%#KD@_M*E7[]ZpYJV!gC!j6s[Mol%6r6G&%p<EZ'q9Au*p<NW%
-s3CS.rQYGH!.Y~>
-!<E/pec208eH!;[bq4:<c&6qMc%CYnc%CA=[&gXRH[DQHH[F"qH`X;qHbHM-K<2bf`N4EN]p*lF
-qop48HaM%MHd0fnH`X;qHbHM-K<2bf`Qa$^UpR51c%CB6c2W.g[/\AOK7!UB)hWL^MgMP,H[EHN
-K6tkfK6tk^H[DQHH[F#EMuLs,]mG+%[%r&$`W"-^Hi;4hHhYc*]mI-2c%CAfc%CAfc%CAfc%CAM
-`IiN5[&gXZK7!UB!K2U-bq=Wqc-:lfc-:lfc-:lfUpR51`Hus-MgKfqMgMP,H[EH-H\8E5XMq8f
-PeE<.XSC$WK6tkfK6tkfK6tkfK6suEK6sE$XL-6)HiD7k[!TKEblGHTeb>U-eGu-8eGu-5ebu$<
-ebu$:eH)`OJ,~>
-!<E/feH!;[bq+4;c+U4'c%CYnc,GooH\8EEXFl/4K6tkMK6s,aH^r?^MgKf/`QbK:H\8Erboa<F
-HbG&Yc-<VJH^pmYSB\-nH[C[ic,GooH\8EEK7!16qKi=Xc%CBBbo;:^c*W+MS>:M%c%CAfc%CAf
-c)cPM["E_MS>?,.#/ugZH\7j-rQY@hrQY@hp<EVqs32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBE
-rlkIrHi)&>K6tkfK6tkfK6tkf`KY^rK<3>!K7gO`Hd/pMH^pmYSB\-nH[C[ic)cPEK<4gl(k[1[
-c%CAfc%CAfc*W+M]u?4_H\8EEK7!UBs,2cZ!58<\!582u!58*VpRLp,s.'&<s.'#;!NZ9O~>
-!<E/fc2bTUat.t7b.=Umb(YPlb/0EpI>+iHY(;;4Kn7CTKmfMcI@86XM1'f/^<3:+I>+]tardp?
-J\$D`b0%/HI@['[REDOdI=6sdb/0EpI>+iHJV!C7!.k#q"1lX+Jc<glJJlV=KmfMcI@86/J]c,d
-J]c-<JVCC`J]aCSrQ5>YQ%=@;RDSpF!J,[tb5[%db5[J$b5[%mb5[%mb5[%mapbS,J\&^`JUN6T
-b(5-Cb5[%ib5[%mb5[%mb5[%mas"WeJUN6Tb-$;LZA!kP[Y9.#Tm`?OWel.PM8%-/KmeZTpWEMe
-s2t@ms2t@ms2kbUJUtDLQ%=@;Y0)<HrlY8#MTPq5r6>;Nq3:rgp<NDtp!3T&rQbG.r6>>G!.Y~>
-!<E/feH!;[bq+4;c+U4'c%CYnc,GooH\8EEXFl/4K6tkMK6s,aH^r?^MgKf/`QbK:H\8Erboa<F
-HbG&Yc-<VJH^pmYSB\-nH[C[ic,GooH\8EEK7!16qKi=Xc%CBBbo;:^c*W+MS>:M%c%CAfc%CAf
-c)cPM["E_MS>?,.#/ugZH\7j-rQY@hrQY@hp<EVqs32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBE
-rlkIrHi)&>K6tkfK6tkfK6tkf`KY^rK<3>!K7gO`Hd/pMH^pmYSB\-nH[C[ic)cPEK<4gl(k[1[
-c%CAfc%CAfc*W+M]u?4_H\8EEK7!UBs,2cZ!58<\!582u!58*VpRLp,s.'&<s.'#;!NZ9O~>
-!<E/feH!;EblN0DOj+#UK?]%^hou5AK<3&:!IKIac2)be^#mQ@XFnKLblGGqeH)`OJ,~>
-!<E/fc2bT@ao]S2Kp'R^`dNQ`Kt?0a!lBMb`l\A&I>-t/qL&@Tk/mb*J\m;e!5?Cs!NlEQ~>
-!<E/feH!;EblN0DOj+#UK?]%^hou5AK<3&:!IKIac2)be^#mQ@XFnKLblGGqeH)`OJ,~>
-!<E/fblGHB`<N]6Uo]K$S<h,"[$7AfMgLu$KAFKI]qifi#.0VjXG_Fqa2J(T]ns].]u8.rX8mb~>
-!<E/faoK0@`Wil6WiD&,TpE\([ZRSiNI@M/J_e<H^7i]h#.BYoWf;G#a2S.R^59i0^;S.pXoNt~>
-!<E/fblGHB`<N]6Uo]K$S<h,"[$7AfMgLu$KAFKI]qifi#.0VjXG_Fqa2J(T]ns].]u8.rX8mb~>
-!<E/fblGHB`<Er>K6r6HQ,O$BP_4=8UrC$SUr<MNP_4=8Uk-M/`;mTiblOmGJ,~>
-!<E/faoK0@`Wa)=JUN6GQ,X*DOb%q7TuOgXUrESPOb%q7Tn15-`W3`kaoSXFJ,~>
-!<E/fblGHB`<Er>K6r6HQ,O$BP_4=8UrC$SUr<MNP_4=8Uk-M/`;mTiblOmGJ,~>
-!<E/fblGG.`IZ!Z`Ri'/]u8.rX8mb~>
-!<E/faoK/,`du-\`n/31^;S.pXoNt~>
-!<E/fblGG.`IZ!Z`Ri'/]u8.rX8mb~>
-!!%S&JV/N+K7a.(J,~>
-!!%S$JUrB'K7O"&J,~>
-!!%S&JV/N+K7a.(J,~>
-!<E0!joD3.s+13$s,I$^V#TT>]`<Q~>
-!<E0!joD*+s+13$s,I$^U&X9;\c@6~>
-!<E0!joD3.s+13$s,I$^V#TT>]`<Q~>
-!<E0!joD3.s+13$s,R*`K;AP0k.LbF~>
-!<E0!joD*+s+13$s,R*`JYE,+k.1PC~>
-!<E0!joD3.s+13$s,R*`K;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:AM?!<(XM!7T[#!;Y@K!!:jS!:eeC!9W#2!!_-W!8?-,!9W#8!<1^P
-!;Y@K!.ijTg?@8jJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:AM?!<(XO!7KU$!<:dQ!;bFL!!:jS!:eeC!9W#8!;bFL!<:dQ!9W#8
-!<1^P!;Y@K!.ijTg?@8jJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9=ec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<:dQ!!M!U!8?0*!<:dQ!<:dQ!<:dQ!<:dO!<:dQ
-!!:jS!;,"F!;kLK!<:dQ!!M!U!8?0*!<1^N!<:dO!<:dO!<:dQ!!:jS!;,"F!<(XO!!CpT!8@AO
-s4[DOs4[JQ!nmVSo\0<Frn@APs4[DOs4[JQ"kiqVg&M,(g4@uGgAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9=ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(N
-k2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Es4[JQ*81Amg&M-,g&M-,!!(a,!!(a,!!(^Q
-!8?-,!8@>No\0<Fr7_/Ns4[JQ+PHeqg&M-,!!(a,!!(^Q!8?-,!8?-,!8?-,!8?-,!8@>No\0<F
-rS%8O&)%!`g=cN,g=cN,g=cN,gACsCgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTg@*bqJH_bI
-k2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(N
-k2s>WJ,~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%n(%Gj"f21\k.LbF~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA_0QgA_-mg&M-,!!(a,!!(a,!!(^Q!87DQg=cN,
-g=cN,gAV*CgA_0NgA_0QgA_-`g&M-,!!(^Q!8?-,!87DQqqD&Ms4[JQs4[JQ!8@DPo%O!A'&!<c
-g&M-,g&M-,g&M-,g&M-,rW)NCq>_)\!!(a,!!(^Q!87DQg=cN,J_G\/n(Rem"ektYk.1PC~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%n(%Gj"f21\k.LbF~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^s5>s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo%F?Lg=cP\g&M-,qZ-ZMrr<;X!!(^Q!8?0(!!:jS!:eeC
-!;tRN!<:dQ!!_-W!87DQgA:jOg&M-MgA_0QgA_0QgA_-Sg&M-CgA_0OgA_-Yg&M-,g&M-,gA:jO
-g&M-CgA_0PgA_-QgA:jVg&M-,!!(a,!!%T(J_KSHs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^s5>s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[OeaM&gK*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQmb7U>s4[JQ!nmVSqqD&M$/,@Zg&M-,g&M-NgA_0CgA_0N
-gA_0QgA_-Yg&M-,!!(^Q!;tRN!;kLM!<:dQ!<:dQ!!:jS!:eeC!<(XO!".E[!8?-,!8?-,!;tRN
-!:eeC!<1^P!!:jS!;tRN!!_-W!8?-,!.ijTg@*bqJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[OeaM&gK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(Nk2s>W
-J,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,n_4!Crn@AP#20%Wg=cN,rn@APs4[JQrn@APs4[JQ
-!nmVSnCmmBs4[DOs4[JQ(tnrig&M-,!!(a,!!(^Q!8?-,!8?-,!8@DPs4[JQ!nmVSn_4!CrS%8O
-#MK.Xg=cN,gAV*PgA_-Sg&M-CgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTg@*bqJH_bIk2s5T
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(Nk2s>W
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%ma_>i"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:\_B!<1^P!<:dO!<(XO!<:dQ!<(XM!<:dQ!:SY?!<:dO
-!<:dQ!!M!U!8?0*!<1^N!<(XO!<:dO!<:dQ!:eeC!<(XO!!:jS!<1^P!<:dO!<:dQ!:eeC!<1^P
-!<:dO!<:dQ!!V'V!87DQJ_G\/mb7\l"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%ma_>i"f21\k.LbF~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+,fRK7SZ9K*A(Nk2s>WJ,~>
-!<E0!joV7Vs+,`PJUrB5JH_bIk2s5TJ,~>
-!<E0!joV@Ys+,fRK7SZ9K*A(Nk2s>WJ,~>
-!<E0!joM:XJV/N+JV/u8"f21\k.LbF~>
-!<E0!joM1UJUrB'JUri4"ektYk.1PC~>
-!<E0!joM:XJV/N+JV/u8"f21\k.LbF~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD*+g>Uc`!;>.H!;P:J!!:jS!;kLM!9`)9!.ijTg@<l#U&X9;\c@6~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD*+g>Ucc!<:dQ!;G4I!;5(G!;kLM!9`)9!.ijTg@<l#U&X9;\c@6~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD+Hg@kRBgA:l+gA_0PgA_0QgAM$OgAM$OgAM$OgA_-Sg&M-MgA_0NgAM$OgA_0PgA_0Q
-gAM$OgA_/(g4@uJg'+2Mk2s5TJ,~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+Hg@tUIJbe%"!/0)+!<1^P!#XDi!8?-,!8?-,!8?-,!8?-,!87DQg&M-MgA_0OgA_0Q
-gA_-Sg&M-PgA_-Zg&M-,g&M-,!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%n^Rf=s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_-Tg&M-,r;ciNr;clOquHcNr;`_KrrE&Prr<D[!!(a,!!(a,
-!!)oMrr<5V!!(^Q!;kLM!<(XO!<:dQ!<:dQ!"IW^!8?-,!8?-,!87DQJ_G\/n_+/?s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%n^Rf=s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0OgA1gLgA_-Wg&M-,g&M-OgA_-Wg&M-,g&M,NgA_0PgA_-QgA:mM
-gA_0PgACpSg&M-,!!)oMrrE#OqZ-ZMrr<2U!!(a,qZ$]O!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gACpNgAV*PgA_0QgA_-Wg&M-,g&M-PgA_0QgA_0QgA_/NgA_0PgA_-S
-g&M-MgA_0QgA_0QgA_-Vg&M-,!!)oMrrE#OrrDoLrW)rOrrDuNrr@W(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA:jMgA:mLg&M-PgA:lJgA_0QgA_0QgA_0QgA_0QgA_-Q
-gAV*PgA_-Vg&M-,!!)oMrrE#OrrE)QrrE&PrW)rOrrE)Qrr<,S!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0NgA_0MgA_0PgA_/JgACsLgAM$MgA_0QgAV'PgAM!Q
-g&M-MgA:jMgAM$Lg&M-NgAM$OgA_/(g4@uJg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%e("Vt
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0QgA_-Zg&M-,g&M-,!!)uOrrE)Qrr@W(J_G\/e(Ou!
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%e("Vt
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e^DtOV#TT>]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0OgAM$NgAM$OgACsNgAM#&g4@t/g="[YU&X9;\c@6~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e^DtOV#TT>]`<Q~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tTg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!e_em\V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0OgAM$NgAM#&g>CTfU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!e_em\V#TT>]`<Q~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tpgAM$NgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD4Keb4Xkec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\Y
-eHMcKk2s>WJ,~>
-!<E0!joD+Hg@g*ngA_0PgA_-Sg&M-NgA_0FgA:m1gA(`"g8is-!<1^P!<:dQ!!_-W!8?-,!.ik^
-g'+2Mk2s5TJ,~>
-!<E0!joD4Keb4Xkec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\Y
-eHMcKk2s>WJ,~>
-!<E0!joD4Keb=[rs7t4F!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#e_ns]
-V#TT>]`<Q~>
-!<E0!joD+Hg@p-us7tCK!<1^P!;Y@K!;,"F!8Q<.!.ik&gA_0PgA_0QgA_-Wg&M-,g&M,(g>LZg
-U&X9;\c@6~>
-!<E0!joD4Keb=[rs7t4F!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#e_ns]
-V#TT>]`<Q~>
-!<E0!joD4Kec19uXT/=rec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!hphn+s5rIW!.Y~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#Orr</T!!(aO!<:aR!8@DP
-!8@DPp"KEGrS%2MJ_I?^rrE#Or;ciNr;_E&hqA7-s5rIT!.Y~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!hphn+s5rIW!.Y~>
-!<E0!joD4Kec19uXT/=rec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XJ!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec19uXT/=rebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD+HgAca#0`V1KgA1d\g&M-,!!(a,!!(^Q!8?-,!;kLJ!!(aP!<:dQ!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/J_L+W"ektYk.1PC~>
-!<E0!joD4Kec19u@fQK(ebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD4Kec19uXT/=rec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<(XO!<1^P!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec19uXT/=rec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<(XO!<1^P!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/J_L+W"ektYk.1PC~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD4Kec19uXT/=rec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XO!<1^P!<:dQ!".E[
-!8?-,!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec19uXT/=rec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^rr6"f21\k.LbF~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#OrrE#Or;clOrrE)QrrE)Q
-rrDcHrrE#Or;bI'JUtXgJ_K;@"ektYk.1PC~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^rr6"f21\k.LbF~>
-!<E0!joD4Kec19ss+/]#eU`@iK)kq&e`YHdV#TT>]`<Q~>
-!<E0!joD+HgAca!s+/l(g4=glJH5_$g?7/nU&X9;\c@6~>
-!<E0!joD4Kec19ss+/]#eU`@iK)kq&e`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#B!Be`YHdV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_VtNGg?7/nU&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#B!Be`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&e`YHdV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_W:^uJcGb$g?7/nU&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&e`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^rr6"f21\k.LbF~>
-!<E0!joD+Hg@kRBgA_0PgA_-Sg&M-NgA_0FgA_0PgA_0KgA_/^gAc_T_W/N5s7P(HJcGDss+14M
-J_K;@"ektYk.1PC~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^rr6"f21\k.LbF~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-kLBa3s5rIW!.Y~>
-!<E0!joD+Hg@tUIJbe%"!<1^P!;Y@K!;,"F!<1^P!;Y@K!4U\^JUt\u_Z0Z/g&Zd)p"KFss8RZ(
-kLp*5s5rIT!.Y~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-kLBa3s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&e`YHdV#TT>
-]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE&Prr<_d!!(^Q!8?-,!8?-,
-!87DQg&M-PgAM$OgA_0QgA_0QgA_-Vg&M-,!!(a,s+,a<j21irp"BFts7P+GJcGb$g?7/nU&X9;
-\c@6~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&e`YHdV#TT>
-]`<Q~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#kLBa3
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<1^P!!(aP!".E[!87DQ
-g&M-,gAV'eg&M-,!!(a,!!(^Q!8?-,!8?-,!8@DP!nmVSgY2[YJ\pHas8V_B!<;YAs8RZ(kLp*5
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#kLBa3
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^rr6"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA1d\g&M-,!!(a,!!(^Q!8?-,!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,a<j2(frjFR@2J_K;@"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^rr6"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<kLBa3s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,b$_uG;AkLp*5s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<kLBa3s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^rr6"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<1^P!%ln)!8?-,!87DQg&M-,
-g&M-,g&M-,!!(a,!!(a,!!(^Q!87DQg=cN,g=cN,gY)XYJcEUeJ_K;@"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^rr6"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;bFL!$Bnp!8?-,!8?-,!87DQ
-g=cN,g&M-,g&M-,!!(a,!!*#PrrE)QrrE&PrrE)Qrr@W(J_G\/"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;cZIquHcNrrE)Qrr<,S!!*#Pr;clO
-rrE)Qr;cfMrrE)QrrE&PrrE)Qrr@W(J_G\/"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tTg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^mbKDX1&V#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<TlJc".)U&X9;\c@6~>
-!<E0!joD3.eUc8%eY^mbKDX1&V#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^mcK)krKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<TmJH5`Ig'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^mcK)krKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jbm4`Jbm7`s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD*+g4@t/g8<U(Jc!:bs+1$`s8VuM"ektYk.1PC~>
-!<E0!joD3.eUc8%eY^msKDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD3.eUc8%eY^msKDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(Jc!:cs+,au_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msKDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(Jc*Cbs8RZI_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc*CbrrUo*Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc3Ics8UgQJc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc3Ics8LaPJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc<Ods8C[OJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc<Ods8:UNJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcEUes81OMJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcEUes8(ILJcEUes81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD4>eH#X+eH#XIeH#WVeH#X+eH#XIeH#XIec,TWec5[IeH#XCeH#X%eH#XIec5ZpeH#X=
-ec5[Jec5Zkec17'^&S-.ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+;g&M-0g&M-Ng&M,[g&M-0g&M-Ng&M-NgAV)\gA_0Ng&M-Hg&M-*g&M-NgA_/ug&M-B
-gA_0OgA_/pgAc^*_Z0Z3gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4>eGoU+eGoUIeGoTVeGoU+eGoUIeGoUIec#QWec,XIeGoUCeGoU%eGoUIec,WpeGoU=
-ec,XJec,Wkec17'^&S-.ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4>eH#X+eH#XIeH#WVeH#X+eH#XIeH#XJeH#XKeH#WXeH#WaeH#WpeH#X<eH#XIeH#Wk
-ec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+;g&M-0g&M-Ng&M,[g&M-0g&M-Ng&M-Og&M-Pg&M,]g&M,fg&M,ug&M-Ag&M-Ng&M,p
-gAc^*_Z0Z2gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4>eGoU+eGoUIeGoTVeGoU+eGoUIeGoUJeGoUKeGoTXeGoTaeGoTpeGoU<eGoUIeGoTk
-ec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4Jec5XPec42"s8CLHs8LRKs8UUTs4./"s8UXLs8LRKrrUaNs7t4Ds8UXJs2*=drrgmP
-ec5[Jec#OIec5[LeHl3*s4./Lec5[Kec5XNec5[Fec#OJec#LMec41Mr;QiKs8W)Krr;uJs8W)K
-!WU^Ls5VW3s4./Lrm_&Lec,UKec5[IeH#XJec5[Lec5XMec5Tus8W,L"96pOs8LRKs8CIKs4.&I
-!nI>NqUPWG!S.5Kec5[Jec,U,ec5[Jec5[LeH>j%s8W)KrVuoJ!WU^Ls8UXLs8:CIs8:CIs8CLJ
-s8LOLs4.,Kf@BnRs8VbE!knX6qpbkGs5rIW!.Y~>
-!<E0!joD+GgA_-Ug&Th,!<(XM!<1^P!<:aY!87G,!!(^Q!<1^P!!:jS!;Y@I!<:dO!5dIi!!M!U
-g&M-OgAM$NgA_0Qg'@]4!87DQg&M-PgA_-Sg&M-KgAM$OgAM!Rg&Tj\qu?fP!!*#PrW)rOrrE&P
-!<CjQ!9;c8!87DQrn7AQgAV*PgA_0Ng&M-OgA_0QgA_-Rg&V**rrE)Q!s%$T!<1^P!<(UP!8@>N
-!nmVSqV(rL!SRPPgA_0OgAV*1gA_0OgA_0Qg&h?/!!*#Pr;clO!<CjQ!<:dQ!;tON!;tON!<(XO
-!<1[Q!8@DPf@p7Us8VbC!lG!;qq;4Is5rIT!.Y~>
-!<E0!joD4Jec,UPeH","!<(IH!<1OK!<:RT!7_)"!!(OL!<1OK!!:[N!;Y1D!<:UJ!5d:d!!LgP
-eGoUJeboLIec,XLeHc0*!7_&LeGoUKec,UNeGoUFeboLJeboIMeH".Mqu?fK!!*#KrW)rJrrE&K
-!<C[L!9;T3!7_&Lrm_#Lec#RKec,XIeGoUJec,XLec,UMeH#QurrE)L!s$jO!<1OK!<(FK!7guI
-!n@8NqUPTG!S%2Kec,XJec#R,ec,XJec,XLeH5g%!!*#Kr;clJ!<C[L!<:UL!;t@I!;t@I!<(IJ
-!<1LL!7h&Kf@BnRs8VbE!knX6qpbkGs5rIW!.Y~>
-!<E0!joD4KeH>j%ec5Tu!<<#J!<<#J$3/Q+s4./"s4./JeH#XKeH>j%ec5Ep!<;uI!<9mc"96p%
-s8CIJs8CIJs8CISs4,["ec42"ec5Tu!<<&K"96p%s7k+Es8:CIs8LOXs4./"s4,["e^a]Mec5Qt
-"96p%s8LOKs52?/s4,["rm_#KrRD#Me^a]ueH#XIeHc-)ec42"ec5Tu!<<&K"96p%s8CIJs8CIJ
-s8CIMs4,["qUG`Kec42"rRCoJrm_,Ne^a]YeIV]1ec41Ms4,["e^a]Mec5X!!<;uI!<<#J"96p%
-s8CIJs8:CIs8LONs4,["rm_#KeCFSO!<;YCs8VuH"f21\k.LbF~>
-!<E0!joD+Hg&h?/g&V**!!)uO!!)uO#lr]5!87G,!87GOg&M-Pg&h?/g&Up%!!)rN!!'jh!s%'/
-!<(UO!<(UO!<(UX!8?-,g&Th,g&V**!!*#P!s%'/!;P7J!;tON!<1[]!87G,!8?-,g=cP\g&V')
-!s%'/!<1[P!8lK4!8?-,rn7>PrRq>Rg=cQ*g&M-Ng'7W3g&Th,g&V**!!*#P!s%'/!<(UO!<(UO
-!<(UR!8?-,qUu&Pg&Th,rRq5Orn7GSg=cPcg(+2;g&Tj\!8?-,g=cP\g&V-+!!)rN!!)uO!s%'/
-!<(UO!;tON!<1[S!8?-,rn7>PeCsqR!<;YAs8VuM"ektYk.1PC~>
-!<E0!joD4KeH5g%eH#Qu!!)uJ!!)uJ#lrN+!7_)"!7_)JeGoUKeH5g%eH#Bp!!)rI!!'jc!s$m%
-!<(FJ!<(FJ!<(FS!7fU"eH","eH#Qu!!*#K!s$m%!;P(E!;t@I!<1LX!7_)"!7fU"e^XZMeH#Nt
-!s$m%!<1LK!8l</!7fU"rm^uKrRCuMe^XZueGoUIeHZ*)eH","eH#Qu!!*#K!s$m%!<(FJ!<(FJ
-!<(FM!7fU"qUG]KeH","rRClJrm_)Ne^XZYeIMZ1eH".M!7fU"e^XZMeH#U!!!)rI!!)uJ!s$m%
-!<(FJ!;t@I!<1LN!7fU"rm^uKeCFSO!<;YCs8VuH"f21\k.LbF~>
-!<E0!joD4KeHQ!'ec41Mrr;rI!<<#Jrr<#K#636Rec41Mrr;uJ"96p%s7k+Es8:CIs2!4hs4,["
-e^a[!rRCoJrRLoIs4%>Rec42"e^a[!rm_,Ne^a]peH#XIeH#XKeI)?,s4./"ec41Ms8LRKs8LRJ
-s8CIJs52?/s4,["rm_#KrRLoIr7(fIr7)&Pe^a]Ms4./JeH#XKeHQ!'ec41Mrr;rI!<<#J"96p%
-s8(7Ks4./"s8CIJs8LONs4,["iRIr.r7),Re^a]Mec41Ms8LOKs8:CIs8CIMs4,["rRCoJr7(fI
-rmh#JrRCoJeCFSOo"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+Hg'%K1g&Tj\rW)oN!!)uOrW)uP"p!?Wg&Tj\rW)rO!s%'/!;P7J!;tON!5[@m!8?-,
-g=lN+rRq5OrS%5Ns4RYWg&Th,g=lN+rn7GSg=cQ%g&M-Ng&M-Pg'Ri6!87G,g&Tj\!<1^P!<1^O
-!<(UO!8lK4!8?-,rn7>PrS%5Nr7V,Nr7VAUg=cP\!87GOg&M-Pg'%K1g&Tj\rW)oN!!)uO!s%'/
-!;bCP!87G,!<(UO!<1[S!8?-,iS"83r7VGWg=cP\g&Tj\!<1[P!;tON!<(UR!8?-,rRq5Or7V,N
-rn@>OrRq5OeCsqRo"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4KeHGs'eH".MrW)oI!!)uJrW)uK"p!0ReH".MrW)rJ!s$m%!;P(E!;t@I!5[1h!7fU"
-e^aX!rRClJrRLlIs4%;ReH","e^aX!rm_)Ne^XZpeGoUIeGoUKeHu<,!7_)"eH".M!<1OK!<1OJ
-!<(FJ!8l</!7fU"rm^uKrRLlIr7(cIr7)#Pe^XZM!7_)JeGoUKeHGs'eH".MrW)oI!!)uJ!s$m%
-!;b4K!7_)"!<(FJ!<1LN!7fU"iRIo.r7))Re^XZMeH".M!<1LK!;t@I!<(FM!7fU"rRClJr7(cI
-rmguJrRClJeCFSOo"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4KeHl3*ec42"e^a]ueJ%u5ec42"e^a]Mec42"e^a]Mec5X!"96p%s7k+Ns4,["e^a]M
-ec3S<#liH*s4./"ec5Tu'E?V5s4./"ec41Ms4./"ec41Ms8LONs4,["psffQe^a]Mec41Ms8UX"
-rr3,Os4,["r7)#Oe^a]Mec5X!!<:s,"96p%s8LOKs8CIMs4,["rRCoJr7)&Pe^a]Ms4./JeH#XK
-eHl3*ec42"e^a]ueH#XJeH>j%ec5Kr"TR$Pec5Tu!<<&K"96p%s5DK=s4,["e^a]Mec41Ms4,["
-rm_5Qe^a]Mec5Tu"96p%s8CIJs8:CIs8LONs4,["rm_#KeCFSOnGiC9"f21\k.LbF~>
-!<E0!joD+Hg'@]4g&Th,g=cQ*g(OJ?g&Th,g=cP\g&Th,g=cP\g&V-+!s%'/!;P7S!8?-,g=cP\
-g&T(F#QWT4!87G,g&V**'*-b?!87G,g&Tj\!87G,g&Tj\!<1[S!8?-,pt?,Vg=cP\g&Tj\!!(a,
-rW!)T!8?-,r7V>Tg=cP\g&V-+!!(p1!s%'/!<1[P!<(UR!8?-,rRq5Or7VAUg=cP\!87GOg&M-P
-g'@]4g&Th,g=cQ*g&M-Og&h?/g&V!'"9@-Ug&V**!!*#P!s%'/!9)WB!8?-,g=cP\g&Tj\!8?-,
-rn7PVg=cP\g&V**!s%'/!<(UO!;tON!<1[S!8?-,rn7>PeCsqRnGiC>"ektYk.1PC~>
-!<E0!joD4KeHc0*eH","e^XZueIqr5eH","e^XZMeH","e^XZMeH#U!!s$m%!;P(N!7fU"e^XZM
-eH!P<#QWE*!7_)"eH#Qu'*-S5!7_)"eH".M!7_)"eH".M!<1LN!7fU"psfcQe^XZMeH".M!!(R"
-rW!)O!7fU"r7(uOe^XZMeH#U!!!(p,!s$m%!<1LK!<(FM!7fU"rRClJr7)#Pe^XZM!7_)JeGoUK
-eHc0*eH","e^XZueGoUJeH5g%eH#Hr"9?sPeH#Qu!!*#K!s$m%!9)H=!7fU"e^XZMeH".M!7fU"
-rm_2Qe^XZMeH#Qu!s$m%!<(FJ!;t@I!<1LN!7fU"rm^uKeCFSOnGiC9"f21\k.LbF~>
-!<E0!joD4Jec,UKec5XMec5Tus8W)Ks8W)K!rpgNrmh&K!S.5Lec5[Cec5[Jec5Zdec,UKec5XM
-ec5Tus8W)Ks8W)K!rpgNrmh&K!S.5Lec5[Cec5[Jec5[LeH#XHec5XNec42!s8CLJs8LRIs5DN-
-s8LRIs8LRKs8LRHrrCUHrrpsQec5["q>UcOs8UXLs4./"ec#OIec5[FeHZ'(s4./LeboIIec5XM
-ec4UYs8W&Js8W,Lrr3&Ms8W)Ks8W,LrVulIs8W)Kr;QcIr;ZfIs8W)KrVtI!s+BqC!e^OQqpbkG
-s5rIW!.Y~>
-!<E0!joD+GgAV*PgA_-Rg&V**rrE&PrrE&P!W^pSrn@AP!SRPQgA_0HgA_0OgA_/igAV*PgA_-R
-g&V**rrE&PrrE&P!W^pSrn@AP!SRPQgA_0HgA_0OgA_0Qg&M-MgA_-Sg&Tk+!<(XO!<1^N!9)Z2
-!<1^N!<1^P!<1^M!!(aM!!V'Vg&M-,q#C`T!!(^Q!87G,gAM$NgA_0Kg'.Q2!87DQgACsNgA_-R
-g&U*crrE#OrrE)QrW!#R!!*#PrrE)Qr;ciNrrE&Pqu?`NquHcNrrE&Pr;bF&s+0eA!eLCOqq;4I
-s5rIT!.Y~>
-!<E0!joD4Jec#RKec,UMeH#QurrE&KrrE&K!W^aNrmh#K!S%2Lec,XCec,XJec,Wdec#RKec,UM
-eH#QurrE&KrrE&K!W^aNrmh#K!S%2Lec,XCec,XJec,XLeGoUHec,UNeH"/!!<(IJ!<1OI!9)K-
-!<1OI!<1OK!<1OH!!(RH!!UmQeGoU"q#C`O!!(OL!7_)"eboLIec,XFeHQ$(!7_&LebfFIec,UM
-eH"RYrrE#JrrE)LrW!#M!!*#KrrE)Lr;ciIrrE&Kqu?`IquHcIrrE&Kr;bF!s+BqC!e^OQqpbkG
-s5rIW!.Y~>
-!<E0!joD4HeH#X-eH#WNeH#X-eH#X7ec,TjeH#WgeH#W#e`,-ZKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD+Eg&M-2g&M,Sg&M-2g&M-<gAV)og&M,lg&M,(g>^idJcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD4HeGoU-eGoTNeGoU-eGoU7ec#QjeGoTgeGoT#e`,-ZKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD4Kec,U-ec5[JebfBVec,U-ec5[JebfBWec#Niec5[JebfAtea(ccKE(uFec1:%s81=M
-V#TT>]`<Q~>
-!<E0!joD+HgAV*2gA_0OgA:l[gAV*2gA_0OgA:l\gAM#ngA_0OgA:l$g?[JmJcGcDgAca(s81LR
-U&X9;\c@6~>
-!<E0!joD4Kec#R-ec,XJeb]?Vec#R-ec,XJeb]?WeboKiec,XJeb]>tea(ccKE(uFec1:%s81=M
-V#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5ec5[Jec5[Lec5[>ec5ZmeH#XEeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcK
-k2s>WJ,~>
-!<E0!joD+?g&M-:gA_0OgA_0QgA_0CgA_/rg&M-Jg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoU5ec,XJec,XLec,X>ec,WmeGoUEeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#X4eH#XIeH#XKeH#X=eH#WmeH#XEeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcK
-k2s>WJ,~>
-!<E0!joD+?g&M-9g&M-Ng&M-Pg&M-Bg&M,rg&M-Jg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoU4eGoUIeGoUKeGoU=eGoTmeGoUEeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec5[HeH#XIeH#XKec,UJec5[Iec5[KeH>j%s8W)K!<;cCs8W&Js8W,L
-$3/QUs4,["ec5[Jec5[Jec5[Kec#OEeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M-FgA_0PgA_0Mg&M-Ng&M-PgAV*OgA_0NgA_0Pg&h?/!!*#P!!)`HrrE#OrrE)Q
-#lrZZ!8?-,g&M-OgA_0OgA_0PgAM$Jg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAec,XKec,XHeGoUIeGoUKec#RJec,XIec,XKeH5g%!!*#K!!)`CrrE#JrrE)L
-#lrKU!7fU"eGoUJec,XJec,XKeboLEeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#XBeH>j%ec5Tu!<;uI!<;uI!<<&K"96p%s8CIJs8LOSs4,["e^a]Ms8CIJs7b%e
-s4,["e^a]Mec41Ms4,["e^a]Mec41Ms4,["e^a]Mec5X!!<;iE!<7r,!<7r,!<8qHs+C@Op=91q
-s8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&h?/g&V**!!)rN!!)rN!!*#P!s%'/!<(UO!<1[X!8?-,g=cP\!<(UO!;G1j
-!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&V-+!!)fJ!!%o1!!%o1!!&nMs+14Mp=fOt
-s8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeH5g%eH#Qu!!)rI!!)rI!!*#K!s$m%!<(FJ!<1LS!7fU"e^XZM!<(FJ!;G"e
-!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH#U!!!)fE!!%o,!!%o,!!&nHs+C@Op=91q
-s8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBeH#XIec,UHeH#XIeH#XKeHQ!'ec41Mrr;uJ!<;uIs8VW>!<;uI&c^D3s4,["
-e^a]Mec41Ms4,[!s8LOKs81=Hs7k+Es,,>,s,,>,s/+?HKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Gg&M-NgAV*Mg&M-Ng&M-Pg'%K1g&Tj\rW)rO!!)rNrrDTC!!)rN&HLP=!8?-,
-g=cP\g&Tj\!8?0+!<1[P!;kIM!;P7J!/fJ1!/fJ1!2eKMJcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD4BeGoUBeGoUIec#RHeGoUIeGoUKeHGs'eH".MrW)rJ!!)rIrrDT>!!)rI&HLA3!7fU"
-e^XZMeH".M!7fX!!<1LK!;k:H!;P(E!/f;,!/f;,!2e<HKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeHl3*ec42"e^a]teH#XIeH#XKeHl3*ec42"e^a^!eHl3*ec41Ms4./JeH#XD
-eKOtCec41Ms4,["e^a]Mec41Ms4,["e^a]Mec41Ms4,["rm_,Ne^a]seH#W,eH#W,eH#WHec1:%
-s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg'@]4g&Th,g=cQ)g&M-Ng&M-Pg'@]4g&Th,g=cQ+g'@]4g&Tj\!87GOg&M-I
-g*$IMg&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!8?-,rn7GSg=cQ(g&M,1g&M,1g&M,MgAca(
-s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeHc0*eH","e^XZteGoUIeGoUKeHc0*eH","e^X[!eHc0*eH".M!7_)JeGoUD
-eKFqCeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7fU"rm_)Ne^XZseGoT,eGoT,eGoTHec1:%
-s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec5XOec41Mr;QcIq#C?Ds8N,Ms8LRKs8UXLrrUaNs8LOKs7Y"Cs8CLJ
-s8UXKrrCUIrs%$Rs4,["s8CLJs8:FIs8(7Gs,,>,s,,>,s/+?HKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-FgA_0PgA_-Tg&Tj\qu?`Np]1<Irr<)R!<1^P!<:dQ!!:jS!<1[P!;>.H!<(XO
-!<:dP!!(aN!!_-W!8?-,!<(XO!;tRN!;bCL!/fJ1!/fJ1!2eKMJcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAec,XKec,UOeH".Mqu?`Ip]1<Drr<)M!<1OK!<:UL!!:[N!<1LK!;=tC!<(IJ
-!<:UK!!(RI!!^sR!7fU"!<(IJ!;tCI!;b4G!/f;,!/f;,!2e<HKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5eboLGeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gAM$Lg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5eboLGeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4ec#RHeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gAV*Mg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4ec#RHeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5eH#W\eH#X9eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M-:g&M,ag&M->g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoU5eGoT\eGoU9eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5eH#W\eH#X9eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M-:g&M,ag&M->g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoU5eGoT\eGoU9eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#XBeH,^#rr<#Ks8W)KrVm2Ss8UXLs4,["ec#LLec5[JeH#XCec5[Jec5[LeHu9+
-s8UX"s4./LrRLrJrRLrJrmguImaV=;MU__,MU__,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Gg&V3-rW)uPrrE&Pr;[/X!!(^Q!8?-,gAM!Qg&M-Og&M-HgA_0OgA_0Qg'Ic5
-!!(a,!87DQrS%8OrS%8Orn@;Nmb.X@MV8%1MV8%1VV;'$s8VfHs+14Mqq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeH#[#rW)uKrrE&Kr;[/S!!(OL!7fU"eboILeGoUJeGoUCec,XJec,XLeHl6+
-!!(R"!7_&LrRLoJrRLoJrmgrImaV:;MU_\,MU_\,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAeH#XJeH>j%ec5X!!<<#J"96p%s8LOKs8CIMs4,["rm_#KpXLGee^a]Mec41M
-s4,["e^a]Mec41Ms4,["e^a]Mec41Ms8LOKs6S89s,,>,s,,>,s/+?HKE(uFec1:%s81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M-Fg&M-Og&h?/g&V-+!!)uO!s%'/!<1[P!<(UR!8?-,rn7>PpY$bjg=cP\g&Tj\
-!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!<1[P!:8D>!/fJ1!/fJ1!2eKMJcGcDgAca(s81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoUAeGoUJeH5g%eH#U!!!)uJ!s$m%!<1LK!<(FM!7fU"rm^uKpXLDee^XZMeH".M
-!7fU"e^XZMeH".M!7fU"e^XZMeH".M!<1LK!:859!/f;,!/f;,!2e<HKE(uFec1:%s81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#XAeH#XJec,UIeH#XJeH>j%ec5X!!<<#J"96p%s7=b@s8:CZs4,["e^a]Mec41M
-s4,["e^a[!rm_#Kqpb]Hm*u+9MU__,MU__,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Fg&M-OgAV*Ng&M-Og&h?/g&V-+!!)uO!s%'/!;"nE!;tO_!8?-,g=cP\g&Tj\
-!8?-,g=lN+rn7>Pqq;#Mm+MF>MV8%1MV8%1VV;'$s8VfHs+14Mqq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUAeGoUJec#RIeGoUJeH5g%eH#U!!!)uJ!s$m%!;"_@!;t@Z!7fU"e^XZMeH".M
-!7fU"e^aX!rm^uKqpbZHm*u(9MU_\,MU_\,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAeH#XJeH>j%ec5X!#liH*s4./"ec5X!!<<#J"96p%s8LOKs7b%es4,["e^a]M
-ec41Ms4,["e^a]Mec41Ms4,["e^a]Mec5X!"96p%s6nJ<s,,>,s,,>,s/+?HKE(uFec1:%s81=M
-V#TT>]`<Q~>
-!<E0!joD+?g&M-Fg&M-Og&h?/g&V-+#QWT4!87G,g&V-+!!)uO!s%'/!<1[P!;G1j!8?-,g=cP\
-g&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&V-+!s%'/!:SVA!/fJ1!/fJ1!2eKMJcGcDgAca(s81LR
-U&X9;\c@6~>
-!<E0!joD4BeGoUAeGoUJeH5g%eH#U!#QWE*!7_)"eH#U!!!)uJ!s$m%!<1LK!;G"e!7fU"e^XZM
-eH".M!7fU"e^XZMeH".M!7fU"e^XZMeH#U!!s$m%!:SG<!/f;,!/f;,!2e<HKE(uFec1:%s81=M
-V#TT>]`<Q~>
-!<E0!joD4BeH#XBec#OIec5[Iec5[Kec5XNec41urrCUKrrpsQs4,["p=93CrRLrJs4.,K!7h#I
-#1`bRe^a^"rRLrJr71iImaV=;MU__,MU__,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-GgAM$NgA_0NgA_0PgA_-Sg&Tk*!!(aP!!V'V!8?-,p=fNHrS%8Os4[GP!8@>N
-#20%Wg=cN,rS%8Or7_/Nmb.X@MV8%1MV8%1VV;'$s8VfHs+14Mqq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeboLIec,XIec,XKec,UNeH".u!!(RK!!UmQ!7fU"p=90CrRLoJs4.)K!7guI
-#1W\Re^XX"rRLoJr71fImaV:;MU_\,MU_\,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7CsDs81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7CmBs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7CsDs81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec17%s7:mCs81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc^(s7:gAs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec17%s7:mCs81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X.ec5[EeH#W\eH#XKeH#XGeH5d$s8CIJs-_C;s,,>,s/+?HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M-3gA_0Jg&M,ag&M-Pg&M-Lg&_9.!<(UO!1DO@!/fJ1!2eKMJb$\Xs81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoU.ec,XEeGoT\eGoUKeGoUGeH,a$!<(FJ!1D@;!/f;,!2e<HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#X-eH#XEeH#W\eH#XKeH#XGeHGp&s4,[!s-_C;s,,>,s/+?HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M-2g&M-Jg&M,ag&M-Pg&M-Lg&qE0!8?0+!1DO@!/fJ1!2eKMJb$\Xs81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoU-eGoUEeGoT\eGoUKeGoUGeH>m&!7fX!!1D@;!/f;,!2e<HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#XAec,UJec5[LeH>j%s8W&Jrr;fErVuoJ!WU^LrrUaNs8LONs4./LrRLoIq:,NG
-ec,UKec5[Jec5XLec,RMec5[Kec5[Jec,UKec#LKec5Nsr;ZcH!<8J;!<7r,!<8qHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&M-FgAV*OgA_0Qg&h?/!!)uOrW)cJr;clO!<CjQ!!:jS!<1[S!87DQrS%5Nq:YiL
-gAV*PgA_0OgA_-QgAV'Rg&M-PgA_0OgAV*PgAM!Pg&V$(quH`M!!&G@!!%o1!!&nMs+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoUAec#RJec,XLeH5g%!!)uJrW)cEr;clJ!<C[L!!:[N!<1LN!7_&LrRLlIq:,KG
-ec#RKec,XJec,ULec#OMeGoUKec,XJec#RKeboIKeH#KsquH`H!!&G;!!%o,!!&nHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#XBeH#XIeIV]1ec41Ms4,["e^a]Mec5Ep!<;uI!<;rH!<<&K#636(s4,["p!j'B
-rRDbbe^a]Mec41Ms4,["e^a]Mec41Ms4,["qpb]Hrm_#KqUGZIec5Tu!<8J;!<7r,!<8qHs+BmU
-s8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&M-Ng(+2;g&Tj\!8?-,g=cP\g&Up%!!)rN!!)oM!!*#P"p!B2!8?-,p"BBG
-rRr(gg=cP\g&Tj\!8?-,g=cP\g&Tj\!8?-,qq;#Mrn7>PqUtuNg&V**!!&G@!!%o1!!&nMs+0aX
-s8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeGoUIeIMZ1eH".M!7fU"e^XZMeH#Bp!!)rI!!)oH!!*#K"p!3(!7fU"p!j$B
-rRD_be^XZMeH".M!7fU"e^XZMeH".M!7fU"qpbZHrm^uKqUGWIeH#Qu!!&G;!!%o,!!&nHs+BmU
-s8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAec5[Kec,UJeHu9+ec41Ms4,["psfBEr7(fIrRLoIrm_,Ne^a^!ec5[DeH#XJ
-ec,UJeI2E-ec41Ms4,["e^a[!rRLrJrRCoJrm_#KqUGZIec5Tu!<8J;!<7r,!<8qHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&M-FgA_0PgAV*Og'Ic5g&Tj\!8?-,pt>]Jr7V,NrS%5Nrn7GSg=cQ+gA_0Ig&M-O
-gAV*Og'[o7g&Tj\!8?-,g=lN+rS%8OrRq5Orn7>PqUtuNg&V**!!&G@!!%o1!!&nMs+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoUAec,XKec#RJeHl6+eH".M!7fU"psf?Er7(cIrRLlIrm_)Ne^X[!ec,XDeGoUJ
-ec#RJeI)B-eH".M!7fU"e^aX!rRLoJrRClJrm^uKqUGWIeH#Qu!!&G;!!%o,!!&nHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#X?eIqo4ec41Ms4,["e^a]Mec41Ms7k+Ks4,["e^a^!eH>j%ec5X!"96p%s8:CI
-s7k+Es8CI_s4,["e^a]Mec41Ms4,["e^a]Mec5Qt!<<&K"TR$&s8VuHr;ZcH!<8J;!<7r,!<8qH
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Dg(FD>g&Tj\!8?-,g=cP\g&Tj\!;P7P!8?-,g=cQ+g&h?/g&V-+!s%'/!;tON
-!;P7J!<(Ud!8?-,g=cP\g&Tj\!8?-,g=cP\g&V')!!*#P"9@00!!)oMquH`M!!&G@!!%o1!!&nM
-s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoU?eIhl4eH".M!7fU"e^XZMeH".M!;P(K!7fU"e^X[!eH5g%eH#U!!s$m%!;t@I
-!;P(E!<(F_!7fU"e^XZMeH".M!7fU"e^XZMeH#Nt!!*#K"9@!&!!)oHquH`H!!&G;!!%o,!!&nH
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBec,UIec5[Lec,RSec5["ec5["s7k.Es8UXJs8UXLrrUaNec,RNec5["rr;cD
-rVulIs8W&Jrr;uJs8N8Qs4,["s8LRJs8:FIrrL[MqUG`Kec41MrVr>:!<7r,!<8qHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&M-GgAV*NgA_0QgAV'Xg&M-,g&M-,!;P:J!<:dO!<:dQ!!:jSgAV'Sg&M-,rW)`I
-r;ciNrrE#OrW)rOrr<5V!8?-,!<1^O!;tRN!!1dRqUu&Pg&Tj\r;`;?!!%o1!!&nMs+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoUBec#RIec,XLec#OSeGoU"eGoU"!;P+E!<:UJ!<:UL!!:[Nec#ONeGoU"rW)`D
-r;ciIrrE#JrW)rJrr<5Q!7fU"!<1OJ!;tCI!!1UMqUG]KeH".Mr;`;:!!%o,!!&nHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#WFeH#X5eH#XGeH5d$s-2%6s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,Kg&M-:g&M-Lg&_9.!0l1;!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoTFeGoU5eGoUGeH,a$!0l"6!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#WGec,U5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,LgAV*:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTGec#R5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gAM$Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^_!!*%VeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g496c!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeU[^^!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gAV*Mg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X.ec5[DeH#XIeH#XIeH#XFec5[BeH#X7eH5d$s8CIJs7t1Fs,,>,s,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-3gA_0Ig&M-Ng&M-Ng&M-KgA_0Gg&M-<g&_9.!<(UO!;Y=K!/fJ1!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU.ec,XDeGoUIeGoUIeGoUFec,XBeGoU7eH,a$!<(FJ!;Y.F!/f;,!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#X-eH#XFec,UIec5[Jec5[EeH#XBeH#X7eHGp&s4,[!s7t1Fs,,>,s,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-2g&M-KgAV*NgA_0OgA_0Jg&M-Gg&M-<g&qE0!8?0+!;Y=K!/fJ1!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU-eGoUFec#RIec,XJec,XEeGoUBeGoU7eH>m&!7fX!!;Y.F!/f;,!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAec,UJec5[LeH>j%s8W&Jrr;`C!<<&K!rpgNrm_)Mec5Eprr<#Ks8N5Ps8UX"
-rVulIs8W&Jrr;fEr;ZcH!<;lF!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-FgAV*OgA_0Qg&h?/!!)uOrW)]H!!*#P!W^pSrn7DRg&Up%rW)uPrr<2U!!(a,
-r;ciNrrE#OrW)cJquH`M!!)iK!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUAec#RJec,XLeH5g%!!)uJrW)]C!!*#K!W^aNrm_&MeH#BprW)uKrr<2P!!(R"
-r;ciIrrE#JrW)cEquH`H!!)iF!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBeH#XIeIV]1ec41Ms4,["e^a]Mec5Bo%0+l.s4,["e^a]Mec5Ep$3/Q+s4,["
-e^a^!eH#XJeHZ'(ec41Ms7OnDs4./JeH#XFeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg&M-Ng(+2;g&Tj\!8?-,g=cP\g&Um$$io#8!8?-,g=cP\g&Up%#lr]5!8?-,
-g=cQ+g&M-Og'.Q2g&Tj\!;5%I!87GOg&M-Kg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeGoUIeIMZ1eH".M!7fU"e^XZMeH#?o$ini.!7fU"e^XZMeH#Bp#lrN+!7fU"
-e^X[!eGoUJeHQ$(eH".M!;4kD!7_)JeGoUFeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec,UJeHu9+ec41Ms4,["pXK?Fe^aTt!7h#Iq:,fOe^a]Mec41Ms8LOK
-s8CLIs8CLJs7b%Fs4./JeH#XFeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-FgA_0PgAV*Og'Ic5g&Tj\!8?-,pY#ZKg=lH)!8@>Nq:Z,Tg=cP\g&Tj\!<1[P
-!<(XN!<(XO!;G1K!87GOg&M-Kg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAec,XKec#RJeHl6+eH".M!7fU"pXK<Fe^aQt!7guIq:,cOe^XZMeH".M!<1LK
-!<(II!<(IJ!;G"F!7_)JeGoUFeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X?eIqo4ec41Ms4,["e^a]Mec41Ms7b%Ds8:CIs8:CIs7k+Ns4,["e^a]Mec5X!
-#liH*s4./"ec5Qt!<;lFr;ZcH!<;lF!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Dg(FD>g&Tj\!8?-,g=cP\g&Tj\!;G1I!;tON!;tON!;P7S!8?-,g=cP\g&V-+
-#QWT4!87G,g&V')!!)iKquH`M!!)iK!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoU?eIhl4eH".M!7fU"e^XZMeH".M!;G"D!;t@I!;t@I!;P(N!7fU"e^XZMeH#U!
-#QWE*!7_)"eH#Nt!!)iFquH`H!!)iF!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBec,UIec5[Lec,RSec5["ec5["s8(:Es8CIJs8:CIs7t4Ds8CLJs8:FIs8LRK
-s8LRJs7b%Hs4./"ec#OEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-GgAV*NgA_0QgAV'Xg&M-,g&M-,!;bFJ!<(UO!;tON!;Y@I!<(XO!;tRN!<1^P
-!<1^O!;G1M!87G,gAM$Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBec#RIec,XLec#OSeGoU"eGoU"!;b7E!<(FJ!;t@I!;Y1D!<(IJ!;tCI!<1OK
-!<1OJ!;G"H!7_)"eboLEeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WZeH#X1eH5d$s7FhAs,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,_g&M-6g&_9.!;+tF!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoTZeGoU1eH,a$!;+eA!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W\ec5ZueH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,agA_0%g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT\ec,WueGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gAM$Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^_!!*%VeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g496c!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeU[^^!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gAV*Mg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X(eH#X7eH#XIeH#XIeH#XFec5[BeH#X9eH#W,eH#W,eH#WHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD+?g&M--g&M-<g&M-Ng&M-Ng&M-KgA_0Gg&M->g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoU(eGoU7eGoUIeGoUIeGoUFec,XBeGoU9eGoT,eGoT,eGoTHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#Wgec,UIec5[Jec5[EeH#XBeH#X9eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&M,lgAV*NgA_0OgA_0Jg&M-Gg&M->g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoTgec#RIec,XJec,XEeGoUBeGoU9eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#XBeH,^#rr<#Ks8W&Js8W&Js8W&Js8W,Ls8W,Ls8W,Ls8VfC!<<&K!rpgNrm_)M
-ec5Eprr<#Ks8N5Ps8UX"rVulIs8W&Jrr;iF!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&V3-rW)uPrrE#OrrE#OrrE#OrrE)QrrE)QrrE)QrrDcH!!*#P!W^pSrn7DR
-g&Up%rW)uPrr<2U!!(a,r;ciNrrE#OrW)fK!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeH#[#rW)uKrrE#JrrE#JrrE#JrrE)LrrE)LrrE)LrrDcC!!*#K!W^aNrm_&M
-eH#BprW)uKrr<2P!!(R"r;ciIrrE#JrW)fF!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAeH#XJeIV]1ec41Ms4,["e^a]Mec5Tu!<<&K!<<&K"om-Qe^a]oeI;K.ec41M
-s4,["e^a]peHu9+ec41Ms4,["rm_#KrRD,Pe^a]Mec5Bo!<7r,!<7r,!<8qHs+BmUs8VuH"f21\
-k.LbF~>
-!<E0!joD+?g&M-Fg&M-Og(+2;g&Tj\!8?-,g=cP\g&V**!!*#P!!*#P"T[6Vg=cQ$g'du8g&Tj\
-!8?-,g=cQ%g'Ic5g&Tj\!8?-,rn7>PrRqGUg=cP\g&Um$!!%o1!!%o1!!&nMs+0aXs8VuM"ektY
-k.1PC~>
-!<E0!joD4BeGoUAeGoUJeIMZ1eH".M!7fU"e^XZMeH#Qu!!*#K!!*#K"T['Qe^XZoeI2H.eH".M
-!7fU"e^XZpeHl6+eH".M!7fU"rm^uKrRD)Pe^XZMeH#?o!!%o,!!%o,!!&nHs+BmUs8VuH"f21\
-k.LbF~>
-!<E0!joD4BeH#XAeH#XJec,UJeH#XIec,UHeH#XJeHGp&s4,[!s7XtEs4,ZtrrCUIs7t1Os4,["
-e^a]Mec5X!!<<#Jrr;rIs8VoF!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Fg&M-OgAV*Og&M-NgAV*Mg&M-Og&qE0!8?0+!;>+J!8?0)!!(aN!;Y=T!8?-,
-g=cP\g&V-+!!)uOrW)oNrrDlK!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUAeGoUJec#RJeGoUIec#RHeGoUJeH>m&!7fX!!;=qE!7fWt!!(RI!;Y.O!7fU"
-e^XZMeH#U!!!)uJrW)oIrrDlF!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAeH#XJeIV]1ec41Ms4,["e^a]Mec5Tu!<<#J#liHTe^a]Mec5Bo!<;uI!<;uI
-!<;iE$3/Q+s4,["e^a^!eHl3*ec42"e^a]teH#XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&M-Fg&M-Og(+2;g&Tj\!8?-,g=cP\g&V**!!)uO#QWQYg=cP\g&Um$!!)rN!!)rN
-!!)fJ#lr]5!8?-,g=cQ+g'@]4g&Th,g=cQ)g&M-Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoUAeGoUJeIMZ1eH".M!7fU"e^XZMeH#Qu!!)uJ#QWBTe^XZMeH#?o!!)rI!!)rI
-!!)fE#lrN+!7fU"e^X[!eHc0*eH","e^XZteGoUGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#XBec#OIec5[Jec5[Jec5[KeboIHeH#XJec5[Eec#OHeH#XIeH#XFec#OHec5[I
-ec5[Kec5[Kec,UEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-GgAM$NgA_0OgA_0OgA_0PgACsMg&M-OgA_0JgAM$Mg&M-Ng&M-KgAM$MgA_0N
-gA_0PgA_0PgAV*Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeboLIec,XJec,XJec,XKebfFHeGoUJec,XEeboLHeGoUIeGoUFeboLHec,XI
-ec,XKec,XKec#REeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WHeH#X3eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,Mg&M-8g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTHeGoU3eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WJec5[2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,OgA_07g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTJec,X2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gAM$Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gAV*Mg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X.ec5[EeH#Wnec5[>eHc-)s4./"ec1WZ!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-3gA_0Jg&M,sgA_0Cg'7W3!87G,g&R,d!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoU.ec,XEeGoTnec,X>eHZ*)!7_)"eGtTZ!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#X-eH#XEeH#WmeH#X>eH>j%s4.)JNR\%/MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-2g&M-Jg&M,rg&M-Cg&h?/!8@AONS4@4MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoU-eGoUEeGoTmeGoU>eH5g%!7h#JNR\"/MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAec,UJec5[LeH>j%s8W&Jrr;fErVuoJ!WU^LrrUaNs8LONs4./LrRLoIq:,NG
-ec,UKec5[LeH>j%s8W#I#QN?)s8UXLs7t4Bs8UULs,GP/s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-FgAV*OgA_0Qg&h?/!!)uOrW)cJr;clO!<CjQ!!:jS!<1[S!87DQrS%5Nq:YiL
-gAV*PgA_0Qg&h?/!!)rN#6<K3!!(^Q!;Y@G!<:aQ!0,\4!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAec#RJec,XLeH5g%!!)uJrW)cEr;clJ!<C[L!!:[N!<1LN!7_&LrRLlIq:,KG
-ec#RKec,XLeH5g%!!)rI#6<<)!!(OL!;Y1B!<:RL!0,M/!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeH#XIeIV]1ec41Ms4,["e^a]Mec5Ep!<;uI!<;rH!<<&K#636(s4,["p!j'B
-rRD5Se^a]Mec41Ms8CIJs8LONs4,["psfWLec42"e^a\ZeH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&M-Gg&M-Ng(+2;g&Tj\!8?-,g=cP\g&Up%!!)rN!!)oM!!*#P"p!B2!8?-,p"BBG
-rRqPXg=cP\g&Tj\!<(UO!<1[S!8?-,pt>rQg&Th,g=cOdg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoUBeGoUIeIMZ1eH".M!7fU"e^XZMeH#Bp!!)rI!!)oH!!*#K"p!3(!7fU"p!j$B
-rRD2Se^XZMeH".M!<(FJ!<1LN!7fU"psfTLeH","e^XYZeGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#XAec5[Kec,UJeHu9+ec41Ms4,["psfBEr7(fIrRLoIrm_,Ne^a^!ec5[DeH#XJ
-ec,UJeH>j%ec5Tu!<<&K"96p%s7k+Ls4./"s4,["NR\%/MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-FgA_0PgAV*Og'Ic5g&Tj\!8?-,pt>]Jr7V,NrS%5Nrn7GSg=cQ+gA_0Ig&M-O
-gAV*Og&h?/g&V**!!*#P!s%'/!;P7Q!87G,!8?-,NS4@4MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUAec,XKec#RJeHl6+eH".M!7fU"psf?Er7(cIrRLlIrm_)Ne^X[!ec,XDeGoUJ
-ec#RJeH5g%eH#Qu!!*#K!s$m%!;P(L!7_)"!7fU"NR\"/MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#X?eIqo4ec41Ms4,["e^a]Mec41Ms7k+Ks4,["e^a^!eH>j%ec5X!"96p%s8:CI
-s7k+Es8CISs4,["e^a]Mec5Tu!<<&K"96p%s7t4Bs8UULs,GP/s,,>,s/+?HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M-Dg(FD>g&Tj\!8?-,g=cP\g&Tj\!;P7P!8?-,g=cQ+g&h?/g&V-+!s%'/!;tON
-!;P7J!<(UX!8?-,g=cP\g&V**!!*#P!s%'/!;Y@G!<:aQ!0,\4!/fJ1!2eKMJb$\Xs81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoU?eIhl4eH".M!7fU"e^XZMeH".M!;P(K!7fU"e^X[!eH5g%eH#U!!s$m%!;t@I
-!;P(E!<(FS!7fU"e^XZMeH#Qu!!*#K!s$m%!;Y1B!<:RL!0,M/!/f;,!2e<HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#XBec,UIec5[Lec,RSec5["ec5["s7k.Es8UXJs8UXLrrUaNec,RNec5["rr;cD
-rVulIs8W)Krr;uJr;ZfIs8ViD"96pOeboH-eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-GgAV*NgA_0QgAV'Xg&M-,g&M-,!;P:J!<:dO!<:dQ!!:jSgAV'Sg&M-,rW)`I
-r;ciNrrE&PrW)rOquHcNrrDfI!s%$TgACr2g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBec#RIec,XLec#OSeGoU"eGoU"!;P+E!<:UJ!<:UL!!:[Nec#ONeGoU"rW)`D
-r;ciIrrE&KrW)rJquHcIrrDfD!s$jOebfE-eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WIeH#XBeH#XCeHGp&s4..,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,Ng&M-Gg&M-Hg&qE0!87F1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTIeGoUBeGoUCeH>m&!7_(,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WJec#ODec5[>eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,OgAM$IgA_0Cg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTJeboLDec,X>eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X.ec5[DeH#XJec5[Jec5[Fec5[BeH#X7eH5d$s8CIJs7t1Fs,,>,s,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-3gA_0Ig&M-OgA_0OgA_0KgA_0Gg&M-<g&_9.!<(UO!;Y=K!/fJ1!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU.ec,XDeGoUJec,XJec,XFec,XBeGoU7eH,a$!<(FJ!;Y.F!/f;,!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#X-eH#XFec,UJeHu9+ec41Ms4,["q:,KFp!j'BlI?%;ec41Mrr;fE!<7r,!<7r,
-!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-2g&M-KgAV*Og'Ic5g&Tj\!8?-,q:YfKp"BBGlIl@@g&Tj\rW)cJ!!%o1!!%o1
-!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoU-eGoUFec#RJeHl6+eH".M!7fU"q:,HFp!j$BlI?";eH".MrW)cE!!%o,!!%o,
-!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAec,UJec5[LeH>j%s8W&Jrr;`C!<;rH#636(s4,["q:5KEs4./L"P*PPe^aWu
-rmh&KrRLoIq:5ECrm_#Kq:,KFMU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-FgAV*OgA_0Qg&h?/!!)uOrW)]H!!)oM"p!B2!8?-,q:bfJs4[JQ"PNhUg=lK*
-rn@APrS%5Nq:b`Hrn7>Pq:YfKMV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUAec#RJec,XLeH5g%!!)uJrW)]C!!)oH"p!3(!7fU"q:5HEs4.,L"P!JPe^aTu
-rmh#KrRLlIq:5BCrm^uKq:,HFMU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XBeH#XIeIV]1ec41Ms4,["e^a]Mec5Bo!<;uI!<<#Js8VlE$3/Q+s4,["e^a^!
-eH#XJeHZ'(ec41Ms7OnDs4./JeH#XFeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg&M-Ng(+2;g&Tj\!8?-,g=cP\g&Um$!!)rN!!)uOrrDiJ#lr]5!8?-,g=cQ+
-g&M-Og'.Q2g&Tj\!;5%I!87GOg&M-Kg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeGoUIeIMZ1eH".M!7fU"e^XZMeH#?o!!)rI!!)uJrrDiE#lrN+!7fU"e^X[!
-eGoUJeHQ$(eH".M!;4kD!7_)JeGoUFeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec,UJeHu9+ec41Ms4,["pXK9DrRCoJrRD#Me^a]qeHu9+ec41Ms4,["
-rm_#KrRLoIrRLrJpXK?Fec5Tu!<;lF!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-FgA_0PgAV*Og'Ic5g&Tj\!8?-,pY#TIrRq5OrRq>Rg=cQ&g'Ic5g&Tj\!8?-,
-rn7>PrS%5NrS%8OpY#ZKg&V**!!)iK!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUAec,XKec#RJeHl6+eH".M!7fU"pXK6DrRClJrRCuMe^XZqeHl6+eH".M!7fU"
-rm^uKrRLlIrRLoJpXK<FeH#Qu!!)iF!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#X?eIqo4ec41Ms4,["e^a]Mec41Ms7b%Ds8LOKs8:CLs4,["q:,fOe^a]Mec41M
-s8LOSs4,["ec41Ms8:CIs7t4Cs8LOKs7t1Fs,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Dg(FD>g&Tj\!8?-,g=cP\g&Tj\!;G1I!<1[P!;tOQ!8?-,q:Z,Tg=cP\g&Tj\
-!<1[X!8?-,g&Tj\!;tON!;Y@H!<1[P!;Y=K!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU?eIhl4eH".M!7fU"e^XZMeH".M!;G"D!<1LK!;t@L!7fU"q:,cOe^XZMeH".M
-!<1LS!7fU"eH".M!;t@I!;Y1C!<1LK!;Y.F!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBec,UIec5[Lec,RSec5["ec5["s8(:Es8UXJs8LRKs7t4Ds8CLJs8:FIs8LRK
-s8LRJs7b%Hs4./"ec#OEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-GgAV*NgA_0QgAV'Xg&M-,g&M-,!;bFJ!<:dO!<1^P!;Y@I!<(XO!;tRN!<1^P
-!<1^O!;G1M!87G,gAM$Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBec#RIec,XLec#OSeGoU"eGoU"!;b7E!<:UJ!<1OK!;Y1D!<(IJ!;tCI!<1OK
-!<1OJ!;G"H!7_)"eboLEeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WZeH#X1eH5d$s7FhAs,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,_g&M-6g&_9.!;+tF!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoTZeGoU1eH,a$!;+eA!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W\ec5ZueH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,agA_0%g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT\ec,WueGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5ec5[Jec5[Lec5[>ec5ZmeH#XEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&M-:gA_0OgA_0QgA_0CgA_/rg&M-Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoU5ec,XJec,XLec,X>ec,WmeGoUEeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#X4eH#XIeH#XKeH#X=eH#WmeH#XEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&M-9g&M-Ng&M-Pg&M-Bg&M,rg&M-Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoU4eGoUIeGoUKeGoU=eGoTmeGoUEeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#XAec5[Kec5[HeH#XIeH#XKec,UJec5[Iec5[KeH>j%s8W)K!<;cCs8W&Js8W,L
-$3/QUs4,["ec5[Jec5[Jec5[Kec#OEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-FgA_0PgA_0Mg&M-Ng&M-PgAV*OgA_0NgA_0Pg&h?/!!*#P!!)`HrrE#OrrE)Q
-#lrZZ!8?-,g&M-OgA_0OgA_0PgAM$Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAec,XKec,XHeGoUIeGoUKec#RJec,XIec,XKeH5g%!!*#K!!)`CrrE#JrrE)L
-#lrKU!7fU"eGoUJec,XJec,XKeboLEeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XBeH>j%ec5Tu!<;uI!<;uI!<<&K"96p%s8CIJs8LOSs4,["e^a]Ms8CIJs7b%e
-s4,["e^a]Mec41Ms4,["e^a]Mec41Ms4,["e^a]Mec5X!!<;iE!<7r,!<7r,!<8qHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&h?/g&V**!!)rN!!)rN!!*#P!s%'/!<(UO!<1[X!8?-,g=cP\!<(UO!;G1j
-!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&V-+!!)fJ!!%o1!!%o1!!&nMs+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoUBeH5g%eH#Qu!!)rI!!)rI!!*#K!s$m%!<(FJ!<1LS!7fU"e^XZM!<(FJ!;G"e
-!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH#U!!!)fE!!%o,!!%o,!!&nHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#XBeH#XIec,UHeH#XIeH#XKeHQ!'ec41Mrr;uJ!<;uIs8VW>!<;uI&c^D3s4,["
-e^a]Mec41Ms4,[!s8LOKs81=Hs7k+Es,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Gg&M-NgAV*Mg&M-Ng&M-Pg'%K1g&Tj\rW)rO!!)rNrrDTC!!)rN&HLP=!8?-,
-g=cP\g&Tj\!8?0+!<1[P!;kIM!;P7J!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUBeGoUIec#RHeGoUIeGoUKeHGs'eH".MrW)rJ!!)rIrrDT>!!)rI&HLA3!7fU"
-e^XZMeH".M!7fX!!<1LK!;k:H!;P(E!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeHl3*ec42"e^a]teH#XIeH#XKeHl3*ec42"e^a^!eHl3*ec41Ms4./JeH#XD
-eKOtCec41Ms4,["e^a]Mec41Ms4,["e^a]Mec41Ms4,["rm_,Ne^a]seH#W,eH#W,eH#WHec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg'@]4g&Th,g=cQ)g&M-Ng&M-Pg'@]4g&Th,g=cQ+g'@]4g&Tj\!87GOg&M-I
-g*$IMg&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!8?-,rn7GSg=cQ(g&M,1g&M,1g&M,MgAc`p
-_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeHc0*eH","e^XZteGoUIeGoUKeHc0*eH","e^X[!eHc0*eH".M!7_)JeGoUD
-eKFqCeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7fU"rm_)Ne^XZseGoT,eGoT,eGoTHec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec5XOec41Mr;QcIq#C?Ds8N,Ms8LRKs8UXLrrUaNs8LOKs7Y"Cs8CLJ
-s8UXKrrCUIrs%$Rs4,["s8CLJs8:FIs8(7Gs,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-FgA_0PgA_-Tg&Tj\qu?`Np]1<Irr<)R!<1^P!<:dQ!!:jS!<1[P!;>.H!<(XO
-!<:dP!!(aN!!_-W!8?-,!<(XO!;tRN!;bCL!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAec,XKec,UOeH".Mqu?`Ip]1<Drr<)M!<1OK!<:UL!!:[N!<1LK!;=tC!<(IJ
-!<:UK!!(RI!!^sR!7fU"!<(IJ!;tCI!;b4G!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5eboLGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gAM$Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5eboLGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4ec#RHeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gAV*Mg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4ec#RHeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5eH#W\eH#X9eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-:g&M,ag&M->g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoU5eGoT\eGoU9eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5eH#W\eH#X9eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-:g&M,ag&M->g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoU5eGoT\eGoU9eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XBeH,^#rr<#Ks8W)KrVm2Ss8UXLs4,["ec#LLec5[JeH#XCec5[Jec5[LeHu9+
-s8UX"s4./LrRLrJrRLrJrmguImaV=;MU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Gg&V3-rW)uPrrE&Pr;[/X!!(^Q!8?-,gAM!Qg&M-Og&M-HgA_0OgA_0Qg'Ic5
-!!(a,!87DQrS%8OrS%8Orn@;Nmb.X@MV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeH#[#rW)uKrrE&Kr;[/S!!(OL!7fU"eboILeGoUJeGoUCec,XJec,XLeHl6+
-!!(R"!7_&LrRLoJrRLoJrmgrImaV:;MU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAeH#XJeH>j%ec5X!!<<#J"96p%s8LOKs8CIMs4,["rm_#KpXLGee^a]Mec41M
-s4,["e^a]Mec41Ms4,["e^a]Mec41Ms8LOKs6S89s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Fg&M-Og&h?/g&V-+!!)uO!s%'/!<1[P!<(UR!8?-,rn7>PpY$bjg=cP\g&Tj\
-!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!<1[P!:8D>!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAeGoUJeH5g%eH#U!!!)uJ!s$m%!<1LK!<(FM!7fU"rm^uKpXLDee^XZMeH".M
-!7fU"e^XZMeH".M!7fU"e^XZMeH".M!<1LK!:859!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAeH#XJec,UIeH#XJeH>j%ec5X!!<<#J"96p%s7=b@s8:CZs4,["e^a]Mec41M
-s4,["e^a[!rm_#Kqpb]Hm*u+9MU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Fg&M-OgAV*Ng&M-Og&h?/g&V-+!!)uO!s%'/!;"nE!;tO_!8?-,g=cP\g&Tj\
-!8?-,g=lN+rn7>Pqq;#Mm+MF>MV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUAeGoUJec#RIeGoUJeH5g%eH#U!!!)uJ!s$m%!;"_@!;t@Z!7fU"e^XZMeH".M
-!7fU"e^aX!rm^uKqpbZHm*u(9MU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAeH#XJeH>j%ec5X!#liH*s4./"ec5X!!<<#J"96p%s8LOKs7b%es4,["e^a]M
-ec41Ms4,["e^a]Mec41Ms4,["e^a]Mec5X!"96p%s6nJ<s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M-Fg&M-Og&h?/g&V-+#QWT4!87G,g&V-+!!)uO!s%'/!<1[P!;G1j!8?-,g=cP\
-g&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&V-+!s%'/!:SVA!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoUAeGoUJeH5g%eH#U!#QWE*!7_)"eH#U!!!)uJ!s$m%!<1LK!;G"e!7fU"e^XZM
-eH".M!7fU"e^XZMeH".M!7fU"e^XZMeH#U!!s$m%!:SG<!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#XBec#OIec5[Iec5[Kec5XNec41urrCUKrrpsQs4,["p=93CrRLrJs4.,K!7h#I
-#1`bRe^a^"rRLrJr71iImaV=;MU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-GgAM$NgA_0NgA_0PgA_-Sg&Tk*!!(aP!!V'V!8?-,p=fNHrS%8Os4[GP!8@>N
-#20%Wg=cN,rS%8Or7_/Nmb.X@MV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeboLIec,XIec,XKec,UNeH".u!!(RK!!UmQ!7fU"p=90CrRLoJs4.)K!7guI
-#1W\Re^XX"rRLoJr71fImaV:;MU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X(eH#X7eH#XJec5[Jec5[Fec5[BeH#X9eH#W,eH#W,eH#WHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD+?g&M--g&M-<g&M-OgA_0OgA_0KgA_0Gg&M->g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoU(eGoU7eGoUJec,XJec,XFec,XBeGoU9eGoT,eGoT,eGoTHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#Wgec,UJeHu9+ec41Ms4,["q:,KFp!j'Bm*u+9MU__,MU__,VUb^!o"G)'qpbkG
-s5rIW!.Y~>
-!<E0!joD+?g&M,lgAV*Og'Ic5g&Tj\!8?-,q:YfKp"BBGm+MF>MV8%1MV8%1VV;'$o"tG,qq;4I
-s5rIT!.Y~>
-!<E0!joD4BeGoTgec#RJeHl6+eH".M!7fU"q:,HFp!j$Bm*u(9MU_\,MU_\,VUb^!o"G)'qpbkG
-s5rIW!.Y~>
-!<E0!joD4BeH#XBeH,^#rr<#Ks8W&Js8W&Js8W&Js8W,Ls8W,Ls8W,Ls8VfC!<;rH#636(s4,["
-q:5KEs4./L"P*PPe^aWurmh&KrRLoIqUGTGMU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Gg&V3-rW)uPrrE#OrrE#OrrE#OrrE)QrrE)QrrE)QrrDcH!!)oM"p!B2!8?-,
-q:bfJs4[JQ"PNhUg=lK*rn@APrS%5NqUtoLMV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeH#[#rW)uKrrE#JrrE#JrrE#JrrE)LrrE)LrrE)LrrDcC!!)oH"p!3(!7fU"
-q:5HEs4.,L"P!JPe^aTurmh#KrRLlIqUGQGMU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAeH#XJeIV]1ec41Ms4,["e^a]Mec5Tu!<<&K!<<&K"om-Qe^a]oeH#XIeH#XJ
-ec5[EeHu9+ec41Ms4,["rm_#KrRD,Pe^a]Mec5Bo!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Fg&M-Og(+2;g&Tj\!8?-,g=cP\g&V**!!*#P!!*#P"T[6Vg=cQ$g&M-Ng&M-O
-gA_0Jg'Ic5g&Tj\!8?-,rn7>PrRqGUg=cP\g&Um$!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUAeGoUJeIMZ1eH".M!7fU"e^XZMeH#Qu!!*#K!!*#K"T['Qe^XZoeGoUIeGoUJ
-ec,XEeHl6+eH".M!7fU"rm^uKrRD)Pe^XZMeH#?o!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAeH#XJec,UJeH#XIec,UHeH#XJeHGp&s4,[!s7XtCs8CIJs8CIMs4,["q:,fO
-e^a]Mec41Ms8LOKs8CLIs8CLJs7t1Fs,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Fg&M-OgAV*Og&M-NgAV*Mg&M-Og&qE0!8?0+!;>+H!<(UO!<(UR!8?-,q:Z,T
-g=cP\g&Tj\!<1[P!<(XN!<(XO!;Y=K!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAeGoUJec#RJeGoUIec#RHeGoUJeH>m&!7fX!!;=qC!<(FJ!<(FM!7fU"q:,cO
-e^XZMeH".M!<1LK!<(II!<(IJ!;Y.F!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAeH#XJeIV]1ec41Ms4,["e^a]Mec5Tu!<<#J#liHTe^a]Mec5Bo!<<&K!<;uI
-"96p%s7t1Os4,["e^a]Mec5X!#liH*s4./"ec5Qt!<;oG!<7r,!<7r,!<8qHs+BmUs8VuH"f21\
-k.LbF~>
-!<E0!joD+?g&M-Fg&M-Og(+2;g&Tj\!8?-,g=cP\g&V**!!)uO#QWQYg=cP\g&Um$!!*#P!!)rN
-!s%'/!;Y=T!8?-,g=cP\g&V-+#QWT4!87G,g&V')!!)lL!!%o1!!%o1!!&nMs+0aXs8VuM"ektY
-k.1PC~>
-!<E0!joD4BeGoUAeGoUJeIMZ1eH".M!7fU"e^XZMeH#Qu!!)uJ#QWBTe^XZMeH#?o!!*#K!!)rI
-!s$m%!;Y.O!7fU"e^XZMeH#U!#QWE*!7_)"eH#Nt!!)lG!!%o,!!%o,!!&nHs+BmUs8VuH"f21\
-k.LbF~>
-!<E0!joD4BeH#XBec#OIec5[Jec5[Jec5[KeboIHeH#XJec5[Eec#OJec#OIec5[Fec#OHec5[I
-ec5[Kec5[Kec,UEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-GgAM$NgA_0OgA_0OgA_0PgACsMg&M-OgA_0JgAM$OgAM$NgA_0KgAM$MgA_0N
-gA_0PgA_0PgAV*Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeboLIec,XJec,XJec,XKebfFHeGoUJec,XEeboLJeboLIec,XFeboLHec,XI
-ec,XKec,XKec#REeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WHeH#X3eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,Mg&M-8g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTHeGoU3eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WJec5[2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,OgA_07g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTJec,X2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAeH#Wnec5[>eH5d$s8CIJs6%o4s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Fg&M,sgA_0Cg&_9.!<(UO!9`&9!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAeGoTnec,X>eH,a$!<(FJ!9_l4!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAeH#WmeH#X>eHGp&s4,[!s6%o4s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Fg&M,rg&M-Cg&qE0!8?0+!9`&9!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAeGoTmeGoU>eH>m&!7fX!!9_l4!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBec#OJeH,^#rr3&Ms8W)K"96pOs8CLIs7t1Gs4.,Ks4./Ls4%5Oec5[IeHc-)
-ec5["s8VoFr;ZcH!<;64!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-GgAM$Og&V3-rW!#R!!*#P!s%$T!<(XN!;Y=L!8@DPs4[JQs4RPTg&M-Ng'7W3
-g&M-,!!)iKquH`M!!)39!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeboLJeH#[#rW!#M!!*#K!s$jO!<(II!;Y.G!7h&Ks4.,Ls4%2OeGoUIeHZ*)
-eGoU"!!)iFquH`H!!)34!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAeH#XIeH#XHeH#XKeHZ'(ec41Ms7OnBs8CISs4,["e^a]Mec5Tu!<<&K"96p%
-s7k+Gs4./JeH#X4eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Fg&M-Ng&M-Mg&M-Pg'.Q2g&Tj\!;5%G!<(UX!8?-,g=cP\g&V**!!*#P!s%'/
-!;P7L!87GOg&M-9g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAeGoUIeGoUHeGoUKeHQ$(eH".M!;4kB!<(FS!7fU"e^XZMeH#Qu!!*#K!s$m%
-!;P(G!7_)JeGoU4eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAeH#XIeH#XJec,UJeH>j%ec5X!s8ViD!<<#Jrr;uJ"96p%s8CIJs8LONs4,["
-psfHGec5Tu!<;64!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Fg&M-Ng&M-OgAV*Og&h?/g&V-+rrDfI!!)uOrW)rO!s%'/!<(UO!<1[S!8?-,
-pt>cLg&V**!!)39!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUAeGoUIeGoUJec#RJeH5g%eH#U!rrDfD!!)uJrW)rJ!s$m%!<(FJ!<1LN!7fU"
-psfEGeH#Qu!!)34!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAeHZ'(ec41Ms8LONs4,["rm_,Ne^a]teH#XEeH#XJeHu9+ec41Ms4,["rRCoJ
-rm_,Ne^a]qeboIHeH#X4eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Fg'.Q2g&Tj\!<1[S!8?-,rn7GSg=cQ)g&M-Jg&M-Og'Ic5g&Tj\!8?-,rRq5O
-rn7GSg=cQ&gACsMg&M-9g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAeHQ$(eH".M!<1LN!7fU"rm_)Ne^XZteGoUEeGoUJeHl6+eH".M!7fU"rRClJ
-rm_)Ne^XZqebfFHeGoU4eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X@ec5[Lec#OJec5XNec42!rr^gOs4.,Kpso?Crmh&Krmh#JrmgrHs4./LpXKEH
-ec41MrVu*3!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-EgA_0QgAM$OgA_-Sg&Tk+!!CpT!8@DPptGZHrn@APrn@>Orn@8Ms4[JQpY#`M
-g&Tj\r;c'8!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoU@ec,XLeboLJec,UNeH"/!!!CaO!7h&Kpso<Crmh#KrmguJrmgoHs4.,LpXKBH
-eH".Mr;c'3!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#WgeH#XBeH#XCeH5d$s5MQ/s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,lg&M-Gg&M-Hg&_9.!92]4!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoTgeGoUBeGoUCeH,a$!92N/!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#Whec#ODec5ZueH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,mgAM$IgA_0%g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTheboLDec,WueGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gAM$Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gAV*Mg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5ec5[Jec5[Lec5[>ec5[<eH#X!eH#XGec5[>eH5d$s8CIJs/XZMs,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-:gA_0OgA_0QgA_0CgA_0Ag&M-&g&M-LgA_0Cg&_9.!<(UO!3=fR!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU5ec,XJec,XLec,X>ec,X<eGoU!eGoUGec,X>eH,a$!<(FJ!3=WM!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#X4eH#XIeH#XKeH#X=eH#X<eH#X!eH#XFeH#X>eHGp&s4,[!s/XZMs,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-9g&M-Ng&M-Pg&M-Bg&M-Ag&M-&g&M-Kg&M-Cg&qE0!8?0+!3=fR!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU4eGoUIeGoUKeGoU=eGoU<eGoU!eGoUFeGoU>eH>m&!7fX!!3=WM!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAec5[Kec5[HeH#XIeH#XKec,UJec5[Iec5[KeH>j%s8W)K!<;fDrVuoJ!WU^L
-rrUaNs8LONs4./LrRLoIq:,NGec,UKec5[LeH>j%s8W#I#QN?)s8UXLs7t4Cs8LOKs/XZMs,,>,
-s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-FgA_0PgA_0Mg&M-Ng&M-PgAV*OgA_0NgA_0Pg&h?/!!*#P!!)cIr;clO!<CjQ
-!!:jS!<1[S!87DQrS%5Nq:YiLgAV*PgA_0Qg&h?/!!)rN#6<K3!!(^Q!;Y@H!<1[P!3=fR!/fJ1
-!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAec,XKec,XHeGoUIeGoUKec#RJec,XIec,XKeH5g%!!*#K!!)cDr;clJ!<C[L
-!!:[N!<1LN!7_&LrRLlIq:,KGec#RKec,XLeH5g%!!)rI#6<<)!!(OL!;Y1C!<1LK!3=WM!/f;,
-!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeH>j%ec5Tu!<;uI!<;uI!<<&K"96p%s8CIJs8LOSs4,["e^a]Ms8CIJs7XtC
-s8:CIs81=Hs8LOQs4,["e^a]meH#XJeHu9+ec42"s4,["rRCoJrm_,Ne^a]peH5d$s8CIJs/XZM
-s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Gg&h?/g&V**!!)rN!!)rN!!*#P!s%'/!<(UO!<1[X!8?-,g=cP\!<(UO!;>+H
-!;tON!;kIM!<1[V!8?-,g=cQ"g&M-Og'Ic5g&Th,!8?-,rRq5Orn7GSg=cQ%g&_9.!<(UO!3=fR
-!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUBeH5g%eH#Qu!!)rI!!)rI!!*#K!s$m%!<(FJ!<1LS!7fU"e^XZM!<(FJ!;=qC
-!;t@I!;k:H!<1LQ!7fU"e^XZmeGoUJeHl6+eH","!7fU"rRClJrm_)Ne^XZpeH,a$!<(FJ!3=WM
-!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeH#XIec,UHeH#XIeH#XKeHQ!'ec41Mrr;uJ!<;uIs8VT=!<;uI!<<#Jrr;uJ
-"96p%s8LRKs7b%Ds8CLIs8UXLs8UULs8CIJs8LONs4,["psfHGec5Tu!<9+M!<7r,!<8qHs+BmU
-s8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&M-NgAV*Mg&M-Ng&M-Pg'%K1g&Tj\rW)rO!!)rNrrDQB!!)rN!!)uOrW)rO
-!s%'/!<1^P!;G1I!<(XN!<:dQ!<:aQ!<(UO!<1[S!8?-,pt>cLg&V**!!'(R!!%o1!!&nMs+0aX
-s8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeGoUIec#RHeGoUIeGoUKeHGs'eH".MrW)rJ!!)rIrrDQ=!!)rI!!)uJrW)rJ
-!s$m%!<1OK!;G"D!<(II!<:UL!<:RL!<(FJ!<1LN!7fU"psfEGeH#Qu!!'(M!!%o,!!&nHs+BmU
-s8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBeHl3*ec42"e^a]teH#XIeH#XKeHl3*ec42"e^a^!eHl3*ec41Ms4./JeH#XC
-eHZ'(ec41Ms8LONs4,["rm_,Ne^a]teH#XEeH#XJeHu9+ec42"s4,["rRCoJrm_,Ne^a]qeboIH
-eH#WMeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg'@]4g&Th,g=cQ)g&M-Ng&M-Pg'@]4g&Th,g=cQ+g'@]4g&Tj\!87GOg&M-H
-g'.Q2g&Tj\!<1[S!8?-,rn7GSg=cQ)g&M-Jg&M-Og'Ic5g&Th,!8?-,rRq5Orn7GSg=cQ&gACsM
-g&M,Rg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeHc0*eH","e^XZteGoUIeGoUKeHc0*eH","e^X[!eHc0*eH".M!7_)JeGoUC
-eHQ$(eH".M!<1LN!7fU"rm_)Ne^XZteGoUEeGoUJeHl6+eH","!7fU"rRClJrm_)Ne^XZqebfFH
-eGoTMeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec5XOec41Mr;QcIq#C?Ds8N,Ms8LRKs8UXLrrUaNs8LOKs7OqBs8UXJ
-s8UXLrrUaNec,RNec5["rr;cDrVulIs8W,LrVulIr;ZfIs8ViD"TR$Pe^aWuXOR=NMU__,VUb^!
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-FgA_0PgA_-Tg&Tj\qu?`Np]1<Irr<)R!<1^P!<:dQ!!:jS!<1[P!;5(G!<:dO
-!<:dQ!!:jSgAV'Sg&M-,rW)`Ir;ciNrrE)Qr;ciNquHcNrrDfI"9@-Ug=lK*XP*XSMV8%1VV;'$
-o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUAec,XKec,UOeH".Mqu?`Ip]1<Drr<)M!<1OK!<:UL!!:[N!<1LK!;4nB!<:UJ
-!<:UL!!:[Nec#ONeGoU"rW)`Dr;ciIrrE)Lr;ciIquHcIrrDfD"9?sPe^aTuXOR:NMU_\,VUb^!
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,ec5[BeH#XCeH5d$s/+<Hs,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1gA_0Gg&M-Hg&_9.!2eHM!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,ec,XBeGoUCeH,a$!2e9H!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,ec#ODec5Z9eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1gAM$IgA_/>g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eboLDec,W9eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5eboLGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gAM$Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5eboLGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4ec#RHeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gAV*Mg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4ec#RHeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5ec5[Jec5[Lec5[>ec5[:eH#X?ec5[Jec5[KeH#XBeH#XKeH#Wrec5[>eH5d$
-s8CIJs4,X"s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-:gA_0OgA_0QgA_0CgA_0?g&M-DgA_0OgA_0Pg&M-Gg&M-Pg&M-"gA_0Cg&_9.
-!<(UO!7fd'!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU5ec,XJec,XLec,X>ec,X:eGoU?ec,XJec,XKeGoUBeGoUKeGoTrec,X>eH,a$
-!<(FJ!7fU"!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#X4eH#XIeH#XKeH#X=eH#X;eH#X=eH#XIeH#XJeH#XCeH#XKeH#WqeH#X>eHGp&
-s4,[!s4,X"s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-9g&M-Ng&M-Pg&M-Bg&M-@g&M-Bg&M-Ng&M-Og&M-Hg&M-Pg&M-!g&M-Cg&qE0
-!8?0+!7fd'!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU4eGoUIeGoUKeGoU=eGoU;eGoU=eGoUIeGoUJeGoUCeGoUKeGoTqeGoU>eH>m&
-!7fX!!7fU"!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAec5[Kec5[HeH#XIeH#XKec,UJec5[Iec5[KeH>j%s8W)K!<;`B!<<#Js8W)K
-s8VuH!<;uI!<<#J!<;fDrVluMs8UXKrrUaNs8LONs4./LrRLoIq:,NGec,UKec5[LeH>j%s8W#I
-#QN?)s8UXLs7t4Cs8LOKs4,X"s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-FgA_0PgA_0Mg&M-Ng&M-PgAV*OgA_0NgA_0Pg&h?/!!*#P!!)]G!!)uOrrE&P
-rrDrM!!)rN!!)uO!!)cIr;ZrR!!(aP!!:jS!<1[S!87DQrS%5Nq:YiLgAV*PgA_0Qg&h?/!!)rN
-#6<K3!!(^Q!;Y@H!<1[P!7fd'!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAec,XKec,XHeGoUIeGoUKec#RJec,XIec,XKeH5g%!!*#K!!)]B!!)uJrrE&K
-rrDrH!!)rI!!)uJ!!)cDr;ZrM!!(RK!!:[N!<1LN!7_&LrRLlIq:,KGec#RKec,XLeH5g%!!)rI
-#6<<)!!(OL!;Y1C!<1LK!7fU"!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeH>j%ec5Tu!<;uI!<;uI!<<&K"96p%s8CIJs8LOSs4,["e^a]Ms8CIJs7XtC
-s8CIMs4,["rRCoJr7(fIr7(fIr7(fIpXK9Drm_)Mec5Ns!<<&K#636(s4,["p!j'BrRD5Se^a]M
-ec41Ms8CIJs8LONs4,["psfHGec5Tu!<:U"!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&h?/g&V**!!)rN!!)rN!!*#P!s%'/!<(UO!<1[X!8?-,g=cP\!<(UO!;>+H
-!<(UR!8?-,rRq5Or7V,Nr7V,Nr7V,NpY#TIrn7DRg&V$(!!*#P"p!B2!8?-,p"BBGrRqPXg=cP\
-g&Tj\!<(UO!<1[S!8?-,pt>cLg&V**!!(R'!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeH5g%eH#Qu!!)rI!!)rI!!*#K!s$m%!<(FJ!<1LS!7fU"e^XZM!<(FJ!;=qC
-!<(FM!7fU"rRClJr7(cIr7(cIr7(cIpXK6Drm_&MeH#Ks!!*#K"p!3(!7fU"p!j$BrRD2Se^XZM
-eH".M!<(FJ!<1LN!7fU"psfEGeH#Qu!!(R"!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBeH#XIec,UHeH#XIeH#XKeHQ!'ec41Mrr;uJ!<;uIs8VT=!<<#J!<;uIrr;oH
-!<;uI!<;uI!<;fD!<<&K!rpgNrRLoIrm_,Ne^a^!ec5[DeH#XJec,UJeH>j%ec5Tu!<<&K"96p%
-s7k+Gs4./JeH#X"eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg&M-NgAV*Mg&M-Ng&M-Pg'%K1g&Tj\rW)rO!!)rNrrDQB!!)uO!!)rNrW)lM
-!!)rN!!)rN!!)cI!!*#P!W^pSrS%5Nrn7GSg=cQ+gA_0Ig&M-OgAV*Og&h?/g&V**!!*#P!s%'/
-!;P7L!87GOg&M-'g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeGoUIec#RHeGoUIeGoUKeHGs'eH".MrW)rJ!!)rIrrDQ=!!)uJ!!)rIrW)lH
-!!)rI!!)rI!!)cD!!*#K!W^aNrRLlIrm_)Ne^X[!ec,XDeGoUJec#RJeH5g%eH#Qu!!*#K!s$m%
-!;P(G!7_)JeGoU"eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XBeHl3*ec42"e^a]teH#XIeH#XKeHl3*ec42"e^a^!eHl3*ec41Ms4./JeH#XC
-eH#XJeHl3*ec42"e^a]teH#XIeH#XIeH#XDeHZ'(ec5["s8LONs4,["rm_,Ne^a]teH#XEeH#XJ
-eHu9+ec41Ms4,["rRCoJrm_,Ne^a]qeboIHeH#X"eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg'@]4g&Th,g=cQ)g&M-Ng&M-Pg'@]4g&Th,g=cQ+g'@]4g&Tj\!87GOg&M-H
-g&M-Og'@]4g&Th,g=cQ)g&M-Ng&M-Ng&M-Ig'.Q2g&M-,!<1[S!8?-,rn7GSg=cQ)g&M-Jg&M-O
-g'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ&gACsMg&M-'g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeHc0*eH","e^XZteGoUIeGoUKeHc0*eH","e^X[!eHc0*eH".M!7_)JeGoUC
-eGoUJeHc0*eH","e^XZteGoUIeGoUIeGoUDeHQ$(eGoU"!<1LN!7fU"rm_)Ne^XZteGoUEeGoUJ
-eHl6+eH".M!7fU"rRClJrm_)Ne^XZqebfFHeGoU"eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec5XOec41Mr;QcIq#C?Ds8N,Ms8LRKs8UXLrrUaNs8LOKs7OnBs8CLJ
-s8LRKrr^gOe^aTt!7h#Is4%,Lp!s*B!7h#Is4./L!nI>$rr3)Ns8UXKs7k.Cs8LRKs8LRJs8LRH
-s8UXLs7b%Hs4./"ec#O!eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-FgA_0PgA_-Tg&Tj\qu?`Np]1<Irr<)R!<1^P!<:dQ!!:jS!<1[P!;5%G!<(XO
-!<1^P!!CpTg=lH)!8@>Ns4RGQp"KEG!8@>Ns4[JQ!nmY.rW!&S!!(aP!;P:H!<1^P!<1^O!<1^M
-!<:dQ!;G1M!87G,gAM$&g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAec,XKec,UOeH".Mqu?`Ip]1<Drr<)M!<1OK!<:UL!!:[N!<1LK!;4kB!<(IJ
-!<1OK!!CaOe^aQt!7guIs4%)Lp!s'B!7guIs4.,L!n@;$rW!&N!!(RK!;P+C!<1OK!<1OJ!<1OH
-!<:UL!;G"H!7_)"eboL!eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WYeH#X2eH#X?eH#X$eH#XBeH#XCeH5d$s3T9rs,,>,s/+?HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M,^g&M-7g&M-Dg&M-)g&M-Gg&M-Hg&_9.!79F"!/fJ1!2eKMJb$\Xs81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoTYeGoU2eGoU?eGoU$eGoUBeGoUCeH,a$!796r!/f;,!2e<HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#WXeH#X4eH#X>eH#X%ec#ODec5ZceH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,]g&M-9g&M-Cg&M-*gAM$IgA_/hg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTXeGoU4eGoU>eGoU%eboLDec,WceGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5eboLGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gAM$Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5eboLGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4ec#RHeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gAV*Mg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4ec#RHeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XCec5[;ec5[Kec5[4ec5[BeH5d$s8CIJs5DK.s,,>,s,,>,s/+?HKCZ_Us81=M
-V#TT>]`<Q~>
-!<E0!joD+?g&M-HgA_0@gA_0PgA_09gA_0Gg&_9.!<(UO!9)W3!/fJ1!/fJ1!2eKMJb$\Xs81LR
-U&X9;\c@6~>
-!<E0!joD4BeGoUCec,X;ec,XKec,X4ec,XBeH,a$!<(FJ!9)H.!/f;,!/f;,!2e<HKCZ_Us81=M
-V#TT>]`<Q~>
-!<E0!joD4BeH#XBeH#X:eH#XJeH#X3eH#XBeHGp&s4,[!s5DK.s,,>,s,,>,s/+?HKCZ_Us81=M
-V#TT>]`<Q~>
-!<E0!joD+?g&M-Gg&M-?g&M-Og&M-8g&M-Gg&qE0!8?0+!9)W3!/fJ1!/fJ1!2eKMJb$\Xs81LR
-U&X9;\c@6~>
-!<E0!joD4BeGoUBeGoU:eGoUJeGoU3eGoUBeH>m&!7fX!!9)H.!/f;,!/f;,!2e<HKCZ_Us81=M
-V#TT>]`<Q~>
-!<E0!joD4BeH#XBec,UJec5[KeH>j%s8W&Jrr;rI!<<#Js8VlEs8W#Is8W)K"96pOs7t4Cs8LOK
-s5DK.s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-GgAV*OgA_0Pg&h?/!!)uOrW)oN!!)uOrrDiJrrDuNrrE&P!s%$T!;Y@H!<1[P
-!9)W3!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUBec#RJec,XKeH5g%!!)uJrW)oI!!)uJrrDiErrDuIrrE&K!s$jO!;Y1C!<1LK
-!9)H.!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeH>j%ec5Tu!<<&K$3/Q+s4,["e^a]ueH#XKeH>j%ec5Bo!<<&K#liH*s4,["
-ec5Bo!rpgNrRCoJiRIr.MU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Gg&h?/g&V**!!*#P#lr]5!8?-,g=cQ*g&M-Pg&h?/g&Um$!!*#P#QWT4!8?-,
-g&Um$!W^pSrRq5OiS"83MV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeH5g%eH#Qu!!*#K#lrN+!7fU"e^XZueGoUKeH5g%eH#?o!!*#K#QWE*!7fU"
-eH#?o!W^aNrRClJiRIo.MU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XBeHQ!'ec41Mrr;uJ$3/Q+s4,["e^a]ueH#XKec,UDec,UJeH#XIec5[CeH5d$
-s8CIJs5DK.s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Gg'%K1g&Tj\rW)rO#lr]5!8?-,g=cQ*g&M-PgAV*IgAV*Og&M-NgA_0Hg&_9.
-!<(UO!9)W3!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUBeHGs'eH".MrW)rJ#lrN+!7fU"e^XZueGoUKec#RDec#RJeGoUIec,XCeH,a$
-!<(FJ!9)H.!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeHl3*ec42"e^a^!eHu9+ec41Ms4,["rRCoJrm_,Ne^a]reH>j%ec5X!#liH*
-s4,["ec5Epr;ZcH!<;$.!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg'@]4g&Th,g=cQ+g'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ'g&h?/g&V-+#QWT4
-!8?-,g&Up%quH`M!!)!3!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeHc0*eH","e^X[!eHl6+eH".M!7fU"rRClJrm_)Ne^XZreH5g%eH#U!#QWE*
-!7fU"eH#BpquH`H!!)!.!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XCec,RSec5["s8UXLec,RTec5["ec5["s4.&Is4./LpsoEE!S.5Lec5[Lec5XN
-ec5[EeHGp&s4,Zus5MQ/s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-HgAV'Xg&M-,!!(^QgAV'Yg&M-,g&M-,!8@>Ns4[JQptG`J!SRPQgA_0QgA_-S
-g&M-Jg&qE0!8?0*!92]4!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUCec#OSeGoU"!!(OLec#OTeGoU"eGoU"!7guIs4.,LpsoBE!S%2Lec,XLec,UN
-eGoUEeH>m&!7fWu!92N/!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#WTeH5d$s4l-)s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,Yg&_9.!8Q9.!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoTTeH,a$!8Q*)!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc^(_Y!j0JcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc^*_Z0Z2gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKE&Xbs7t4FK*&ads81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAca(_Z0Z3gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec1:%^&S-.ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAca(_Z0Z4gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAca'_Z0Z5gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAca'_Z0Z6gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca&_Z0Z7gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca&_Z0Z8gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca%_Z0Z9gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca%_Z0W;g4=hQ_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca$_>sW8Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca$_?0agJc!=as81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca#_Z,2a_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca#_>o/`_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHeGt6js81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,Mg&Q]ms81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHeGt6js81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#W/eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,4g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoT/eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZXKBC\fV#TT>]`<Q~>
-!<E0!joD+Pg4=g+JUrBTJ`bYiU&X9;\c@6~>
-!<E0!joD4SeU`@(K7SZXKBC\fV#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZYK)kr6eHMcKk2s>WJ,~>
-!<E0!joD+Pg4=g+JUrBUJH5`4g'+2Mk2s5TJ,~>
-!<E0!joD4SeU`@(K7SZYK)kr6eHMcKk2s>WJ,~>
-!<E0!joD4Sec19n]`J/H]`3PrJ\@A_s8V`)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`q_?'\R]`3Q"J\m_is8V`.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19n]`J/H]`3PrJ\@A_s8V`)s8V63"f21\k.LbF~>
-!<E0!joD4Sec19p^&S*5K>"tu!/#j9J\@A_rVuT)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`s_Z0W:J\o,#!.f^<J\m_irVuT.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19p^&S*5K>"tu!/#j9J\@A_rVuT)s8V63"f21\k.LbF~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S,Jec18Q]n*k_^&.j)^&S,peHMJVS=BQZJ,~>
-!<B_0RJY_<JbR%\s8RWO_Z0YOgAc_T_L]Ri_YaB._Z0Yug'*nUR@+$TJ,~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S,Jec18Q]n*k_^&.j)^&S,peHMJVS=BQZJ,~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s1m1bK7U^e]p?A3s8UXJs8'G/s5qi8SB\a\S,e'~>
-!!)u?!1E`<s+1!_rVm&TJUt]<s1m@gJUt[h_Nr(=s8UgOs8'V4s5r#=REE+PR/ha~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s1m1bK7U^e]p?A3s8UXJs8'G/s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S,Jec18Q]n*k_^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_YsN6gAc^*_Z0YOgAc_T_L]Ri_Z0Z7gAV'L_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S,Jec18Q]n*k_^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S,Jec18Q]n*k_^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_YsN4gAc^*_Z0YOgAc_T_L]Ri_Z0Z5gAV'N_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S,Jec18Q]n*k_^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S,Jec18Q]n*k_^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_YsN2gAc^*_Z0YOgAc_T_L]Ri_Z0Z3gAV$Q_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S,Jec18Q]n*k_^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ebb!oec17'^&S,Jec18Q]n*k_^&S--ebt.#s5qi8SB\a\S,e'~>
-!<C:A\cA/qgA?HrgAc^*_Z0YOgAc_T_L]Ri_Z0Z2gAQU&s5r#=REE+PR/ha~>
-!<CCD]`=T"ebb!oec17'^&S,Jec18Q]n*k_^&S--ebt.#s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S,Jec18Q]n*k_^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_Yo&^gAc^*_Z0YOgAc_T_L]Ri_Z0Z3gAQR(_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S,Jec18Q]n*k_^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S,Jec18Q]n*k_^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_Yo&`gAc^*_Z0YOgAc_T_L]Ri_Z0Z5gAQU%_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S,Jec18Q]n*k_^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S,Jec18Q]n*k_^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_Yo&bgAc^*_Z0YOgAc_T_L]Ri_Z0Z7gAQU#_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S,Jec18Q]n*k_^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8Tmbs+>m9J\@A_s8W,LrIas[s8V63"e<iN]po(Q~>
-!<C:A\cA/qgAca"_Yo#hg4=gls8Tmgs+,a<J\m_is8W,QrIOg^s8V68"e!NE\sWPK~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8Tmbs+>m9J\@A_s8W,LrIas[s8V63"e<iN]po(Q~>
-!<CCD]`=T"ec19r^&3Ka^&S,Jec18Q]n*k_^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<C:A\cA/qgAc`u_Yerd_Z0YOgAc_T_L]Ri_Z0Z7Jb[+^s5r#=REE+PR/ha~>
-!<CCD]`=T"ec19r^&3Ka^&S,Jec18Q]n*k_^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec19p^&EWc^&S,HK7U^e]p?A3s8R`F^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAc`s_Z#)f_Z0YMJUt[h_Nr(=s8RZD_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec19p^&EWc^&S,HK7U^e]p?A3s8R`F^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19n]`Ni"s1O&9]n*k_]`J.coY(;)k1'X*c+Uf\!.Y~>
-!<C:A\cA/qgAc`q_?,;*s1Nu7_L]Ri_?'[foYUY.k1U!,b.>0P!.Y~>
-!<CCD]`=T"ec19n]`Ni"s1O&9]n*k_]`J.coY(;)k1'X*c+Uf\!.Y~>
-!<CCD]`=T"ec18Qs+13$s02OceHMJf]tKp9J,~>
-!<C:A\cA/qgAc_Ts+13$s02Ocg'*ne]"4:0J,~>
-!<CCD]`=T"ec18Qs+13$s02OceHMJf]tKp9J,~>
-!<CCD]`=T"eGt5Qs+13$s0)IbeHMJf]tKp9J,~>
-!<C:A\cA/qg&Q\Ts+13$s0)Ibg'*ne]"4:0J,~>
-!<CCD]`=T"eGt5Qs+13$s0)IbeHMJf]tKp9J,~>
-!<CCD]`=RReUc8%eW&)_SB\a\S,e'~>
-!<C:A\cA.Lg4@t/g5XeiREE+PR/ha~>
-!<CCD]`=RReUc8%eW&)_SB\a\S,e'~>
-!<CCC^%%VDUk,=mUogEm^%.Znc2PBWS,e'~>
-!<C:@]()2>Tn/ngTrk!g](26hb5SsQR/ha~>
-!<CCC^%%VDUk,=mUogEm^%.Znc2PBWS,e'~>
-!]^8*rOqgI!53s`JcC<$XoIq9rk/B'!<7Q~>
-!^m%2rOVUC!4ma]JcC<$XoIq6rji0!!<7Q~>
-!cn@drOqgI!53s`JcC<$XoIq9rk/B'!<7Q~>
-!\j]"n%A^kJ`_OGJ`a)s!6suG!h98jJ,~>
-!^m%2n%&LeJ`_OGJ`a)s!6XcA!gs&gJ,~>
-!cn@dn%A^kJ`_OGJ`a)s!6suG!h98jJ,~>
-s#C,\S=K,_!1\W&J`_OGXl]W.n\+sm!W`9#J,~>
-s$QngR@3TV!1AE#J`_OGXl]W+n[eag!W`9#J,~>
-s)S5AS=K,_!1\W&J`_OGXl]W.n\+sm!W`9#J,~>
-">Mnk!!)MYJ\?WJJ\A.unXTUZrr7K~>
-r^?bdn<nj=J\$EDXLdqirrE&uJ,~>
-"DW"!!!)MYJ\?WJJ\A.unXTUZrr7K~>
-"?A1s0fadbJH16$MZE\TJ,~>
-r'Z)9JH16$MZE\TJ,~>
-rc8*TF+F=B!.b-.!;ukI~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/note.gif b/lib/et/doc/src/note.gif
deleted file mode 100644
index 6fffe30419..0000000000
--- a/lib/et/doc/src/note.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/notes.gif b/lib/et/doc/src/notes.gif
deleted file mode 100644
index e000cca26a..0000000000
--- a/lib/et/doc/src/notes.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/notes.xml b/lib/et/doc/src/notes.xml
index 5abab9766c..8611955d3d 100644
--- a/lib/et/doc/src/notes.xml
+++ b/lib/et/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Event Tracer (ET) Release Notes</title>
@@ -28,12 +28,50 @@
<rev>%VSN%</rev>
<file>notes.xml</file>
</header>
- <p>This document describes the changes made to the Event Tracer (ET) system
- from version to version. The intention of this document is to
- list all incompatibilities as well as all enhancements and
- bugfixes for every release of Event Tracer (ET). Each release of Event Tracer (ET)
- thus constitutes one section in this document. The title of each
- section is the version number of Event Tracer (ET).</p>
+ <p>This document describes the changes made to the <c>Event Tracer
+ (ET)</c> system from version to version. The intention of this
+ document is to list all incompatibilities as well as all
+ enhancements and bugfixes for every release of <c>Event Tracer
+ (ET)</c>. Each release of <c>Event Tracer (ET) </c> thus constitutes
+ 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.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Thanks to Olle Mattsson the GUI parts are rewritten to
+ use <c>wxWidgets</c>. For the time being it is still
+ possible to use the old <c>GS</c> based version of the tool,
+ but it is deprecated. The <c>wxWidgets</c> based version is
+ started by default.</p>
+
+ <p>A print function has been added, in order to enable
+ printing of sequence charts.</p>
+
+ <p>A new tutorial has been added to the documentation. It is
+ based on <c>Jayson Vantuyl's</c> article
+ <c>http://souja.net/2009/04/making-sense-of-erlangs-event-tracer.html</c>.</p>
+
+ <p>The functions <c>et:trace_me/4</c> and
+ <c>et:trace_me/5</c> has been introduced in order to replace
+ the deprecated functions <c>et:report_event/4</c> and
+ <c>et:report_event/5</c>. Hopefully the new names makes it a
+ little more obvious what the intended usage of the functions
+ are.</p>
+
+ <p>The <c>max_events</c> configuration parameter to
+ <c>et_viewer</c> is not used any more. Now the event cache
+ in the <c>Viewer</c> only contains those events that
+ actually are displayed in the GUI.</p>
+
+ <p>Own Id: OTP-8058</p>
+ </item>
+ </list>
+ </section>
+
+</section>
<section><title>ET 1.3.3</title>
@@ -130,8 +168,8 @@
<section>
<title>Improvements and new features</title>
- <p>This is the first release of the Event Tracer (ET) as
- a stand-alone application.</p>
+ <p>This is the first release of the <c>Event Tracer (ET)</c> as
+ a stand-alone application separated from the Megaco application.</p>
</section>
</section>
</chapter>
diff --git a/lib/et/doc/src/part.xml b/lib/et/doc/src/part.xml
index d0375ffaf9..627aee866d 100644
--- a/lib/et/doc/src/part.xml
+++ b/lib/et/doc/src/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Event Tracer (ET) Users Guide</title>
@@ -32,7 +32,8 @@
and provides tools for collection and graphical viewing of trace data.</p>
</description>
<xi:include href="et_intro.xml"/>
- <xi:include href="et_architecture.xml"/>
+ <xi:include href="et_tutorial.xml"/>
+ <xi:include href="et_desc.xml"/>
<xi:include href="et_examples.xml"/>
</part>
diff --git a/lib/et/doc/src/ref_man.gif b/lib/et/doc/src/ref_man.gif
deleted file mode 100644
index b13c4efd53..0000000000
--- a/lib/et/doc/src/ref_man.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans.gif b/lib/et/doc/src/sim_trans.gif
deleted file mode 100644
index e3ab0bd3f1..0000000000
--- a/lib/et/doc/src/sim_trans.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans.png b/lib/et/doc/src/sim_trans.png
new file mode 100644
index 0000000000..0a3a8fdcb5
--- /dev/null
+++ b/lib/et/doc/src/sim_trans.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans.ps b/lib/et/doc/src/sim_trans.ps
deleted file mode 100644
index efc48162b7..0000000000
--- a/lib/et/doc/src/sim_trans.ps
+++ /dev/null
@@ -1,6595 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: (ImageMagick)
-%%Title: (sim_trans.ps)
-%%CreationDate: (Mon Oct 14 16:45:00 2002)
-%%BoundingBox: 0 0 512 426
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 1
-%%Orientation: Portrait
-%%PageOrder: Ascend
-%%Pages: 1
-%%EndComments
-
-%%BeginDefaults
-%%EndDefaults
-
-%%BeginProlog
-%
-% Display a color image. The image is displayed in color on
-% Postscript viewers or printers that support color, otherwise
-% it is displayed as grayscale.
-%
-/DirectClassPacket
-{
- %
- % Get a DirectClass packet.
- %
- % Parameters:
- % red.
- % green.
- % blue.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile color_packet readhexstring pop pop
- compression 0 eq
- {
- /number_pixels 3 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add 3 mul def
- } ifelse
- 0 3 number_pixels 1 sub
- {
- pixels exch color_packet putinterval
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/DirectClassImage
-{
- %
- % Display a DirectClass image.
- %
- systemdict /colorimage known
- {
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { DirectClassPacket } false 3 colorimage
- }
- {
- %
- % No colorimage operator; convert to grayscale.
- %
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { GrayDirectClassPacket } image
- } ifelse
-} bind def
-
-/GrayDirectClassPacket
-{
- %
- % Get a DirectClass packet; convert to grayscale.
- %
- % Parameters:
- % red
- % green
- % blue
- % length: number of pixels minus one of this color (optional).
- %
- currentfile color_packet readhexstring pop pop
- color_packet 0 get 0.299 mul
- color_packet 1 get 0.587 mul add
- color_packet 2 get 0.114 mul add
- cvi
- /gray_packet exch def
- compression 0 eq
- {
- /number_pixels 1 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add def
- } ifelse
- 0 1 number_pixels 1 sub
- {
- pixels exch gray_packet put
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/GrayPseudoClassPacket
-{
- %
- % Get a PseudoClass packet; convert to grayscale.
- %
- % Parameters:
- % index: index into the colormap.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile byte readhexstring pop 0 get
- /offset exch 3 mul def
- /color_packet colormap offset 3 getinterval def
- color_packet 0 get 0.299 mul
- color_packet 1 get 0.587 mul add
- color_packet 2 get 0.114 mul add
- cvi
- /gray_packet exch def
- compression 0 eq
- {
- /number_pixels 1 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add def
- } ifelse
- 0 1 number_pixels 1 sub
- {
- pixels exch gray_packet put
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/PseudoClassPacket
-{
- %
- % Get a PseudoClass packet.
- %
- % Parameters:
- % index: index into the colormap.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile byte readhexstring pop 0 get
- /offset exch 3 mul def
- /color_packet colormap offset 3 getinterval def
- compression 0 eq
- {
- /number_pixels 3 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add 3 mul def
- } ifelse
- 0 3 number_pixels 1 sub
- {
- pixels exch color_packet putinterval
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/PseudoClassImage
-{
- %
- % Display a PseudoClass image.
- %
- % Parameters:
- % class: 0-PseudoClass or 1-Grayscale.
- %
- currentfile buffer readline pop
- token pop /class exch def pop
- class 0 gt
- {
- currentfile buffer readline pop
- token pop /depth exch def pop
- /grays columns 8 add depth sub depth mul 8 idiv string def
- columns rows depth
- [
- columns 0 0
- rows neg 0 rows
- ]
- { currentfile grays readhexstring pop } image
- }
- {
- %
- % Parameters:
- % colors: number of colors in the colormap.
- % colormap: red, green, blue color packets.
- %
- currentfile buffer readline pop
- token pop /colors exch def pop
- /colors colors 3 mul def
- /colormap colors string def
- currentfile colormap readhexstring pop pop
- systemdict /colorimage known
- {
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { PseudoClassPacket } false 3 colorimage
- }
- {
- %
- % No colorimage operator; convert to grayscale.
- %
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { GrayPseudoClassPacket } image
- } ifelse
- } ifelse
-} bind def
-
-/DisplayImage
-{
- %
- % Display a DirectClass or PseudoClass image.
- %
- % Parameters:
- % x & y translation.
- % x & y scale.
- % label pointsize.
- % image label.
- % image columns & rows.
- % class: 0-DirectClass or 1-PseudoClass.
- % compression: 0-none or 1-RunlengthEncoded.
- % hex color packets.
- %
- gsave
- /buffer 512 string def
- /byte 1 string def
- /color_packet 3 string def
- /pixels 768 string def
-
- currentfile buffer readline pop
- token pop /x exch def
- token pop /y exch def pop
- x y translate
- currentfile buffer readline pop
- token pop /x exch def
- token pop /y exch def pop
- currentfile buffer readline pop
- token pop /pointsize exch def pop
- /Times-Roman findfont pointsize scalefont setfont
- x y scale
- currentfile buffer readline pop
- token pop /columns exch def
- token pop /rows exch def pop
- currentfile buffer readline pop
- token pop /class exch def pop
- currentfile buffer readline pop
- token pop /compression exch def pop
- class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
- grestore
- showpage
-} bind def
-%%EndProlog
-%%Page: 1 1
-%%PageBoundingBox: 0 0 512 426
-DisplayImage
-0 0
-512 426
-12.000000
-512 426
-1
-0
-0
-256
-020202
-0a0a0a
-6272a4
-fea602
-fe0202
-bec2be
-fefefe
-c6c6d6
-424242
-7a86ae
-0202fe
-bebece
-717ace
-bebabe
-e6e6e6
-42568a
-6a72c6
-969296
-6272b6
-5a6e9e
-4a464a
-969ade
-9696d6
-5a6a96
-fefafe
-b6baee
-2a3662
-323e72
-f6f6f6
-324272
-9696ce
-5a6696
-7286c6
-6272ae
-969ab6
-e6e2e6
-f6f2f6
-3a4a8a
-969ac6
-728ac6
-526297
-626ea6
-7a8bce
-42569e
-9696be
-d6d6d6
-eeeeee
-555e9e
-828282
-dedade
-727eb6
-5a6aa6
-828eb5
-4a528a
-3a4a82
-5a6eae
-8a92ce
-52669e
-eeeaee
-4a5a9e
-6a7ac6
-9ea6d6
-627abe
-a6aac6
-a6aade
-7982ae
-4a5296
-424e96
-7278a6
-a7acce
-828ec6
-a6a6de
-727ac6
-5266ae
-bec2d6
-dedef6
-5a6eb6
-7282ce
-6a72bd
-8a96b6
-8a9ad1
-5a6aae
-969ad6
-808ad6
-cecece
-4256a6
-9e9ed6
-969bbe
-8a92d6
-d6dad6
-8292c6
-5a5e96
-dedede
-6266a6
-7a82ce
-8a96d6
-525d8a
-757eae
-5262a6
-e6e6f6
-3a4e8a
-969ed6
-626aae
-aeafd6
-9696b6
-6a6e9e
-5a66a6
-32427a
-7a86bd
-f6f6fe
-bebed6
-969ace
-dedfee
-9ea6de
-424a7f
-6276b6
-b6bade
-969ece
-7282c6
-424642
-a3a6c6
-8a8eb6
-8296ce
-6a72ae
-7986ce
-626a9e
-626eb6
-ced2ee
-8286b6
-cfd1e6
-707aae
-828ed6
-626ebe
-4a5ea6
-424e82
-3a427a
-4a5996
-3a4672
-4a569e
-8a96c6
-969ede
-b6bede
-96a2d6
-4a4a4a
-d6daee
-8292ce
-5a6296
-727ab8
-5a669e
-5a72be
-8a92b6
-626aa6
-9ea2de
-6a76a1
-6a6ea6
-7a82b7
-525a9e
-eeeef6
-4a5682
-42528a
-b6beee
-9e9ec6
-d4d6e6
-8a96be
-5a66b6
-a6aed6
-6a7ece
-6a7fc6
-8286ae
-7580a6
-525a96
-5a6ab6
-6a76be
-7a82d6
-a6a2a6
-7a8ac6
-eeeaf6
-c6c6ee
-9ea1ce
-d6d2d6
-7a86c6
-626eae
-525eae
-8a96de
-828ace
-e6e6ee
-8292de
-8a92c6
-c6c2d6
-6276be
-6b76ae
-435282
-acb5de
-828abe
-5262af
-626e9e
-6a7ab6
-727ece
-8a92be
-9ea2d6
-aeaaae
-e6e2f6
-8a92de
-9696c6
-828ebe
-c6cce5
-3a467a
-9e9ebe
-828ac6
-4a5e8a
-6a72a4
-424e8a
-5266b6
-62669e
-7a82c6
-96a2c6
-4a5e96
-5a62a6
-9eaad6
-424a8a
-7a86d6
-525ea6
-7a8aba
-4a56a6
-8a96ce
-6a76c6
-425296
-8a8ebe
-7282bc
-828ece
-6272be
-828ab6
-626696
-6a7abe
-626ab6
-5a66ae
-32466a
-5a6a9e
-5a629e
-a7aec6
-727ec6
-e6eaf6
-828aae
-e6e2ee
-4a5aa6
-d6dae6
-525e96
-727ebe
-324672
-dee2f6
-6a7aa6
-bec2e6
-3a4682
-5a6ebe
-4a578a
-8292d6
-ec89f8ecf800000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-00000089f889f8898787870000060606060606060606060606060606061aa0a0a0a0a0a0
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a019191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-1919191919191919191919191919191919191919191919c01a0606060606060606060606
-060606060606060606ae0606060606060606060606060606060606060606ae0606060606
-06060606060606060606060000878787ecec0006062d2d2d313131315c5c5c2323230e0e
-0e1abacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabaca
-bacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabaca
-bacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabaca
-bacabacabacabacabaca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca
-83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca
-83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca
-83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca8383838383838383838383838383
-838383838383838383838383838383838383838383838383838383838383838383838383
-838383838383838383838383838383838383838383838383838383838383838383838383
-838383838383838383838383838383838383838383838383838383838383838383838383
-838383838383838383838383838383838383838383838383838383838383838383838383
-838383838383838383838383838383838383838383838383838383838383ba831a0654b3
-b3b32d2d2d313131315c5c5c2323230e0eae0654b3b3b32d2d2d313131315c5c5c232323
-0e0eae0654b3b3b32d2d2d313131315c5c5c23060600ec891d0006b32d2d2d313131315c
-5c5c2323230e0e0e231ac5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5
-c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5
-c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5
-c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c548c548c50cc548c50cc548c50cc548c50cc548
-c50c4d48c50c4d48c50cad48c50cad48c50cdc48c50cdc48c50cdc48c50cdc48c50cdc48
-c50c5348c50cb8c5c50cb8c5c50cb8c5c54883c5c54883c5c54883c5c54883c5c54858c5
-c548cac5c548cac5c548cac5c5485fadc5485fadc5485fadc548b7adc50cb7adc5c5b7ad
-c5a615adc5a615adc5a615adc5a615adc5a615adc5a615adc5a615adc5a615adc5a615ad
-c5a615adc5a615adc5a68cadc5a68cadc5a68cadc5a68cadc5a68cadc5a68cadc5a68cad
-c5a68cadc5a68cadc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdc
-c5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdc
-c5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdc
-c5c58cc51a06b3b3b32d2d2d313131315c5c5c2323230e0e23ae06b3b3b32d2d2d313131
-315c5c5c2323230e0e23ae06b3b3b32d2d2d313131315c5c5c2323230e54001d1d00062d
-2d2d313131315c5c5c2323230e0e0e3a0e1aac3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c
-3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c
-3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3cc5464d3c3c3c3c3c3c3c3c3c3c3c3c3c3c
-3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c0c3c0c3c3c0c3c0c3c0c3c
-0c3c0c3c0c3c0c3c0ca70c3c0ca60c3c0cc50c3c0cc50c3c0c4d0c3c0c4d0c3c0c4d0c3c
-0c7c3c0c3cb4a60c3c7ca63c0c53a70c3c53a70c3c53a60c3c53a63c0ce5c53c0ce5c53c
-0c58c53c0cffc53c0c38c50c3c58c50c3c5fc50c3c580c0c3c580c0c3c580c0c3c5f0c3c
-3c504d3c3c504d3c0c504d3c0c504d3c0c154d3c0c154d3c0c154d3c0c154d3c0c654d3c
-0c654d3c0c654d3c0c654d3c0c654d3c0c654d3c0c654d3c0c654d3c0c654d3c0c8e4d3c
-0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c
-0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c
-0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c
-0c8e4d3c0c8e4d3c3c98c5e11a06b3b32d2d2d313131315c5c5c2323230e0e0e3aae06b3
-b32d2d2d313131315c5c5c2323230e0e0e3aae06b3b32d2d2d313131315c5c5c2323230e
-0e54008900062d2d2d313131315c5c5c2323230e0e0e3a3a231ae1acacacacacacacacac
-acacacacacacacacacacacacacacacacacacacacac4b4bacacacacacacacacacacacacac
-acacacacacacacacacacacacacacacacacacacacacacac5fb1ac6518067f4b4bacac1c18
-acacacacacacacacacacacacacacacacacacacacacacacacacacacacacace1ace110e110
-e110ac10ac6d1810ac6d1810ac10ac103c10ac104810ac104810ac10c510ac10c510ac10
-c510ac105ee1acb171e1e110b4e1ac10dce1ac10b40cac10b848e110b848e110b848e110
-8348e1108348e110910ce1105848e110580ce1105f48e1105f48e11016c5e11052c5e110
-52c5e11052c5e110150ce1e115c5e1e165c5e1e165c5e1e165a6e1e165a6e1e165a6e1e1
-65a6e1e156a6e1e156a6e1e198a6e1e198a6e1e198a6e1e198a6e1e1984de1e1984de1e1
-984de1e1984de1e1714de1e1714de1e1714de1e1714de1e1475ee1e1475ee1e1475ee1e1
-475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1
-475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1
-475ee1e1475ee1e1475ee1e1475ee1e1475ee1e11a18542d2d2d313131315c5c5c232323
-0e0e0e3a3aae18542d2d2d080808080808080808080e0e0e3a3aae18542d2d2d31080831
-5c5c5c0808230e0e0e3a0d0000062d2d31313108085c5c2323230e08083a3a3a231aeaea
-eaeaeaeaeaeaeaeaeaeaeab815eaeaeaeaeaeaeaeaeaeaeaeaeaeaea84907ffceaeaeaea
-eaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeab8181e436306
-aa898181fc846d6d1beab815eaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaea
-eaeaea84847e847e84848484ea6d6d1bea6d6d1b8484841284ea84107e84841084848438
-658484ac8484843c128484481284ea4006d684c5e6847ef04e8484d69aea84d610ea84d6
-10ea845e10ea845e108484b8108484b8108484b810848446e1847e83e1848438e1848438
-e1847ee0e1847ee03c847e5f3c8484163ceaea58e1eaea16e1abea16e1abea16aceaea16
-aceaea1648eaea1648eaea1648eaea1548eaea1548eaea1548eaea1548eaea1548eaab15
-48abea1548abea1548abea56e1eaab56e1eaab56e1eaab56e1eaea5648eaea5648eaea8e
-48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e
-48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e
-48eaea8e48eaea8e48eaea8e48eaea8e48eaea9848eaea98488484ea1a182d2d2d593131
-315c5c5c2323230e0e0e3a3a3aae062d2d2d59080808080808087777080e0e3a3a3aae06
-2d2d2d5908080808315c777708080e0e3a3a0d0000062d31312d080808082323230e0877
-14143a2e231aababababababababababababab6d18f4abababababababababababababab
-a451fcfcabababababababababababababababababababababababababababababababab
-abab63811b3b1c181bc2c2fcfca46d241bab6d18f4ababababababababababababababab
-abababababababababababa451a4aba4aba4aba4ab6d6d1bab6d6d1b51a451a4abab4ca4
-aba484a451a4e66d18dfe6ab51a4bd51aba4ac51aba43c377ff35151aba43ceaaba4c5ea
-ababc5eaa4ab7684a4ab76e6a4ab76e6aba4b484aba4b48451a4af84aba4af84aba446e6
-51a446e6aba45ae6ab51914eab51e04eab51e04eabab8b4eabab5facabab5facabab5fac
-abab5facabab50acabab50e9a4ab6fe9a4ab6f3ca4ab6fe9a4ab6fe9a4ab75e9a4ab75e9
-a4ab75e9a4ab75e9a4ab75e9a4ab75e9a4ab653cabab8e3cabab8e3cabab8e3cabab8e3c
-a4ab8e3ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73c
-a4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73c
-a4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4ab8ee9a4ab8ec4a4a456ab
-1a182d2d313131315c5c5c2323230e0e0e3a3a3a2eae182d2d2d311a0808080808770808
-770e3a3a3a2eae182d2d31b3080808080808080877770e3a3a3a0d000006313131310808
-080808230e77080814142e2e231aa4d4a4d4a4d47c4b189d8ea48d0606067cd4a4d4a4d4
-a4cd065fd4a4c09dc26d18a4d47c4b189d8ea4c0067cd4cd06b4a4cdfba4204b189d8ea4
-d4c9f9c0c9d4a4d4a49106a9fccd060606e96d18a4d46d6d1b8d0606067c7c4b189d8ea4
-d4c9f9c0c9d46d18a4d4a4d4a4d4da631806b0e9d4dab006b0dad449d46d6d1bd46d6d1b
-d4204b189d8e49d4da631806b0a78d06060627dab006b0dad412d4f9f974c94938068249
-493e84d449e9fdd4d43c84d4d4a74cd449a784d4d4764ca4497612d4492095d449b412a4
-49afe6d4d4af4ed449e5e649a4e5bdc2c291bdc2c291bdc2c238bdc2c25f73d4d47aacd4
-d4e0bdd4a4e0bdd4a48bbdd4d4e0bdd4d4e0bdd4d4503ed4d4503ed4d4503ea4d4503ea4
-d4503ea4d4503ea4d45093d4d475e9d4d465e9d4d465e9d4d4653ea4d465c4a4d48ec4a4
-d48ec4a4d48ec4d4d48ec4a4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4
-d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4
-d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4
-d48e3c49d48e3cc21a1c2d313131315c5c5c2323230e0e0e3a3a3a2e2eae1c2d31313108
-08081a0808777708083a3a3a2e2eae1c2d3131313108080808777708080e3a3a3a2e0d00
-0006313131312d080808770808081414142e2e9d311af4b6b6b6b6ea6d9d9abc06337e6d
-18f61bdfb6b6b6b6b6bb066e42b6b0456b6d241bea6d9d9abc0633d60696df9d0696df6d
-413b6d9d9abc0633b66d064b401bb6b6b674068642126d18601d6d6d1b9c6d241b7e6d18
-60866d9d9abc0633b66d064bda1b63c91bb6b6b6b6a506c94199689fd706cd174a0675b6
-b66d241b9c6d241b5d6d9d694a0633a506f94199680feb6d18602206cd174a06b2c2b66d
-06703f6b3206ef424ec2b69c10d9b69ce1d9b6b610d99cb63cd99cb693a4b6b6f7a4b69c
-f05db69c765db69c5e5db69cb466b69cb4eab69cafeab6b6b8eab6b6b8eab6b646eab6b6
-46eab69c467eb6b6e312b6b6bb12b6b6bb12b6b6bb12b6b63812b6b6e37bb6b6e37bb6b6
-384eb685384eb685384eb685384eb685384eb6b61e4eb6b61e4eb6b61eacb6b61eacb685
-6facb6b66facb6b66facb6b66facb6b66facb6b66facb6856facb6856facb6856facb685
-6facb6856facb6856facb6856facb6856facb6856facb6856facb6856facb6856facb685
-6facb6856facb6856facb6856facb6856facb6856facb6856facb6856facb6856facb685
-6facb6856fac85b66facb6b675acf4b61a1c313131315c5c5c2323230e0e0e3a3a3a2e2e
-2eae1c3131313108315c23235c0e0e0e143a3a2e2e2eae1c31313131312d080877080877
-0e3a3a3a2e2e0d000006315c5c5c232308087777140814143a2e24245c1adfdfdfdfdf75
-063f258b06f22b6d6d1be2dfdfdfdfdff485241864f00628256d6d1b6f063f258b06f23b
-064a2818b00b5106ce26063f258b06a82b6d18726bfc55dff481061b55f46d6d1b2b6d6d
-1bf46d6d1bf46d6d1b26063f258b06a82b6d18726b25f41b1b55dfdff49d06606b43e225
-63069ece49060e25f46d6d1bf46d6d1b52063f648b06a82e06601b2be264556d6d1b6306
-9efceb06b964f46d18ce1be249060764c2f4f47ec2f4f47ec2dff412c2f4f44e49f4f44e
-498a8ac449f4f493a4f4f4f0a4f4f4f051f4f47651f4f47651f4f4b4513bf46c33f4f4de
-29f4f4d04cf4f4d037f4f4b8668adfd0eadf8ad066df8ad0eadf8ad066df8ad0668af45a
-eadff45aeadf3b5a668af4bb668af4bb7e8af4bb7e8af48b7e8adfbb7e8a8abb7e8a3b8b
-7e8a3b8b7e8adfbb4cdf8abb4cdf8a8b4cdf8a1e7edf3b6f4cdf3b6f37dff46f37dff46f
-37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f
-37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f
-37dff46f37dff46f37dff46f7edf3b6f7edff42612f4f4551a1c31315c5c5c2323230e0e
-0e3a3a3a2e2e2e2424ae1c31313131082323230e0e0e3a3a082e2e2e2424ae1c31315c5c
-5c230808777708773a3a2e2e2e240d0000065c5c5c2323230e7708081414142e2e242424
-311af4f4f4f43ba50606060606cf436d6d1bf4f4f4f4f4f4f4f48d06f2744b1be26d241b
-a50606060606cf43902479a20b6357f31b670606060606a1256d6d1b55f4f4f4f4cd061b
-df3b6d241bdf6d241bf46d241bf46d6d1ba50606060606a1256d6d1bdfdfdff4f4f4f4f4
-df06061be28af4f418061b2b3b06066b3b6d241bf46d241ba50606060606cf06061df485
-2bf4626d6d1b18061b2b6a06061b516d6d1b49b6850607fc3bdf7eb6f4df12c2f43b7e62
-f4f41262f4f47b493bf4c4c23b55c4d93bdff7d93bdff75df4dff76af4dfe45d3bdf9beb
-3bdf6c33f48a6c37f42bc14c3b8ad07ef4dfd07ef4f4467ef43b467ef43b467ef43b467e
-f43b467ef4f4d07ef4f4467ef43b467ef4f4e312f4f4e3123bf4e3123bf4bb123bf48b12
-3bf48b123bf4bb123bf4bb123bf48b12f43b8b123b3b5012f43b6f12f43b1e12f43b1e12
-f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73
-f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73
-f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f4f41e73f43b1e12dff41e3b1a24315c
-5c31ae0808080808141408ae2e2e24242eae24315c5c5c0823230e0e0e3a3a3a8f2e2e24
-242eae24315c5c5c2308770808080814142e2e2e24240d0000065c5c2323230e0e0e1414
-08142e2e2424241c311a8a8a8a8a422606ef1b1b1b1bfc6d6d1b8a8a8a8a8a8a8a423206
-b324c66b2b6d6d1b2606ef1b1b1b1bfca50631b29606f5a51b2606ef1b1b1b1b256d6d1b
-428a8a8a8ac0069e2b8a6d6d1b426d6d1b8a6d6d1b8a6d6d1b2606ef1b1b1b1b256d6d1b
-8a8a8a8a8a8a8a8a8ab0061f8a428a8a630635426606631b2b6d6d1b426d6d1b2606ef1b
-1b1b1bf1061f8a8a42dd3b6d6d1bf10635dd9a06631b3b6d6d1b858a66063f878a662f8a
-8ab5dd8a8a29dd8a8a21628a8a7b628a8abe628a8abed98a8a93d98a8a936a8a8a616a8a
-8a326a8a8a9b6a8a8a9b5d8a8a9b5d8a8a9beb8a8a805d8a8ac1668a8ac1668a8ac1668a
-8ac1668a8ac1668a8acc668a8acc298a8acc298a8acc298a8a46298a8ae3b58a8ac6b58a
-8ac6298a8a96b58a8ac6298a8abb298a8a8b298a8a8b298a8a8bb58a8a8b298a8acb212b
-8acb218a8a26218a8a26218a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a
-8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a
-8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a26218a8a26218a
-8a269a421a9d5c5c5c2377777777770814148f8f2e2424241cae245c5c5c2308230e0e0e
-3a3a3a2e8f2e2424241cae245c5c5c23770877777714141414142e2424240d0000065c23
-23230e0e0e3a3a14142e2e2424241c24311a428a8a8a8a629d18269bbb808a6306d2628a
-8a8a8a42428a42b00606d3fc8a6d241b629d18269bbb808ad606060202060699fc629d18
-a19bbbc18a6d241b8a8a8a428a93064143426d241b8a6d241b426d241b426306d2b59d18
-a19bbbc18a6d241b428ab9638a8a8a8a8ab206b9bb9b2666a1064abecd06961b426d241b
-8a6d241b629d18a16cbbc1b206b9969b75668a6306d2a5064ac4cd064f1b8a6d241b8a42
-d7067d87669c8a42b59c8a4229b6424229628a429a628a42be628a42be5b8a42c4d98a42
-93d98a4232d98a4232d98a42e4d98a429b6a8a4280338a426c668a42c1668a42c15d8a8a
-c1978a8ac1668a8ac1668a8ac1668a8acc298a8accb5428accb5428acc7e428accb5428a
-e3b5428ac6b5428ac6b5428ac6b58a8ac6b58a8abbb5428abb7e428a8bb58a8a8b218a8a
-8b218a8a8b218a8acb21428acb21428a267b428a267b428a267b428a267b428a267b428a
-267b428a267b428a267b428a267b428a267b428a267b428a267b428a267b428a267b428a
-267b428a267b428a267b428a267b428a267b428a267b428a267b428a267b428a267b422b
-267b422b267b8a8acb7b8a2b1a245c5c2323080808081414141414142424241c24ae245c
-5c2323770e0e0e3a3a3a2e2e142424241c24ae245c5c235c087708083a3a1414148f2424
-241c0d0000062323230e0e0e3a3a3a2e2e2e2424241c1c1c311a4242424242427d4a1c06
-b079dbe3241869db424242424242426706071bdb426d6d1b42974a1c06b079db9c061889
-d318066bdb425d4a1c06b079db6d6d1b424242354235a2a2db426d6d1b426d6d1b426d6d
-1b42e32418d26a4a1c06b079db6d6d1b4242246d1b42354242424f700618f3e8d3226306
-f1681b87426d6d1b426d6d1b425d4a1c06b0793596700618f3e8dbe32418d2570e06f157
-1b87426d6d1b425b70a21b9c9c42427d9c42425d9c424229f642429add3542699c42427b
-5b4242be5b42424492424282ee424282924242619235429b9442429b6a42429b6a424280
-5d4242805d4242a85d4235805d4235805d423580d54242805d4242a8974242807d424280
-974242c17d4242e35d4242e35d4242795d4242e35d4235e35d424279974242e3294242e3
-7d4242797d4242797d4242797d42429629424296294242969a4242966942429669424296
-694242966942429669424296694242966942429669424296694242966942429669424296
-694242966942429669424296694242966942429669424296694242966942429669424296
-69424296694242966942422c7d42352c294242421a2e5c232323ae7708081408148f8fc8
-24241c1c1cae2e5c23232308777708141414148f1424241c1c1cae2e5c230e0e0e7777f1
-3a0e2e8f142424241c1c0d00000623230e0e0e3a3a3a2e2e2e2424241c1c1c18b31a35db
-35db353535d3871b1b1bdb35fc1b06060606060606443535ce1b1b3535421a1b3535d387
-1b1b1b7235351b1b35351b1b35353525871b1b1bfc351b1a3535db3535357d242c35d31b
-1b35d31b1b35351b1b3535721b1b8625871b1b1bdb351b1bdb35421b1a35db35353535fc
-1b1b1b1b2535871b1b1b6b4235d31b1b35421a1b353564871b1b1bdb35fc6b1b1b1bfefe
-721b1b866b1b1b1b6b355baa1b1b5b7824d187aa3535d5aa3535d5aa35357d9c35357df6
-db359af63535695b35359a5b3535d25b3535d25b3535445b3535445b3535615b35359392
-353541ee353541d53535a8d535dba8d5db35a8d5353580d5353580d5353580d5353580d5
-353580d5353580d53535e7d5353579d5353579d5353579d5353579d5353579d5353579d5
-3535797d353579693535797d3535797d3535797d35352c7d35352c7d35352c7d35352c69
-35352c6935352c6935352c6935352c6935352c6935352c6935352c6935352c6935352c69
-35352c6935352c6935352c6935352c6935352c6935352c6935352c6935352c6935352c69
-35352c6935352c6935352c6935352c6935352c693535c66935db2c351a2e2323230e0e0e
-3a3ab02e2e2e2424241c1c1c1cae2e2323230e0e0e3a3a3a2e2e2e2424241c1c1c1cae2e
-2323230e0e0e3a3a3a2e2e2e2424241c1c1c0d000006230e0e0e3a3a3a2e2e2e2424241c
-1c1c18182d1ad3d335d3d3d3d343d3d3d3d3d335649f0f1b1b1b1b1b1b1bfcd3644243d3
-d39f43d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d364d3d39fd3d3d3d3d3d343d343d3d3d3d3
-d3d39f7dcf25d364d3d3d3644364d3d3d3d3d3d3d3d39fd3d3d3d3d364d3d39fd3d3d3e2
-d342d3d3d3d364d3d3d3d3d3439fd3436443d3d39fd36464d39f43d3d30fd3d3d39fd3d3
-9f8a9f64d38a0f64d3880f9f43aa424343284264d3288878281b9f64d3ee8ad3d3178a64
-d31faa64d3c3d89fd37dd864d302aad36402aad3d3be92d3d39992d3d3999264d34462d3
-d3932fd3d36139d364611fd3d34192d3d34192d3354192d3d34192d3d34117d3d3de17d3
-d3de17d3d3de17d3d3e717d3d3e7edd3d3e717d3d3e717d3d3e717d3d3e717d3d3e71fd3
-d3e71fd3d33417d3d35a1386d39617d3d39613d3d3966964d3c6c364d3966964d3966964
-d39669d3d3967dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3
-d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3
-d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3967dd3d3967dd3d34f69d335967dd3
-1a3a23230e0e0e3a3a3a2e2e2e2424241c1c1c1818ae2e23230e0e0e3a3a3a2e2e2e2424
-241c1c1c1818ae2e23230e0e0e3a3a3a2e2e2e2424241c1c1c180d0000060e0e0e3a3a3a
-2e2e2e2424241c1c1c181818b31a7272368672db86868686863672db86dbdb723672db25
-72db648686368686867286dbdb8686d3868672db8686862586648672db86db868686db72
-64728686db8686dbdb727236728786dbdb8686db7272db25db72db86db86db8686867272
-72dbdbdb6472db7286368636db7286866472db868625867286868686db8672db86db8672
-db7286869f86727235bf8686fe9f7286febf257288bf868660358686f6356472726486db
-929e867292fe86861ffe86867dfe72727daa7286c3aa862569aa8672d2aa3686d2603686
-99f67286fa2f368644928672a9287272a9282586415b86db419286724192868641928686
-091fdb86091f8686091f8686091f7286a81f8686f21f8686f21f8686f21fdb86f21fdb86
-f21fdb86f21f8686341f8686341fdb86341786863417648679178686797d8686967d8686
-967d7286967d8686967d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d8686
-4f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d8686
-4f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d7272
-4fd53672967d72361a2e230e0e0e3a3a3a2e2e2e2424241c1c1c18181cae2e230e0e0e3a
-3a3a2e2e2e2424241c1c1c18181cae2e230e0e0e3a3a3a2e2e2e2424241c1c1c18180d00
-00060e3a3a3a2e2e2e2424241c1c1c1818180606b31af4f4dff43bdfdfdfdfdff4f43bdf
-3b3bf4f4f43b3bf43b3bdfdf3bdfdfdff48af43bdff48adfdff43bdfdfdf3bdf8adff43b
-df3bdfdfdf3bf48af4f48a3bf4df3b3bf4f4f4df3bdf3b3bf4df3bf4f43b3b3bf43bdf3b
-f43bdfdfdff4f4f43b3b3b8af43bf4df3bdf3bf4f4f48adff43bdf8a3bdff4dff4dfdf3b
-dff43bdf3bdff43bf4dfdf8adff4f4df3bf4df8af4f4df8af43bf43b3b3bdf3bdff4dfdf
-3bdff4f4f48af4dff4dff43bdf3bdfdff48a8a8a3bf4f43b3bf48a8a8af43b8a8a3b3bf4
-3b3b8a8af43bdff43bf4df3b8af48af43bdff48a8af43bdf8a3b8a8a3bf43b8a3bf4f48a
-3bdfdf3b3bdf8adf8af48a8a8adf8a8a8a8adf8a8af4df8a8adfdfdf8a8adf8a8adfdf8a
-df3bdf3b3b3b8af43b3bdf3bf4f48a8a3bdfdf42df8a42424242424242df42424242df42
-4242424242df4242dfdf4242df42df4242df4242df42df4242df42df4242df4242df42df
-4242df4242df42df4242df4242df42df4242df4242df42df4242df4242df42df4242df42
-42df42df4242df4242df42df4242df4242df42df4242df4242df42df4242df4242df42df
-42df4242dfdfdfdfdfdfdf8adfdf42421a3a0e0e3a3a3a2e2e2e2424241c1c1c18181806
-06ae3a0e0e3a3a3a2e2e2e2424241c1c1c1818180606ae3a0e0e3a3a3a2e2e2e2424241c
-1c1c181818060d000011111111111111111111111111111111111111111a010101010101
-010101010101010101010101010101010101010101010101010100010101010101010101
-010101010101010101010101010101010101010101010101000101010101010101010101
-010101010101010101010101010101010101010100010101010101010001010101010101
-010101010001010101010101010101010101010101010101010101010100010100010001
-010101010101010101010001010101010101010101010101010101010100010101010101
-010101010101010101010101010100010101010101010100010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010100010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101011a1111111111111111111111
-111111111111111111ae1111111111111111111111111111111111111111ae1111111111
-111111111111111111111111111111000006230e0eae0606060606060606060606060606
-060606060606060606060606060606060606061818181818060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060618060606180606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606ae18230e0d0000060e0e23ae060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-0606060606060606060606060606060606060606060606061830ae060e0e0d0000060e0e
-0eae06065959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959593030ae06
-0e0e0d0000060e0e23ae0606595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959593030ae060e0e0d0000060e0e0eae060659595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959593030ae060e0e0d0000060e0e0eae06065959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959592d3030ae060e0e0d0000060e0e0eae0606
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959593030ae060e0e0d00
-00060e0e0eae060659595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959592d
-3030ae060e0e0d0000060e0e0eae06065959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959593030ae060e0e0d0000060e0e0eae0606595959595959590000000000
-000000590000595959595959595959595959595959595959595900005959595900000000
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590000000059595959595959590000590000595959595959595959
-595959595959590000595959595959595959595959595959595959595959595959595959
-000000000000000059000059590000595959595959595959595959595959595959595959
-595959595959000059595900005959595959595959000059595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959592d3030ae060e0e0d0000060e0e0eae060659595959
-595959000059595959595959000059595959595959595959595959595959595959590000
-595959590000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595900005959000059595959595959000059000059
-595959595959595959595959595959000059595959595959595959595959595959595959
-595959595959595900005959595959595900005959000059595959595959595959595959
-595959595959595959595959595900005959590000595959595959595900005959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959593030ae060e0e0d0000060e0e
-0eae06065959595959595900005959595900005900005959000000005959595959595959
-595959595959590000595900005900005959000000005959000059590000595900005959
-000000005959000059000059595959595959595959595959000059595959595900000000
-595900005900005959000000005959590000000059590000000059590000000059590000
-590000595959595959595959595959590000595959590000590000590000000059590000
-000059590000590000595959595959595959595959590000595959000059590000000059
-590000590000590000595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959592d3030ae06
-0e0e0d0000060e0e0eae0606595959595959590000595959590000590000590000595900
-005959595959595959595959595959000059590000590000590000595900005900005959
-000059590000590000595900005900000000005959595959595959595959595900005959
-595959000059590000590000590000590000595900005900005959000059590000595900
-005959000059000000000059595959595959595959595959000059595959000059000059
-590000595900005959000059000000000059595959595959595959595959000059595900
-005900005959000059000059000000590000595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959593030ae060e0e0d0000060e0e0eae060659595959595959000000000059000059
-000059000059590000595959595959595959595959595900005959000059000059000059
-590000595900005900005900005959000059590000590000005959595959595959595959
-595959590000595959595900005959000059000059000059000059590000590000595959
-595959000059590000595900005900000059595959595959595959595959595900000000
-005900005900005959000059590000595900005900000059595959595959595959595959
-595900000000000000590000595900005900005900005959000059595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959592d3030ae060e0e0d0000060e0e0eae06065959595959595900
-005959595900005900005900000000000059595959595959595959595959595900595900
-595900005900000000000059590000590000590000595900000000000059000059595959
-595959595959595959595959000059595959590000595900005900005900005900000000
-000059000059595959595900005959000059590000590000595959595959595959595959
-595959590000595959590000590000595900005959000000000000590000595959595959
-595959595959595959590000595959000059000000000000590000590000595900005959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959593030ae060e0e0d0000060e0e0eae0606
-595959595959590000595959590000590000590000595959595959595959595959595959
-595959590000000059590000590000595959595959000059000059000059590000595959
-595900005959595959595959595959595959595900005959595959000059590000590000
-590000590000595959595900005959595959590000595900005959000059000059595959
-595959595959595959595959000059595959000059000059590000595900005959595959
-000059595959595959595959595959595959000059595900005900005959595959000059
-000059590000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959592d3030ae060e0e0d00
-00060e0e0eae060659595959595959000059595959000059000059000059590000595959
-595959595959595959595959590000595959000059000059590000595959000059590000
-595959000059590000590000595959595959595959595959595959595900005959000000
-005959000059000059000059000059590000590000595900005959000059000000595900
-005900005959595959595959595959595959595900005959595900005900005959000059
-000000595900005900005959595959595959595959595959595900005959590000590000
-595900005900005900000059000059595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-3030ae060e0e0d0000060e0e0ed706065959595959595900005959595900005900005959
-000000005959595959595959595959595959595959000059595900005959000000005959
-595900005959000059595959000000005959000059595959595959595959595959595959
-595900000000595900000000595900005900005959000000005959590000000059595959
-000059590000000059590000595959595959595959595959595959590000595959590000
-590000595959000059590000000059590000595959595959595959595959595959590000
-595959000059590000000059590000590000590000595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959592d3030ae060e0e0d0000060e0e0eae0606595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959000059595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959593030ae060e0e0d0000060e0e0eae060659595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595900005959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-59595959595959595959595959595959595959595959592d3030ae060e0e0d0000060e0e
-0eae06065959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595459545954595954595954595959595959595959595959593030ae06
-0e0e0d0000060e0e0eae0606595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595459595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595954595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959545959595959595459595459595459545959595459545959595959595959595959
-595959545959545959545959595959595959595959595959595959595959595959595959
-5959592d3030ae060e0e0d0000060e0e0eae060659595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595954595959545959595459595954595959545959595459595954595959545959
-595959595959595959595959595954595959545959595459595954595959595959595959
-595459595459545959545954595959595954595459545954595954595959545959595459
-595954595959545959595459595954595959545959595459595954595959545959595459
-595954595959545959595459595954595959545959595459595954595959545959595459
-595959595954595959595959595459595959595959595959595959595959595959595959
-545959545959545959595959595959595959595959595959595959595959595959595959
-5954595959595959595959593030ae060e0e0d0000060e0ef9ae06065959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595954595954595459595959595959595959595959595959595959595959595959595959
-595959595959595959595459545954595459545959595959595959595959595959595959
-595459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595459595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959592d3030ae060e0e0d0000060e0e0eae0606
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595954595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959593030ae060e0e0d00
-00060e0e0eae061c59595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595954595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959592d
-3030ae060e0e0d0000060e0e0eae0606303030303030303030303030303030303030a930
-3030a930a93030a930a930fa30303030a930303030303030303030303030303030303030
-30303030303030303030303030a93030a93030a9303030a93030a930fa30303030a93030
-303030303030303030303030303030303030303030303030303030303030303030303030
-3030303030a9303030fa3030a93030fa3030a930fa303030a93030303030303030303030
-3030303030303030303030a9303030a9303030a9303030a930fa30303030a93030303030
-303030303030303030303030303030a9303030a9303030a93030a93030a93030a930a930
-30a93030a930a93030a930a93030a930a93030a930a93030a930a93030a93030a93030a9
-303030a93030a930a93030a930a93030a930a93030a930a930a93030a930a930a93030a9
-3030a93030a930a930a930a93030a93030a930a930a930a93030a930a93030fa30a93030
-a930a93030a930a93030fa3030a930a93030fa3030a930a93030fa3030a930a93030fa30
-30a930a93030fa3030a930a93030fa3030a930a93030fa3030a930a93030fa3030a93030
-a930a93030a930a93030a930a93030a93030a93030a93030a93030a93030a930303030a9
-3030a930a930a93030a93030a930a930a93030a93030a930a93030a93030a93030fa30fa
-303030a9303030303030ae180e0e0d0000060e0e0eae0630303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030ae060e0e0d0000060e0e0eae59592d2d2d2d
-2d2d2d54592d2d2d2d2d2d2d2d5459595959595959595959595959592d54592d54592d2d
-2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d54595959595959
-595959595959595959545954592d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d
-2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d54595459595959595959595959595959
-5954592d2d2d2d2d54592d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d545959595959595959
-595959595959545954592d2d2d54592d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d5459595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959592d5459592d2d2d2d2d2dae060e0e0d0000060e0e
-0ed759595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959ae06
-0e0e0d0000060e0e0eae2d59595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959545959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959ae060e0e0d0000060e0e0e22595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595959595959595959595954595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959ae060e0e0d0000060e0e0e2259595959595959595959595959595959595959545959
-595959545959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595459595959595954595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959ae060e0e0d0000060e0e0e22595959595959
-595959595959595959595959595959595959595959595459595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-595954595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959545959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959000000000059595959595959595459590000
-595959595959595959000059000059595959595900005959595959595959595959595959
-595959595959595959595959000059595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595954595959595959595959595959595959ae06
-0e0e0d0000060e0e0e225959595959595959595959595959595959595959595959595959
-595959595959595959595954595959595959545959545959595459595959595959595959
-595959595959595959595959595959595959595959595959595954595959595959595959
-595959595459595959545959545959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954595959595900005959000059595959
-595959595959000059595959595959595959595900005959595959590000595959595959
-595959545959595959595959595959595959595900005959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959ae060e0e0d0000060e0e0eae59595959545954595954595959591c1c1c1c
-1c1c1c1c1c1c1c5959595959595959000000000000595959595959595959595959595959
-595959595459595459595959595959595959595959595959595959595959595959595959
-545959545959545959595959595959595959595959595959595959595459595459595459
-595959595959595959595959595959595959595959595954595959595959595959590000
-595959000059590000000059590000000059590000000059590000590000595959595959
-000059595959590000000059590000595959000059590000000059590000595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959545959595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e0e0ed759595959595959595959
-595959591c061c061c061c061c1c30595959595959595900005959595959545959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959000059595900005900005959000059590000595900005959000059000059
-000059595959595900005959595900005959000059000059595900005900005959000059
-000059595959545959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595954595954595959545959545959595459595954595459
-545959595459595459595459595459595954595959595459595959545959595959595959
-59595959595959595959595959595959595959595959ae060e0e0d0000060e0e0eae5959
-5959595959595959595959591c0659595959595959303059595959595959590000595959
-590000590000590000000059595900000000595900000000005959000000005959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595900005959590000590000595900005959000059595959
-595900005900005900005959595959590000595959590000595900005959000059000059
-590000595900005900005959595959595954595954595959545959595459595459595459
-595459545959545959595959595959595959595959595959595959595959595959595959
-595954595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595954595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595954595959595959595959595959595459595959595959595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595906065959595959595930305959595959
-595959000059595959000000000000005959000059000059590000595959590000590000
-595900005959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590000595959000059000000000000
-595900005959590000000000590000590000595959595959000059595959000000000000
-595900005900005959000000000000590000595959595959595959595959595959595959
-595959595959595959595959595959595459595954595959545959595459595954595459
-595459595954595959595959545959595954595959545959595459595954595959545959
-595459595959595959595459545959595959595959595959595959545959595959595954
-595959595959595459595959595959545959595959595954595959595959595459595959
-595959545959595959595954595959595959595954595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959590606595959595959
-593030595959595959595900000000005900000059590000595900005900005959000059
-595900005959000059590000595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959000059595900
-005900005959595959590000595900005959000059000059000059595959595900005959
-595900005959595959595900000059595900005959595959000059595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959545954595959595959595459545959545959595459595959
-595459545959595959545954595959595954595459595959595459545959595959545954
-595959595954595459595959595459545959595959545959545959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954595959595959595959595959595459
-59595959595959595959d7060e0e0d0000060e0e0ed75959595959595959595959595959
-060659595959595959303059595959595959590000595959590000595959000000000000
-590000000000005959590059595900000000000059595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595900005959000059590000595900005959000059000000595900005900005900005959
-595959590000595959590000595900005959590000005959590000595900005900005959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595906065959595959595930305959595959595959000059595959000059
-595900005959595959000059595959595900005959590000595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590000000000595959590000000059595959000059590000005900
-000000590000595959595959000000000000590000000059595959590059595959590000
-000059590000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d0000060e0e
-0ed75959595959595959595959595959061c5959595959595930fa595959595959595900
-005959595900005959590000595900005900005959000059000059595959000059590000
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959545959595959595959595959595959595959595959595959ae06
-0e0e0d0000060e0e0eae59595959595959595959595959591c0659595959595959303059
-595959595959590000595959590000595959590000000059595900000000595900000000
-005959000000005959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954595959
-595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959061c3030
-303030303030305959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959545959595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959545959595959595959ae060e0e0d00001c0e0e5cd75959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595459595959595959595959595959595959cd5959595959cd595959
-595959cd5959595959595959595959595959595954595959595959595959595959595954
-595959595959595959595959595959545959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959ae060e0e0d0000060e0e5cd759595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595954595959cd5959595959cd595959595959
-cd5959595959cd595959595959cd595959cd595959595959545959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595954595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595459595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959590100595959590100010059595901000100
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959595959595959595959595959
-595959595459595959595959595959595959595959595959595959595959595959545959
-595959595959595959545959595959595959ae060e0e0d00001c0e0e0ed7595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959595959595959595959595959545959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590000000159595900005959
-000159000059590001595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595459595959595959595959595959595959
-595959595959595959595959595959595459595959595959595954595959595959595959
-595954595959595959595959595459595959595954595959595959595959595959595900
-005959590000595900005900005959000059595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959ae06
-0e0e0d00001c0e0e59d75959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959545959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590000595959000059590000590000595900005959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959545959595959595959595959595959595959595959595959595959595959
-595959595959ae060e0e0d0000060e0e2eae595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959545959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595954595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959000059595900005959000059000059590000595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e5c0e2259595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595459595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595900005959590000595900005900
-005959000059595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959545959595959595959595959
-59595459595959595959595959595959595959595959ae060e0e0d0000060e0e0eae5959
-5959595959595959595959591c1c1c1c1c1c1c1c1c1c1c59595959595959590000595959
-000059000059595959590000595959595959595959595959590000000000015959595959
-595959595959595959595959595959595959595959595959590100010001000100595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595459595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590000595959
-000059590000590000595900005959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59cd59595959595959595959595959595959595959545959595959595959ae060e0e0d00
-001c0e0e0ed759595959595959595959595959591c1c061c1c1c1c1c061c305959595959
-595959000059595900005959595959595959000059595959595959595959595959000059
-595959595959595959595959595959595959595959595959595959595959595959595959
-000059595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959000059595900005959000059000059590000595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959591c06595959595959
-593030595959595959595900005959590000590000595900005900005959000000005959
-595959595900005959595900005901005901000001595901590100015901000159595959
-5959595959595959000059595959010000015959595959595959cd595959cd5959595959
-595959595959595959595959595959595959595959595959595459595959595959595959
-595959595959595959595959595959595959595954595954595959595959595959595959
-595959595959595959595954595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595900005959595900000000595959000000005959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959ae060e0e0d00001c0e0e0e4f5959595959595959595959595959
-06065959595959595930a959595959595959590000595959000059000059000059000000
-590000595900005959595959590000595959590000000000000059590000590000595900
-005959000159595959595959595959590000595959000059590001595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595459595959595959595959595954
-5959595959545959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-cd5959595959595959595959595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595906065959595959595930305959595959595959000000000000005900
-005900005959000059000059590000595959595959000000000059000000595900005959
-000059000059590000595900005901010000000059595959000059595900005959000059
-59595959595959595959595959595959595959595959cd59595959595959595959595959
-595959595959545954595959595959545954595959545959595954595959595959595959
-595959595959595959545959595959545954595459595459595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd5959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959545959595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959590606595959595959593030595959595959595900
-005959590000590000590000595900005900000000000059595959595900005959595900
-005959590000595900005900005959000059590000595959595959595959595900005959
-590000595900005959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959545954595959595959595959595959595959
-595959595959595959595959545959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959cd59595959cd
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595954595959595959595959595959
-595959595959595959595959595959595959545959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959ae06
-0e0e0d0000060e0e0eae5959595459595959595959595959060659595959595959303054
-595959595959590000595959000059000059000059590000590000595959595959595959
-590000595959590000595959000059590000590000595900005959000059000000000000
-595959590000595959000059590000595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595954595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959cd59595959595959595959
-595959595959595959595959cd5959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959055959
-590559595959595959055959590559595905595959055959595905595959055959595959
-595959595959595959595959595959cd5959595959595959595959595959595959595459
-595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959061c5959
-595959595930305959595959595959000059595900005900005900005900000059000059
-590000595959595959000059595959000059595900005959000059000059590000595900
-005959595959595959595959000059595900005959000059595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959545959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959590606595959595959593030595959595959595900005959590000590000595900
-005900005959000000005959595959595900005959595900005959595900000000595900
-005959000059590000595959595959595959595900005959595900000000595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-a930a93030a93030a93030a930303030a93030a930fa3030fa3030a930a93030a93030a9
-30a93030fa3030fa3030a930a93030a93030a930a930fa30fa30fa30fa30fa30fa30fa30
-fafa3027fa30fa27fafa30273027fafa30fa30fa27fafa30fa30fa3027fafafafafafafa
-fafafafafafafafafafafafafa30273027fafafafafafafafa30273027fafafafafafafa
-fafafafafafa30fa30fa30fa30fa3030303030fa30303030303030303030303030303030
-3030fa3030fa30fafa30fafa595959595959595959595905595959595959590559595959
-595959055959595959595905595959595959590559595959590559595959590559595905
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959061c30303030303030303059595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595930303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-30303030303030303030303030303030303030f159595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959ae060e0e0d00
-00060e0e5cae595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959593030050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05050505050505050505050505050505050505050505050505050505050505051c1c0606
-060606061c0618181c061c061c06061c1c1c1c1c1c1c1c1c2e1c2e1c5959595959595959
-595959595959055959595959595905595959595959590559595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959ae060e0e0d00001c0e0e0ed759595954595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959303005050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050606060606060606060606060606060606060606061c1c1c1c1c1c1c1c301cf1
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-59595959595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959cd595959595959595959595959595930300505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505060659595959595959595959595930065959595959595959
-5959595930301c1c59595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959ae060e0e0d00001c0e0e0ed7595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959cd59595959
-595959593030050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050506065959595959595959595959593006
-59595959595959595959595930301c2e5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959cd595959595959595959595959595959595959595959
-595959595959595959595959303005050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050606595959595959
-595959595959300659595959595959595959595930301c1c595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959ae06
-0e0e0d00001c0e0e0ed75959595959595959595959595959595959595959545959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-595959595959595959595959595959595959595930300505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0606595959595959595959595959300659595959595959595959595930301c2e59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959ae060e0e0d0000060e0e0eae595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959543030050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050506065959595959595959595959593006595959595959595959595959
-30301c1c5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-5959595959595459595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595954595959595959595959595959
-59595959595959595959cd59595959595959595959595959595959595959595959595959
-303005050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050606595959595959595959595959300659595959
-595959595959595930301c2e595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-59595959595959595959595959595959595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595954595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595930300505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505060659595959595959595959
-5959300659595959595959595959595930301c1c59595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959ae060e0e0d00
-001c0e0e59d7595959545959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd59595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595930fa050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050506065959
-59595959595959595959301c59595959595959595959595930301c2e5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-59595959595959595959595959595959595959595959cd59595959595959595959595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959591c1c1c1c1c1c1c1c
-1c1c1c595959595959595900005959590000590000595959595900005959595959595959
-595959595900005959590000595959595959595900005959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959303005050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505051c06595959595959595959595959300659595959595959595959595930301c1c
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595459595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-1c1c061c06060606061ca959595959595959590000595959000059595959595959590000
-595959595959595959595959590000595959000059595959595959590000595959595959
-595959595959595959595959595954595959595959595959595959055959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595930300505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050606595959595959595959595959301c5959595959595959
-5959595930301cf159595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959ae060e0e0d0000060e0e0eae595959595959
-59595959595959591c065959595959595930305959595959595959000059595900005900
-005959000059000059590000000059595959595959000059595900005900005900005959
-000059590000590000590000595959000000005959000059590000595901015901015901
-015959595959595959595959595959595959595959595959595959595959595954595959
-595959593030050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050506065959595959595959595959593006
-59595959595959595959595930301c1c5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959590606595959595959593030595959595959595900
-005959590000590000590000590000005900005959000059595959595900005959590000
-590000005900005900005900005959000000590000590000595900005900005959000059
-590000590001015901015959595959595959595959595959595959595959595959cd5959
-595959595959595959595959303005050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050606303030303030
-303030303030301c30303030303030303030303030301c2e595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959ae06
-0e0e0d0000060e0e0eae59595959595959595959595959591c0659595959595959303059
-595959595959590000000000000059000059000059590000590000595900005959595959
-590000595959000059000059590000590000000059595900005959000059000059590000
-595900005900005900005959000059590000595959595959595959595959595959595959
-595959595959595959595959595959595959595930300505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0630303030303030303030303030303030303030303030303030303030301c1c59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959595959ae060e0e0d00001c0e0e59d75959595459595959595959595959061c5959
-595959595930fa5959595959595959000059595900005900005900005959000059000000
-000000595959595959000059595900005900005959000059000000005959590000595900
-005900005959000059590000590000590000595900005959000159595959595959595959
-59595959595959595959595959595959595959595959595959595959fa301c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c2e1c2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e1c1c1c
-1c1c1c1c1c1c06060606060606060606060606060606061c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1cf15959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959590606595959595959593030595959595959595900005959590000590000590000
-595900005900005959595959595959595900005959590000590000595900005900005900
-005959000059590000590000595900005959000059000059000059590000595900005959
-595959595959595959595959595959595959595959595959595959595959595959595959
-301c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c2e1c1c2e1c1c2e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c0606060606060606060606060606060606060606060606060606
-060606060606060606061c1c595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959061c59595959595959303059595959595959590000595959
-000059000059000059000000590000595900005959595959595900005900005959000059
-590000590000595900005900005959000059000059590000595959000059590000595959
-0000595900015959595959595959595959595959cd595959595959595959595959595959
-545959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959590559595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595906065959595959595930305459595959
-595959000059595900005900005959000059000059590000000059595959595959590000
-000000595900005959000059000059595900000000595900005959000000005959595900
-005959000059595900005959000059595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595905595959595959595959595959590559595959595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595459595959
-5959ae060e0e0d00001c0e0e0ed75959595959595959595959595959061c303030303030
-303030595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595905
-595959055959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd59595959595959595959595959cd5959595959
-59595959595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959055959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959ae060e0e0d00001c0e0e59d7595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59fa30fa30fa30fa3030a930fa30fa30a93030a9595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-5959595959595959593030303030303030303030303030303030301c595959595959ae06
-0e0e0d00001c0e0e0ed75959595459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959593030050505050505053005050505050505061c
-595959595959ae060e0e0d0000060e0e0eae595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595930300505050505051c3005
-0505050505051c06595959595959ae060e0e0d00001c0e2e59d759595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959055959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505051c3030050505050505061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959303005050505051c1c30300505050505050606595959595959ae060e0e0d00
-001c0e0e0ed7595959595959595959595959595959595959595954595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595954595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959055959595959595959595959595905595959595959595959
-59595959595959595959595959303005050505051c1c5930300505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595954595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959595959595459595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959055959595959595959595959595959595959593030050505051c1c59593030050505
-05050606595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-595954595959595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595459595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595930300505050506
-1c5959593030050505050606595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505051c1c595959593030050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595459595959595959595959595959595959595959595459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959593030050505061c59595959593030050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595954595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959303005051c0659595959595930300505050606
-595959595959ae060e0e0d00001c0e0e0ed7595959595959595959595959595959595959
-595959595959595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959545959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595930300505061c5959595959
-595930300505061c595959595959ae060e0e0d0000060e0e59ae59595959595959595959
-595959595959595959595959595959595959595459595959595959595959595959595954
-595959595959595959545959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959040459595959595959595959595904045959595904045959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959045959595959595959595959595959595904
-595959595959595959595959595959595959595959595959595959595959595959545959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959080559595959
-595959595959595959595908045959595959595959595959595959080459595959595959
-595959595959595959595959595959590559595959595959595959595959595959303005
-1c065959595959595959303005050606595959595959ae060e0e0d00001c0e0e0ed75959
-59595959595959595959590303595903030303590303030303590303590303cd03030359
-cd0303595903035903030303035903030359595959545959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959045959595959595959595959595904595959595904595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590459595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959b354085959595959595959595959595959cd
-045959595959595959595959595959595959595959595959595959595959595959595959
-5959595959303005061c5959595959595959593030050606595959595959ae060e0e0d00
-00060e0e0eae5959595954595959595959595959035959035959037f59037f59037f0359
-7f59035959037f5903597f037f03597f59037f59037f5903595959595959595459595459
-595959595954595459595959545959595954595959595954595459545959595959595959
-595959595959595959595959595959595959595959595959595905595959590404cd0459
-590404cd0404595959595959595959040404595904040459595959040459595959590459
-595959590459595959595959595959595959595959595959595959595959595959595959
-545959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590404590459590459040459595959040459595959040404595959040459
-595904045959595959595959595904040404590404590459595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959590804cd08545908540408545959590804cd
-595959080404cd59590404595959080459595959595959595959592d04595959590804cd
-5959590804cd595904590804595959080459595908540408045959595959595959595959
-5959595959595959595959595930301c0630303030303030303030303005060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959590359590359590303
-5903595903035959595903035903595903595903590359035903595903037f0359595459
-595959595959595954595459595959595959595959595459595959595459595959595959
-59545959595959595959595959595959cd59595959595959055959595959595959595959
-5959cd045904590459590459cd04595959595959595904595959597f0459590459590459
-5904595959cd0459595959cd045959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595904cd04590459cd04595904595904595904595904cd
-595959595959045959595959045959595959595959597f0459597f04cd04590459595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595954045904590454590454
-5904595904595408595904cd595959595959045959545905085959595959595959595959
-045959590459540859590459590459590454045959590459cd04592d590459cd59595959
-595959595959595959595905595959595959595959303006303030303030303030303030
-3030061c595959595959ae060e0e0d0000060e0e0eae595959595959595959595959597f
-03595903595903590303595903590359595903590303595903595903590359037f035959
-035903035959595959595959595959595959595959595959545959595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-595959595959595959595904590459045959045959045959595959595959590404595959
-04cd59045959040404595959595904595959595904595959595959595959595959595959
-595959595959595959595954595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959045904590459590459cd045959
-040404cd595959040459595959cd0459595904040459595959595959595959047f595904
-59047f045959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595904
-7f0459045959045959045959040404b35959590404595959595904595959040404595959
-595959595959595904cd5959045959045959045959595959040459595959040404595959
-540459595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed7595959595959
-595959595959595903595903595903595903595903595903595903595903595903595903
-595903590359595903595903595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595904cd045904595904595904595959595959
-5959cd59590459590459590459cd04595904595959590459595959590459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959597f0459045904
-59590459590459cd045959045959595959045959595904595904cd5904595959595959cd
-595959045959040459047f04595959595959595959595959595959595459595959595959
-595959595905595959595959595959595959595959595959595959595959055959595959
-595959595959590459045904595904595904cd59045959045959595959045959cd590459
-590459590459595959595959595959590459595904595904545904595904597f04590459
-59cd04595904595959045959595959595959595959595959595959595959595959595959
-593030060606061c1c061c061c0606060606061c595959595959ae060e0e0d0000060e0e
-0eae595959595959595459595959595959030359590303595903590303037f5903030359
-5903597f5903035959590359035959030359590359595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959045904590404595904
-045959595959595959590404045959040404590404595904045959590404040404590404
-040404595959595959595959595959595959595959595459595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959590459047f0404040404590404595904045959590404047f59590404040404590404
-590459595959595959595959040459045904590404595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959047f04590404040404590404595904045959590404
-045959590404040404590404cd04595959595959595904040404047f5904045959595904
-04595904047f040459595904045959590404040459595959595959595959595959595959
-59595959595959595930301c06060606060606060606060606300606595959595959ae06
-0e0e0d00001c0e0e0ed7595959595959595959595959595959597f59597f5959597f5959
-59595959595959595959595959597f595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd59597f0459595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959545959595959595959595959595959595959595959590559595959595959590559
-5959595959595959595959595959595959595959595959595959597f597f595959595959
-5959cd595959cd59595959595959597f5959595959595959595959595959595959595959
-597f595959597f595959595959595959595959597f595959595959595959595959595959
-595959595959595959595959595959595930300606595959595959595959595930300606
-595959595959ae060e0e0d0000060e0e59ae595959595959595959595959595959595959
-595959595959595959595959597f59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590404595959590404040404045959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959597f595959597f59595959595959
-5959595959595959597f5959595959595959590404040404045959595959595959595959
-595959595954595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590404040404
-0459595959595959595959595959595959595959595959595959595959595959595959cd
-595959595959595959595959595959595959595959595959593030060659595959595959
-5959595930300606595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-597f59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5905595959595959595959595959595959595959595959cd595959597f59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd59595959595959cd5959595959595959595959cd59595959595959597f59595959
-597f59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd5959cd59595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303006
-0659595959595959595959593030061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959597f5959cd5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300606595959595959595959595930300606595959595959ae060e0e0d00
-001c0e0e0ed7595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59cd59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-5959595954595959595959595930300606595959595959595959592d3030060659595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959cd5959595959595959595959595959595959595959
-595959595959595959595959595959595459595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595954595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959545959303006065959595959595959595959
-30300606595959595959ae060e0e0d00001c0e0e59d75959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-595959595959595959595959595959595959595959055959590559595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959055959595959595959595959595959595959593030061c595959
-595959595959592d3030061c595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd595959cd595959cd595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595905595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300606595959595959595959595930300606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595905
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd595959cd595959595959595959595959595959cd5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959592d3030061c595959595959595959592d30300606595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959cd595959595959595959595959
-59595959595959595959595959595959cd5959595959cd59595959595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959cd595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300606595959595959595959595930300606
-595959595959ae060e0e0d00001c0e0e0e4f595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd595959cd595959cd595959cd595959cd595959595959cd595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd595959595959595959595959595959595959595959cd
-59595959cd59595959595959cd5959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959592d3030061c59595959595959
-5959592d3030061c595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-5959595959cd59595959595959595959595959595959595959595959595959595959cd59
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959cd59595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595954595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959055959595959595959595959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303006
-06595959595959595959595930300606595959595959ae060e0e0d00001c0e0e0ed75959
-5959cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959cd59595959cd59595959
-59595959595959595959595959595959595959595959595959595959595959cd59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959592d3030061c595959595959595959592d30300606595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd59595959cd595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959055959
-595959595959595959595959593030060659595959595959595959593030060659595959
-5959ae060e0e0d00001c0e0e0e4f59595959595959595959595959595959595959595959
-59595959595959595959595959595959cd59595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-5959595959595959595959595959cd5959595959595959595959595959cd595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959592d3030061c595959595959595959592d
-3030061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959cd5959595959
-595959595959595959595959cd59595959595959595959595959595959cd595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300606595959
-595959595959595930300606595959595959ae060e0e0d00001c0e0e0ed75959595959cd
-5959595959595959595959595959595959cd5959cd5959cd595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-2d3030061c595959595959595959592d30300606595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959cd595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300606595959595959595959595930300606595959595959ae06
-0e0e0d00001c0e0e0ed75959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959cd59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959595959cd
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595459595959595959592d3030061c595959595959595959592d3030061c
-595959595959ae060e0e0d0000060e0e0eae595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959cd5959595959595959595959595959595959595959595959cd5959595959595959
-5959595959595959595959595959595959595959595959595930300606303030a9303030
-3030303030300606595959595959ae060e0e0d00001c0e0e0ed759595959595959cd5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959595959595959595959cd5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959592d30301c
-30303030303030303030303030300606595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd59595959595959595959595959cd595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c590e0ed7595959595959595959595959595959595959595959595903595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd5904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-5959595959595959595959595959595959cd595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-59035959595959595959595959595959595959cd59595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904cd5959595959595959595959595959595959cd045959
-595959595959595959595959595959045959595959595959595959595959595959595959
-595959045959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5904cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959cd5959595959595959595959
-595959595904595959595959595959595959595959595904595959595959595959595959
-59595959595959595959cd04595959595959595959595959595959595959595959595959
-595959595959595959cd59595959595959595959595959595959595959595959cd045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595905595959595959595959cd595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e59ae595959595959
-595959595959cd5959595959595959595903595959595959595959cd5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959590404045959040404045959040459595959045904040459040404045959
-595959595959590404595904045904045959040404045959590404595959045904040459
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd5959595959595904595959595959595959595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c2e0e
-0ed7595959595959595959595959595959595959595959597f0359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959cd5959595959595904cd5959595959045959cd5959cd0459595959045959
-59cd5904cd5959595959595959590459590459cd0459cd0459595904cd59595904cd5904
-5959cd0459cd595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959055959595959590559595959595959595959595959595959
-5959595959595959cd5959595959595959595959595959cd590459595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-595959595959595959595959595959595959595959595959595959595959595959595459
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959035959
-59cd59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595904045959595904595959590404
-04595959cd045959595959045959595959595959595904cd5904595904595904cd595904
-59595959040404cd59595904595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959590459595959cd595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959055959590559595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e2e59d7595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959cd5959595959595959595959595959
-5959595959595959595959595959595959590559595959595959595959595959cd595959
-595959595959595959595959595959595904595959595959595959595959595959045959
-590459590404595904595959590459595959590459590459595959595959045959045959
-045959045959590459590459045959045959590459595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd04595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd045959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-595959595959595959595959595959595959595959595959543030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-5959595959595959595959595903cd595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595904040459595959590404595904045904595904040404595959590404595959595959
-595959040459595959040459045959590404cd5959040459595904040404595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-5904595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-5959595959595959595959595904595959595959cd595959595959cd5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959cd595959cd595959cd595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59cd595959cd595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959cd5959595959595959595959595959595959595959595959
-5959595959595959cd5959040404040404cd595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959595959595959595959
-5903595959595959595959595959595959595959595959595959595959cd5959cd5959cd
-5959cd5959cd595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959cd5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959cd5959
-595959595959595959cd5959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959c8595959595959595959595959595959595959595959cd59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595904595959595959595959cd59595959
-5959595959595959595959595959595959595959cd595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd0459cd595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e59d7595959595959
-59595959595959595959595959595959590359595959595959595959595959595959cd59
-5959595959595959595959595959595959595959595959595959595959595959595959cd
-595959595905595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd04595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595901015959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595459595959595959595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959cd5959595959595959595959595959
-5904595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590100010159595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959055959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-5959595959595959593030050505050505058d050505050505050606595959595959ae06
-0e0e0d00001c0e0e0e4f59595959595959cd595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-5959cd5959595959595959595900000101010159cd045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959590559595959595959590559
-59595959cd5959595959595959595959cd59595959595959595959595959595959045959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-54595959595959595959595959595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0ec8595959595959595959595959595959595959
-5959595959035959595959595959595959cd595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595901010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101000000000000000001010104595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e0e0e4f59595959595959595959
-59cd5959595959595959595959c859595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-5959595959595959595959595959595959595c5959595959595c59595959595c59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595900000000000059
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959540859595959595959595959595959595959595959595959
-595959595959595959595959595959cd5959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0ed75959
-5959595959595959595959595959595959595959590359595959595959cd595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590000005959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd5959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959055959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595900005959595959595904595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-5959cd595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd595959cd59595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595904cd595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595905595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005ef0505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-595959595959595959c85959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959cd59595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd045959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595959595959595959
-595959595959595959595959595959595954595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e59ae595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd5959595959595959595959595959045959cd595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959cd5959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-59595959595959595959cd5959595959595959595959595959595959595959595959597f
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-5959cd5959cd595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-5959595959595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0ed75959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595905595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505058d05050505050606
-595959595959ae060e0e0d00001c0e0e0ed7595959595959595959595959595959595959
-5959595959c8595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd590459cd59595959
-cd5959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959055959595959595959595959cd59595959595959595959595959595959595959
-59595959590459595959cd5959595959595959595959595959cd59595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595930fa050505050505050505
-0505050505050606595959595959ae060e0e0d0000060e0e59ae59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959597f0459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5904595959595959595959cd595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd59595959590459595959595959595959595959595959595959595959
-59cd59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959545959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959545959595959
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595905
-595959595905595959595959590559595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e59d7595959595959595959cd595959595959595959595959
-59c859595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959597f045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595904cd59
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-cd5959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595905595959595959595959595959590559595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595459595959595959595959595959595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0ed759595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959045959595959590459595959590404595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd0459595959595959595959
-5959595959595959595959595959595959cd595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e0e0e4f5959595959595959595959595959595959595959595959c85959
-595959595959595959595959055959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-5959595959595959595959cd595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595904595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eae595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959055959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959597f04595959595959595959595904590404595959
-590404595904590459040459595959595959040404045959590404595959590404045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-59595959595959595959595959c859595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-59590459cd04595904595904590459045904595959595959595959045959595959590459
-595904595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595905595959595959
-05595959595959595959595905595959595959595959cd59595959595959595959595959
-5959595959595959595959595904595959595959595959cd595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595954595959595959595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0ed75959
-5959595959595959cd595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-5959595959595959595959595959595959595959cd595959595959595959595959045959
-595959595959595959590459590459590404047f59045904590459595959595959595904
-595959595959045959590459590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd595959595959595959595959595959595904cd59595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959593030050505050505c005050505050505050606595959595959ae060e0e0d00
-001c0e0e2e4f5959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595905595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-595959595904595959595959595959595959045959047f59045959045959047f04595959
-595959595959590459590459597f04595959045959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959cd5959595959595959595959595908595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd0459595959595959595959590404045904045959040459
-5959045904595959595959597f59595904047f5904040404047f590404cd045959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959590559595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e590ed75959595959595959595959595959
-5959595959595959590d59cd595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd595959595959595959045959cd5959595959595959597f59
-59595959595959597f59595959595959595959595959597f59595959595959cd59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595954595959595959595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-cd5959595959595959595959597f59595959595959595904040404040459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595904cd5959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595959595905595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595954595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0e4f59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595905595959595905595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-59045959595959595959595959595959595959595959595959597f5959597f597f597f59
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd595959cd595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959cd0459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0ec85959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959cd595959cd595959cd595959cd5959595959595959595959
-5959595959595959595959595959595959595959590459595959cd595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959590459cd
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e0e0e4f595959595959595959595959595959595959
-5959595959c8595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959055959595959595959595959595959cd59595959595959595959595959
-595959595959595959595959595959597f04595959595959590000595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-cd5959595959595959595959595959595959595959595959595959595408595959595959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eef59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959010000005959
-595959597f59595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c2e590e4f5959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595905595959595959595959595959595959595959595959
-59595959595959595959cd59595959595959595959595959595959595959595959045959
-000000000000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-595959595959cd5959595959595959595959595954085959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959545959595959595959545959
-595959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed759595959595959cd59595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595900000000000000000000000000000000000000000000010000010000010000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000100010000010001000100010001000100010000010000010001010000010001010101
-010101010101010101010101010100000004595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959590559595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959595959595959595959
-590d59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595905
-5959595905595959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959590459590000000000595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595905
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595900000000595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595904cd59595959595905595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0e4f595959595959
-5959595959595959595959595959595959c8595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-0559595959590559595959595959595959595959595959595959595959595959595959cd
-595959595959595959595959595959595959595959595959595959595904595959595959
-590000595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959055959595959
-5959595959595959595959595959595959595959595959cd595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595954595959595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904cd595959595959590559595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959055959595905
-595959595959595959055959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c2e590e4f59595959595959595959595959595959595959595959590d5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959cd5959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959592d085959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eae595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959cd5959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595954595959593030050505050505050505
-8d05050505050606595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-59595959595959595959595959c859595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959055959595959
-595959590559595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959cd5959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0ed75959
-595959595959595959595959595959595959595959035959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595904cd59595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd59595959595959595904cd59595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c2e592e4f5959595959cd5959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959597f595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959055959595959595959055959595959595959595959595959
-595959055959595959595959590559595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-595959595959595959c85959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd5959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959545959595959595959592d085959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595954085959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930fa0505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959595959590559595959595959590559595959590559
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595905595959595959595959595959cd59595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed75959595959595959595959595959595959595959595959c859595959595959595959
-595959595959595959595959055959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-595959595959595959595959590459595959595959595959595959595959055959595959
-595959595959595959595905595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595905595959595959595959595959595959595959590559595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-5959595459595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959055959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959597f59595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595904cd59595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-055959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959055959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e0e0e4f595959595959595959595959595959595959
-5959595959c8595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959cd59595959595959cd595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959545954595954595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-59595959595959595959595959595959595959595959595959595959595959cd59595959
-59595959cd04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5905595959595959595959595959595959595959595959595930fa050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959045959595959595959595959595959595959595959595959595959595959595959
-595959590459595959045959595959595959595959595959595959040459595959595959
-59595954595959040459595959595959595959595959595959595959cd59595959595959
-590459595959595959595959595905595959595959055959595959595959595959595959
-595905595959595959595959055959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595905595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595959595959595959595959595959595959595959595959595959590559595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959cd59595959595959597f045959
-595959595959595959595904595959595959595959595959595959595959595959595959
-59595959595959595959595959595959590459595959595959595459595954595459597f
-045954595954595959595959595959590459595959595959595959595959595959595959
-595959595959595954085959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-055959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959590559595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959055959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595905595959595959595905595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5459595959047f5959595959595959595959040404045959045904040404045904045959
-595959595904590459040459045904040459590404595959040404045959590404595959
-595959595959595904595959590404595959590404595959045904045959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959055959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959590559595959595905595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930300505050505050505058d0505050505060659595959
-5959ae060e0e0d00001c2e592e4f59595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959045959595959595959595959597f04597f59597f04597f
-597f04597f0459595959595959045904590459597f0459597f59597f045959597f04597f
-5959047f5904595959595959595959590459595904595904595904595904595904590459
-595959595959595959595959595959595959595959595959590459595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-59595959595959595959cd5959595959595959cd59595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595905
-59595959595959595959595959595959595959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959045959595959595959595959595904
-59595959590459595959045959045959595959597f047f047f0459595904595959595959
-0459595959045959595904040459595959595959595959590459595904597f0459590459
-7f59597f0404595959595959595959595959595959595959595959595959595959045959
-595959595959595959595905595959595959055959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595459595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed7595959595959
-5959595959595959595959595959595959c8595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595905595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959597f04595959595959
-5959595959597f045959045959045959595904597f045959595959595959045904595959
-5904595959595959045959597f0459590459045959045959595959595959595904595959
-045959045959045959045959047f04595959595959595959595959595959595959595959
-595959cd5904595959595959590559595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595905595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959cd5904595959595959055959595959595959595905
-595959595905595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959055959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959590404595904040404595959040459595959595959
-5959047f0459595904040404595904040404045959590404597f59040459595959595959
-595904040404045959040459595959040459590404590404595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595905595959595959595959595905595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595459595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e0e59d75905595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595905595959595959595959595959595959595905595959
-595905595959595959595959cd5959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959597f59597f597f5959595904
-7f5959595959595959595959595959597f597f595959597f597f59595959595959595959
-7f595959595959595959597f597f595959597f5959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959055959
-595959595959595959595959595959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eef595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959595959597f04595959595959595959595959595959595959
-595959595904045959595904040404040459595959595959595959595959595959595959
-595959595959595959595904040404040459595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959055959595959595959595959595959595959595905595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e2e59d759595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-59595959595959595959595959597f5959595959597f59597f5959595959595959595959
-59595959595959595959595959595959595959595959597f595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959590559595959595959595959595959595905595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59cd59595959595959595959590459595959595959590559595959595959055959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959055959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595904cd59595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595904cd59595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e0e0ed75959595959595959595959595959595959595959595959c8595959595959
-595959595959595905595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595905595959595959
-5959595959595959595959cd595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959595959595959595959595959595408595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959055959595959595959
-055959595959595959595905595959595959055959595959595959595959595959595959
-59cd59595959595959595959595959595959595901015959595959595408595959595959
-595959590559595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd0459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd59595959cd595959595959595959590459595959595959595959
-595905595959595959595959595959595905595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959cd59595959595959590000000159595959
-590459595959595959595959595959595959595959595959595959590559595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e0e4f5959595959595959595959595959
-595959595959595959c85959590559595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595905595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd59595959cd595959595959595959045959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959597f5959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959055959595959595959595959595905595959
-595959595959595959590559595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959cd5959595959595959595959595959
-590000000000005959045959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959545959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595959595959595959595903595959595959595959055959595959595905
-595959595959595905595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595900000001000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000100010001000001000100010101000101010001000100
-000000000001010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010100000000000000000000000004595959595959595959595959595959595959
-595959590559595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595905595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959045c59f9595cf95cf95cf95cf95cf95cf95cf9590e0ef9
-5cf95cf95cf95cf959f1590e0ef95cf95cf95cf95cf959f1590e0ef95cf959f1590e0e5c
-f95cf95cf95cf95cf95cf95cf95cf95cf95cf95cf95cf95cf95cf959f959f9595c59f959
-5c595c595959595959595959595959595900000000000059590459595959595959595905
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-59595959595959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959590559595959595959595959590559595959
-595959595959055959595959595905595959595959595959595959595959595959055959
-5959595959595959595959595959595959595959595959cd595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959000000595959595904cd59
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505058d05050505050606
-595959595959ae060e0e0d00001c0e590e4f595959595959595959595959595959595959
-5959595959c8595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595900005959
-595959595908595959595959595959595959595959590559595959595959595959595905
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e2e0eae59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959540459595959595959595959595959055959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0e4f5959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595905595959
-595959595905595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-545959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0eef595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959590559595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595905595959595959595959590559595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0e4f59595959595959595959595959595959595959595959
-590559595959595905595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959055959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-540859595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959035959595959595959595959595959595959590559595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959592d045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0e4f595959595959
-5959595959595959595959595959595959c8595959595959595959595905595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595905595959595959595959595905595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959597f04595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959590559595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595905595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c2e592e4f5959595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-055959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eae595959590559595959595959595959595959
-595959595903595959595959595959595959590559595959595959595959595959595959
-595959590559595959055959595959595959055959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959055959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-595959595959595959595959590559595959595959055959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959055959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-59595905595959595959595959595959595959595459595959595959595959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959597f59595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959597f045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e2e59d75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959590559595959055959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959597f5904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595459595959595959595959595408595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959055959595959
-595959595959595954595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959595959595959590559595959595959595959595959595959595959
-595905595959595905595959595959595959055959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959047f595959595959595959595959595959595959595959
-595959595959595959595959595959045959595959595959595959590404595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595459595459595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-2d0459595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595930300505050505050505058d050505
-05050606595959595959ae060e0e0d00001c592e59d75959595959595959595959595959
-595959595959595959c85959595959590559595959595959595959595959595959595959
-595959590559595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959597f04595959595959595959595959
-7f0459595959595959595959595959595959595959595959595959595959595959545959
-59545959595959595959595959595959595954595959595959595959595959597f045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959590559595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930fa0505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959545959595904595959595959
-595959595959590404590459045904040459040459595904590404595959040404045959
-590404595959590404045959595959595959595959595959595959595959595959595459
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-545959595959595959595959595959595904595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959595959595959595959590559595959595959590559
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-7f0459595954595959595459597f04597f047f597f04597f597f597f0459597f04597f04
-59597f047f59597f04597f04595904597f04595959595959545959595459595954595959
-545959545959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959597f0459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959540859595959595959595959
-595959595905595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959590559595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959590459590459595904595959590404
-0459595904595904595959045959595904040459597f0459590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959592d045959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e0e0e4f595959055959595959595959595959595959
-5959595959c8595959595959595959595905595959595959595959595959595959595959
-595905595959590559595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595905595959cd59595959595959cd5959595959
-595959595959595959595959595959595904595959595959595959595959045959045959
-590459595904597f0459597f04595904595959045959045904597f045959045959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959545959595930fa050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eef59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959040404595904040404595904045904590404047f0404597f590404597f59040459
-595959040459045959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5904cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e59d75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-055959595959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595905595959595959595959055959595959595959595959595959
-595959595959595959595959595959cd5959595959595959595959595959595959045959
-5959595959595959595959597f0459597f597f595959597f595959595959595959595959
-5959595959595959595959597f59cd595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959595959cd
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959055959595905595959595959
-595959595959595905595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0eae595959595959595905595959595959595959595959595903595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959055959595959590559595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959597f04595959595959595959595959040404595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959592d04595959595959
-595959595959590559595959595959595959595959595959595959590559595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904595959595959595959595959597f5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd5959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959590559595959595959
-59595959595959595959595959595959545959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595905595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-5959595959cd595959cd5959595959cd59595959cd595959595959595959cd595959cd59
-5959cd595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed7595959595959
-5959595959595959595959595959595959c8595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959055959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-590000595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904cd595959595959595959595959595959595959595959595959595959cd59
-5959595959595959595959595959595959595959cd5959cd5959cd5959cd5959cd595959
-cd59595959595959595959595959595959595959595959cd595959595959595959595959
-595959595959595959595959595959595408595959595959590559595959595959595959
-055959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959590359595959595959595959
-595959590559595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959000000005959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd59595959595959595959595959595959595959595959cd59
-59595959595959cd595959cd5959595959595959595959592d0459595959595959595959
-595959590559595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505058d05050505050606595959595959ae06
-0e0e0d00001c0e0e0e4f5959595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959055959595959595905595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959597f59045959000000000000595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959cd595959595959cd595959cd5959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959cd59595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595459595959595959595959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eef595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595900000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000001010000000000
-010100000101000000000000010000000100000100000100000000010000010001010101
-010101010101000101010100010101010001000100010101010100010101000101010001
-010100010001000101010101010101010101010101010101010101010100010000010000
-010000000100000100010001000100000001010000000100010000010000000000000000
-000000000004cd5959595959595959590559595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c2e590e4f59595959595959595959
-595959595959595959595959590559595959590559595959595959595959595959055959
-595959595959595905595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd5959595959595959cd59595959595959590459590000000000595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959c85959595959595959595905595959
-590559595959595959595905595959595959595959595959590559595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959045959
-595900000000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e0e0ed75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959590000595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595408595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0ed759595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595905595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c2e592e4f5959595959595905595959595959
-595959595959595959c85959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959055959595959590559595959595959
-055959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959595959595959595959590559595959595959595959
-590559595959595959595959595959595959055959595959595959595959055959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959540859595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-59595959545959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0ed75959595959595959595959595959595959595959595959035959
-595959595905595959595959595959595959595905595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-59cd59595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959592d045959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c2e592e4f595959595959595959595959595959595959
-5959595959c8595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f04595905595959595959595959595959595959595959055959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595905595959
-595959055959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-595959595959595959595959595959055959595959590559595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-545959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-545959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595905595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930300505050505050505058d0505050505060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595905595959595959595959595959
-590559595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959597f590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959035959595959595905595959595959595959595959595959055959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959055959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0e4f595959595959
-5959595959595959595959595959595959c8595959595959595959055959595959595959
-595959595959595905595959590559595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f04595459595959595959595959595959595959595959595959595959595959
-595959595959595954595959595954595459595459545954595459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595408595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959590a0a595959595959595959595959595959595959
-595959595959595959595959595959595959595959590a595959590a5959595959595959
-595959595959595959595959595959595459595959595959595959595959595959595959
-595959595959595959595959590459595954595459545959545954595954595959595459
-545959545959595459595954595959595959595959595959595959595959595959595959
-595954595959595959545959595959595959595959595959595959595959595959595959
-5959595959595959595459595959595959595959595959592d0459595959595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e2e594f5959595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595905595959595959055959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-595959595959595959045959595959595959595959595959590a59595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959590a
-595959595959595959595959595459595959595959545959595959595959595959595959
-59595959595959595959595959595959595959597f045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959545959595959595959595959545959595959595459595959
-59595459595959595959595959595959595959595959595959595959595959597f045959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595954595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e592eef595959595959595959595959595959595959
-595959595903595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595905595959595959595959595959595959595959
-5959595959595959595959597f59595959047f5959595959595959595959590a0a0a5959
-590a0a595959595959595959590a0a595959590a0a59590a0a590a59590a0a590a595959
-590a0a5959590a0a0a0a5959595954595959595959595959595959595959595959595959
-595959595959595959595459595959595959545959545959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959545959545959595959595959595959595959595959
-595959595904595959595959595959595959055959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e2e594f59595959595959595959
-595959595959595959595959590559595959595959595959055959595959595959055959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-59595959595959595959595959595959595959595959597f590459595959595959545959
-59590a59590a59590a59590a59595959545959590a59590a59590a59590a590a590a590a
-590a590a590a595959590a595959590a5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959540859590559595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959590559595959595959
-05595959595959595959595959595959595959595959595959595959595959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eef5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959590a59590a59590a59590a59595959595959590a59595959590a59
-590a590a590a590a590a590a590a595959590a595959590a595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959592d045959595959595959595959595959
-595959595959590559595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e2e59d75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f045954595959595959595959590a59590a59590a59590a5959595959595959
-0a59590a59590a59590a590a590a590a590a590a590a595959590a595959590a59590a59
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904595959595959595959595959590a0a590a59590a0a59
-5959595959595959590a0a595959590a0a59590a590a590a0a0a590a590a0a590a0a0a0a
-0a5959590a0a595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959cd59595959595959595959
-590459595959595959595959595959595959590559595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e2e59d75959595959595959595959595959
-595959595959595959c85959595959595959595959590559595959595905595959595959
-595959595959595959595959055959595959595959055959595959595959595959595959
-055959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595954085959595959595959595959055959595959595959595959590559
-595959595959595959595905595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959545959595930fa0505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e592ed7595959595959
-595959595959595959595959595959595903595959595959595905595959595959595959
-595959595959595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595904595959595959
-59595959595959595959595959595959590a0a0a0a0a0a59595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959592d04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e2e
-59d759595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959c85959
-595959595959595959595959590559595959595905595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959597f045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595930300505050505050505058d05050505050606
-595959595959ae060e0e0d00001c0e2e59d7595959595959595905595959595959595959
-5959595959c8595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959590559595959590559
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595408595959595959590559595959590559595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959545959595930fa050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e592ed759595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-cd5959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd5959cd59595959
-5959595959595959595959592d0459595959595959595959595959595959595959595959
-595959595959590559595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e2e59d75959
-595959595959595959595959595959595959595959c85959595959595959590559595959
-595959595959595959590559595959590559595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959cd5959cd595959cd5959595959595959595959595959cd595959
-59595959595959597f045959595959595959595959595959595959595959595959595959
-5959cd59595959595959595959595959595959595959595959cd59595959595959cd5959
-595959595959cd595959cd59595959595959cd595959595959595959595959cd59595959
-59595959595959595959595959595959595959597f045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595959595959595959595903595959595959
-595959595959595959590559595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959cd595959cd595959595959595959595959595959cd595959cd5959
-5959595959595959595959595959595959047f5959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-cd5959595959595959cd595959595959595959595959cd59595959595959cd5959595959
-5959595959595959595959595959595959cd595959595959595959595904595959595959
-595959595959595959595959595959055959595959595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e2e59d759595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959590559595959595959595959595959055959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-540859590559595959595905595959595959595959595959590559595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959590559595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-59595959595959595959cd59595959595959595959045959595959595459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd595959595959cd595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e2e59d7595959595959
-5959595959595959595959595959595959c8595959595959595959595959595959595959
-595905595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595459595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-595959597f04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595954595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959595959
-595959595959590559595959595959595959595905595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-590459595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959590559595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e2e594f5959595959595959590559595959595959595959595959c85959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959cd5959595959595959595959595959
-595959595959597f59045959595959595959595959595959545959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e592eef595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959545959595959595959
-595959595959595959595959595959595959595959595959595959595959595954595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904cd59595959cd
-595959595959cd595959595959595959595959595959595959595959595959595959cd59
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959592d04595959595959595959055959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c2e590e4f59595959595959595959
-595959595959595959595959590559595959595959595905595959595959595959595959
-595959595959595959595959590559595959595959595959595959055959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959597f0459595959595959595959
-595459595959595459595959595959595959595459595959595459595959595959595959
-545959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959590559
-595959595959055959595959595959595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e2e0eae5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-055959595959590559595959055959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959545959545959545959595959545959595959
-545959545959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959590459595959595959595959595959595959cd595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505058d05050505050606595959595959ae060e0e0d00
-001c0e2e59d75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959590559595959595959595959595959
-59595959595959595959595959595959595959595959cd59595959595959595959595959
-595959597f04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959cd5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd59595959595959595959595408595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-5959595959595959545959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e2ed759595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959cd5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-2d0459595959595959595959055959595905595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e59d75959595959595959595959595959
-595959595959595959c85959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595959595959595959595959595959595959595959
-59595959cd5959595959cd5959595959595959595959cd59595959595959595959595959
-59595959595959597f045959055959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e2ed7595959595959
-595959595959595959595959595959595903595959595959595905595959595959595905
-595959595959595959055959595959595959055959595959590559595959055959595905
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-5959595959cd595959595959595959595959595959595959595959595959595959595959
-59595959590459cd59595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-59d759595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-7f0459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959cd5959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959595959540859595959595959595959
-595959595959590559595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595954595959
-59595959595959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e2ed75959595959595959595959595959595959595959595959035959
-595959595959595959590559595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959590559595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e0e59d7595959595959595959595959595959595959
-5959595959c8595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959595959597f04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd59595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959055959595905595959595959595905595959595959595905
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959040459595959595959595959595959595959595959
-5959595959595959595959595959cd045959595959590459595959590404595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e2e59d75959
-595959595959595959595959595959595959595959c85959595959590559595959595959
-595959595959595959595905595959595959595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959597f045959
-595959595959595959595959595959595959595959595959045959595959595959595959
-595959595959595959595959595959595959595959595904595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959595959595959595954085959595959595959595959595959
-595959595959595905595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959590559595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595904595959595959595959595959045904040459590404595959595904595959
-59040459595904045959595959040404cd59590404595959595959595959040404045959
-59040459595959040404cd59595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959592d04595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e2e59d759595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959055959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-5959595959595959595959597f04595959595959595959595959590459cd59590459cd04
-5959597f0459595904595904595959cd04595959047f595959cd04595904595959595959
-5959cd045959595959cd045959cd04595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-7f0459595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eef5959595959055959595959595959
-595959595959595959c85959595959595959590559595959595959595959595959595959
-595905595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959047f59595959595959595959595904
-595959590404045959595959045959cd0404047f59590404045959595904045959590404
-045959cd5959595959595904595959595959045959590459590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-59cd595959595959595959595959595959cd595959cd5959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959055959595959595959595959595959595905
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e2e594f595959595959
-5959590559595959595959595959595959c8595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959590559595959055959595959
-595959595959595905595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959590459595959045959045959595904595959045959045904597f04595959
-595959045959047f59045959595959595959590459590459595904595959045959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd04595959595959595959cd5959cd5959cd59595959595959595959595959cd
-5959cd595959cd595959595959cd595959cd5959595959595959595959595959cd595959
-5959595959595959595959595959595959595959cd595959595959595959595959595959
-595959595959595959595959595959595408595959595959595959595959595959590559
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595459595959595904040404595959040459595904040404045959040459
-5959040459047f5904040459595959040459595959595959595959590404cd5904040404
-04595904045904cd59595959cd5959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd5959595959cd59
-59595959595959cd5959cd5959595959595959cd5959595959cd59595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959055959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505058d05050505050606595959595959ae06
-0e0e0d00001c0e2e59d75959595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595959595959595959595959595959595905
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959cd5959
-595959595959595959045959595959595959cd595959597f595959595959cd5959595959
-7f5959595959597f59595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959cd59595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd595959595959595959595959595959595959cd59595959595959595959cd045959
-595959595959595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-59595959545959595959595959595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e592ed7595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904cd5959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595904
-0404040404595959595959595959595959cd595959595959595959595959595959595959
-cd5959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-595959595959595959595959590559595959595959590559595959595959590559595959
-590559595959595959595959595959595959055959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-5959cd5959595959595959595959cd595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd595959595959cd595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959595959cd
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959540859590559595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595905595959595959595959595959595959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0ed75959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595905595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-59595959595959595959595959597f595959595959595959595959595959595959595959
-59595959595959595959cd59595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e0e0ed75959595959595959595959595959595959595959595959c8595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959045959595959595959595959595959595959595959597f5959595959595959
-5959597f5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd595959595959595959595959595959595900005959595959595904595959595959
-595959595959590559595959595959590559595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595954595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0ed759595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-5959595959597f59595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd59595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959590000000059595959
-590459595959595959595905595959595959595905595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-595959595959595959c85959595959595959595959595959595959595905595959595959
-595959595959595959595959595905595959595905595959595959595959595959055959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959cd59595959595959590459595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590000000000005954085959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930fa0505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595959595905595959
-595959595959055959595959055959595959590559595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959cd59595901000001000001
-000000010100000000000000000000000000000000000000000000000000000000000000
-000100010101010101010101010101010101010101010101010101010001010101010101
-010101010101010101010101010101010101010101010101010101010001010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010100010001000100
-000100000000000000000000000000000004595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c2e59
-0ed759595959595959595959595959595959595959595959590559595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595900000000000059590459595959595959595959
-595959595959595959595959595959055959595959595959590559595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-5959595959595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959000000595959595904cd59
-595959595959595959590559595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e2e59d7595959595959595959055959595959595959
-5959595959c8595959595959595905595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595900005959
-59595959b308595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959545959595930fa050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0ed759595959595959595959
-595959595959595959595959590359595959595959595959595959595905595959590559
-595959595905595959595959595959595959590559595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959592d0459595959595959595959595959595959055959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595459595959595959
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595905595959595959595959595959595959595959595959595905595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959cd5959595959595959595959595959
-5959597f5904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930300505050505050505058d0505050505060659595959
-5959ae060e0e0d00001c0e2e59d759595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959590559595959595959590559595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-540859595959595959595959055959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959545959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959592d045959595959595959595959595959595959055959595959595959
-595905595959595959595959055959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e2e59d7595959595959
-5959595959595959595959595959595959c8595959595959595959595959055959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959597f04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595905595959595959595959595905595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e2e594f5959595959595959595959595959595959595959595959c85959
-595959055959595959595959595905595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-055959595959595959595959595959595959595905595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eef595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595905595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959597f04595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959592d04595959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e2e594f59595959595959595959
-595959595959595959595959590559595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959cd5959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959055959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eef5959
-595959595959595959595959595959595959595959035959595959595959595959055959
-595959595959595959595959590559595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959597f59045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-590559595959595959595959595959595959595959055959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e0e0e4f5959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595954595459545959595459595459545959545959545959595959
-545959545959545954595459595954595954595459545954595459545954595954595959
-595959595959595959595959595959597f04595459595954595959545959595459595954
-595959545959595459545954595459595459595459595954595459595459545959595459
-595954595959595954595954595459595459595954595959595459595959595959595959
-595959595959595959595959595959595959595959595959595959595408595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eef59595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595905595959595959595959595959
-055959595959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959590404595959595959
-595959040459595959595959595959045959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959045959595959590459595959595459595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959545959595954595959595959595959595959595959595959595959595959595959
-2d0459595959595959595959055959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e594f5959595959595959595959595959
-595959595959595959c85959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd5959595959595959045959595959595959595959595959
-7f045959595959595959597f045959595959595959595904595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595904595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959055959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e2eef595959595905
-595959595959595959595959595959595903595959595959595959595959055959595959
-595959595959595959595905595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959597f04595959595959
-595959595959590404045959590404595959595904595959590404595959040404045959
-590404595959595959595959040404045959045904040459040459595904590404595959
-5904040459590404595959595904045959590404040459595904045959595904047f5904
-7f0404595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959545959
-595954595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505058d05050505050606595959595959ae060e0e0d00001c0e0e
-594f59595959595959595905595959595959595959595959590559595959595959595959
-595959595905595959595959590559595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959590559595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595904597f04595904597f04595959590459595904597f04
-59597f045959595904595904595959595959595959045959595959045959595959590459
-59590459590459590459595959595959045959590459590459597f047f595959597f0459
-595904595904595904597f04590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959545959595959595959595959540859595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-59595959545959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e2eef5959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959055959
-595959595905595959595959590559595959055959595959590559595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-5959595959595959590459595959595959595959595904595904597f040404595959597f
-04595959040404595959590459595959040404595959595959595959590459595959cd04
-595959590404045959590459590459595904045959590404045959590459595959595904
-5959595959590459595904597f045959045959047f045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595954595959595959595959595959595959592d045959
-595959595959595959595959595959595959055959595959595959595959055959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e2e594f595959595959595959595959595959595959
-5959595959c8595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959045959045959
-04595904595959590459595904597f0459597f0459590459047f59045959595959595959
-590459590459590459595904597f0459595904595904595959597f045904595904595959
-045959045959590459590459595904595959045959045959045959045904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f04595905595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e592eef59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-5959595959595959595959595959595959595959595959597f0459595959595959595959
-597f59040459047f59040459595904040404047f5904045959595959040459595904047f
-5959595959595959cd590404595904040404595904045904590404047f04045904040459
-7f5904045904597f59040459595959590404595904040404045959040459590404045904
-040459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959055959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e2e59d75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595959595959595959590559595959055959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-5959595959595959595959597f59595959597f59595959597f5959595959595959595959
-597f59595959595959595959595959595959595959595959597f595959595959597f5959
-595959597f5959595959597f5959595959597f595959595959cd59597f597f597f595959
-7f595959597f59597f045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959595959
-595959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959055959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904040404040459595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959592d04595959595959
-595959055959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959595959595959595959
-590559595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959055959595905595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959597f59595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595459595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595905595959595959
-595959595959055959595959595959590559595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959590559595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed7595959595959
-5959595959595959595959595959595959c8595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-cd5959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595900005959
-595959597f04595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959cd595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959055959595959
-595959595959595959595959595959595959595905595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0ed759595959595959595959595959595959595959595959590359595959595959595959
-595959595905595959595959590559595959595959595959595959590559595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590000000059595959590459cd5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959cd595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595904cd595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e0e0ed75959595959595959595905595959595959595959595959c85959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959590559595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959590459cd595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959597f5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590000000000005959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd595959cd59595959
-59cd59595959595959595959595959595959595959595959595959595959595959085959
-595959055959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-59595959595959595959595959595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0ed7595959595959595959595959595959595959
-595959595903595959595959595959595905595959595959595959595959595959595959
-595959055959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595900000100000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000004595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd595959595959cd59595959595959595959595959595959595959595959
-595959cd5904595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e2e59d759595959595959595959
-595959595959595959595959590559595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd59595959595959595959cd595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595900000000000059
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959590459595959595959590559595959055959595959595959
-595959595959055959595959595959595905595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959545959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959590559595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590000005959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-5959595959595959cd59595959595959595959595904cd59595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959545959595959
-595959595930300505050505050505058d05050505050606595959595959ae060e0e0d00
-001c0e2e59d75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959590559595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595900005959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959592d08595959595959
-595959595959595959595959595959590559595959595959590559595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e592ed759595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595905595959595959595959
-590559595959055959595905595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959047f595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-540459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e2e59d75959595959595959595959595959
-595959595959595959c85959595959595905595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-5959cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959055959595959595959595959
-595959595959595905595959590559595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595930fa0505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd59595959595959595904595959595959595959055959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-055959595959595959055959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959cd5959cd5959595959595959595959
-595959595959cd59595959595959595959cd595959cd5959595959595959595959595959
-5959cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959540859595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595954595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0ed75959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959597f0459595959595959595959595959cd
-595959cd5959cd5959cd59595959595959cd5959cd59595959595959595959595959cd59
-595959cd5959cd595959595959cd59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e2e59d7595959595959595959595959595959595959
-5959595959c8595959595959595959055959595959595959595959595959055959595959
-595959595905595959590559595959595959595959595959595959595959595959595959
-595959595959595959055959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959590559595959595959595905
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595930fa050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0ed759595959595959595959
-595959595959595959595959590359595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959590559595959595959595959
-595959595959595959595959055959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959cd5959595959595959595959055959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959055959595959055959595959595959595959595959595959595959595959
-595959595959595959595959cd5959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959597f045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959055959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595905595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-597f59595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959592d04595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0e4f59595959595959595959595959595959595959595959
-59c859595959595959595959595959595959595959590559595959595959595959595959
-055959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-595959cd5959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959597f59595959595959597f0459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595959595959595959595959595959595959595959
-590459595959590559595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959545959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eef5959595959595959595959595959
-595959595959595959035959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959595959cd5959595959595959595959
-595959595959595959045959595959595959595959590559595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e2e594f595959595959
-5959595959595959595959595959595959c8595959595959595959595905595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595408595959595959595959595959595959595959
-595959595959595959595959595959590559595959055959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959590559
-595959595959595959595959595959595959055959595959595959595959595959590559
-595959595959595905595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959590a0a595959595959
-5959595959595959595959595959590a5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904cd595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959592d0459595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505058d05050505050606595959595959ae06
-0e0e0d00001c0e0e0e4f5959595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-59595959595959597f045959595959595959595959595959595959595959595959595959
-590a5959595959595959595959595959595959595959590a595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595459595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959590559595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959590559
-595959595959595959595959545959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0ed7595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959545959595904595959595959595959595959590a0a59590a
-590a0a595959590a0a0a5959595959595959590a0a59590a0a590a0a59590a0a0a0a5959
-590a0a5959590a590a0a0a59595959595959595959595959595959595959595959595959
-5959595959595959595959595459595959595959cd595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e2e59d759595959595959595959
-595959595959595959595959590559595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959597f0459595959545959595459
-59590a59590a59590a59590a59590a59590a59595959595959590a59590a59590a59590a
-5959590a595959590a59590a5959590a5959595959595459595954595959595459595959
-545959595959595959595959545959595459595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd595959
-5959cd595959595959595959540859595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e2ed75959
-595959595959055959595959595959595959595959035959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959590559595959595959595905595959595959595959595959
-595959cd5959595959595959595959595959595959595959595959595959595959045959
-595959595959595959590a0a0a5959590a59590a59590a59590a59595959595959590a59
-590a59590a59590a5959590a595959590a0a0a595959590a595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595904595959cd59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959592d045959595959595959595959595959
-595959595959595959595959595959055959595905595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e2e59d75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959055959595959590559595959055959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f045959595959595959595959590a59590a59590a59590a59590a59590a5959
-5459595959590a59590a59590a59590a5959590a59590a590a59590a5959590a59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959cd5959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd595959cd59595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5459595959595959595959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e592ed759595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-5959595959595959595959595904595959595959595959595959590a0a59590a0a0a590a
-0a59590a0a590a59595959595959590a0a595959590a0a590a5959590a0a5959590a0a59
-59590a0a0a0a595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e2e59d75959595959595959595959595959
-595959595959595959055959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959595959595959595959595959595959595959595959595959
-595959595959595954085959595959595959595959595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959545959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595905595959595959
-595959595959055959595959595959595959055959595959595959595959590559595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd595959595959595904595959595959
-59595959595959595959595959595959595959595959590a0a0a0a0a0a59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959592d04595959595959595905595959595959595959
-595959595959595959595959595959590559595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e2e
-59d75959595959595959595959595959595959595959595959c859595959595959595959
-595959595959595959595959595959595905595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959cd5959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959cd59595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-590559595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0ed75959595959595959595959595959595959595959595959035959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595904cd59
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e2e59d7595959595959595959595959595959595959
-5959595959c8595959595959595959595959595959595959055959595959595959595959
-055959595959595959595959595959595959595959590559595959595959595959595959
-59595959595959595959595959595959590559595959595959595959595959cd59595959
-cd5959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959cd5959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd5959595959cd59595959595959595959595959595959cd5959595959
-59595959b308595959595959595959595959595959595959595959590559595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eef59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959cd5959595959
-5904cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595459592d0459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505058d05050505050606595959595959ae060e0e0d00001c0e2e594f5959
-595959595959590559595959595959595959595959055959595959595959590559595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959cd595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959055959595959
-595959cd5959cd595959cd59595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959cd59595959
-595959595959595959595959595959595959595959045959595959595959595959055959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-545959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0eef595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959cd595959cd5959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959cd5959cd595959cd59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e2e594f59595959595959595959595959595959595959595959
-59c859595959595959595959595959595959595959055959595905595959595959595959
-595959595905595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595905595959595959595959595959595959595959
-59595959cd59595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-54595959595959595959595959595959cd59595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd0459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd595959595959595959595959595959
-540859590559595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eef5959595959595959595959595959
-595959595959595959035959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd045959595959595459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-5959cd595959cd5959595959595959595959595959595959595959595959595959045959
-cd5959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959592d045959595959595959595959595959055959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e2e59d7595959595959
-5959595959595959595959595959595959c8595959595905595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959055959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959590559595959545959595959595959595959
-5930301c1c1c1c1c1c1c1c1c1c061c060606061c595959595959ae060e0e0d0000060e59
-2ed759595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959cd5959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959593030051c1c1c1c1c0606060606060606300606595959595959ae06
-0e0e0d00001c0e2e59d75959595959595959595959595959595959595959595959055959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959055959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd59595959597f045959595959595959545959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959cd5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-595959595959055959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959593030051c065959595959595959593030050606
-595959595959ae060e0e0d0000060e0e0ed7595959595959595959595959595959595959
-5959595959c8595959595959595959595905595959595959595959055959595959595959
-055959595959595959595959595959595959595959595959595959055959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595459
-595959595959595959595959595959595959595959595959595959595959595459595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959592d04595959595959595959595959595905595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959593030050506065959595959
-5959593030050606595959595959ae060e0e0d00001c0e2e59d759595959595959595959
-59595959595959595959595959c859595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959597f0459595959595959595954
-595954595959595959545959595959595959595959595959595459595954595954595954
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05061c5959595959595930300505061c595959595959ae060e0e0d0000060e0e0eef5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595459595954595959545959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595905595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050606595959595959303005050606595959595959ae060e0e0d00
-001c0e2e594f5959595959595959590559595959595959595959595959c8595959595959
-055959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595905595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-595959597f04595959595959595959595959595459595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959cd59595959cd595959595959595959595408595959595959
-595905595959595959595905595959595959595959595959595959595959055959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959593030050505060659595959593030050505060659595959
-5959ae060e0e0d0000060e0e0eef59595959595959595959595959595959595959595959
-590359595959595959595959595905595959590559595959595959595959595905595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959cd5959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd59595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-2d0459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959593030050505051c0659595959303005
-05050606595959595959ae060e0e0d00001c0e2e594f5959595959595959595959595959
-595959595959595959c85959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959597f045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959055959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595459595959595959595959595930300505050506
-06595959303005050505061c595959595959ae060e0e0d0000060e0e0eef595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595905595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959cd5959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595905595959595959055959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505060659593030050505050606595959595959ae060e0e0d00001c0e0e
-0e4f59595959595959595959595959595959595959595959590559595959595959595959
-595959595959595905595959595905595959595959595959595959595959595959595959
-595959595959055959595959055959595959595959595959595959595959590559595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-7f0459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595459595959595959595959595959595959
-cd59595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd0459595959595959590559595959595959595959595959
-595959055959590559595959595959595905595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959540859595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959593030050505050506065430300505050505061c595959595959ae06
-0e0e0d0000060e0e0ed75959595959595959595959595959595959595959595959035959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959590559
-595959595959595959595959595959595959590559595959595959595959595959590559
-595905595959055959590559595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959592d045959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959545930300505050505050630303005050505050606
-595959595959ae060e0e0d00001c0e0e0ed7595959595959595959595959595959595959
-5959595959c8595959595959595959595905595959595959595959595959595959590559
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959597f04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595408595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959cd5959595959595959595959cd595959595959
-595959595904595959595959595959595959595959595959595959055959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959545959595959593030050505050505063030
-0505050505050606595959595959ae060e0e0d0000060e0e0ed759595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959590559595959055959595959595959595959595959595959
-595959055959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904cd595959595959595905595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959303005
-05050505050530300505050505050606595959595959ae060e0e0d00001c0e2e59d75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd59595959595959595959597f045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959303005050505050505308d050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959595905595959595959595959595959595959590559595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959545959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959055959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930301c1c061c06060606061c0606060606060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959597f0459595959595959595959595959595959595959595959
-595959595959595959595959595959595959545959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959300606060606060606060606060606
-0606061c595959595959ae060e0e0d0000060e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-5959595959595959595959595959595959595959590459cd595959595959595959595959
-595959595959595959595959595959595959595959595959545959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959055959595959595959595959595959
-595959595959590559595959055959595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959ae060e0e0d00001c0e0e0e4f595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595905595959595959590559595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595459
-595959595954595959545959595959595959595959595954595959545959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959cd5959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d0000060e0e
-0eef5959595959593efafa27fafa30fa3030fa3030fa3027fafa273e27273e2727272727
-27273e2727273e2727273e2727273e2727273e2727273e2727272727273e272727272727
-273e2727273e2727273e27272727272727273e2727273e27273e27273e273e273e3e273e
-273e27272727fa27fafa27fa27fa2730fafa30fa3027fa30fa30fa30fa3027fa302730a9
-30a93030a9303030fa3030fa303030303030fa30fa30fa30fa30fa3030fa303030fa3030
-3030fa303030fa3030fa3030fa30fa30fa30fa30fa30fa30fa30fafa30fafa30fa30fafa
-30fafa30fa30fafa30fafa30fa3027fa3027fa3027fa27fa27fa27fafa27fafa27fa273e
-273e27273e27fa27fa27273027fa27fa273e273e273e273e273e273e273e273e273e273e
-27273e273e273e273e273e273e273e273e273e27273e27273e27273e273e273e273e273e
-2727273e273e27273e2727273e27273e27273e27273e273efa27fafa27fafa27fafa27fa
-27fa2730fa30fa30fa30fa30fa30fa30fa30a93030a9a9faa927fa27272727273e272727
-3e2727273e272727272727273e2727273e2727273e2727273e2727273e27273e27273e27
-273e273e273e273e273e2727273e27272727fa27fa27fa2727fa27fafa30fa30fa3030fa
-30303030303030595959595959595959595959595959595959595959595959595959ae06
-0e0e0d00001c0e2e594f59595959595930303030303030303030303030303030302727fa
-272727273e2727fa27272727fa272727fa272727fa272727fa272727fa27273e2727fa27
-2727273e2727fa27272727fa272727fa272727fa273e2727fa272727fa2727fa2727fa27
-27272727272727272730fa30fa3030273030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-302730303030303030303030303030303030303030303030302730273027302730272730
-27273027273027fa273027273027302730273027302730273027fa273027302727302730
-273027302727302730fa273027fa273030fa2730fa2730273030fa273030303027303030
-303030303030303030303030303030303030303030303030303030303030303030272727
-fa27fa272727fa272727fa2727273e2727fa27272727fa272727fa272727fa272727fa27
-27fa2727fa2727fa27272727272727272727fa3027fa2730fa3030303030303030303030
-30303030303030303030303030301c595959595959595959595959595959595959595959
-595959595959ae060e0e0d0000060e0e0eef595959595959273005050505050505050505
-050505052e052e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e1c2e2e2e1c2e1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c2e1c1c1c1c1c1c2e1c2e1c2e1c1c2e1c2e1c1c2e1c1c2e1c2e1c2e1c2e1c2e1c2e
-1c2e1c2e2e1c2e2e2e2e2e2e2e2e2e2e2e2e2e1c2e1c1c1c1c1c1c1c2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e1c2e2e2e1c2e2e1c2e2e2e2e2e0505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505052e1c050505050505050505050505051c1c59595959595959595959595959
-5959595959595959595959595959ae060e0e0d00001c0e0e0e4f59595959595930300505
-050505050505050505051c2e30051c1c1c1c2e1c1c2e1c1c1c2e1c1c1c2e1c1c1c2e1c1c
-1c2e1c1c1c2e1c1c1c1c1c1c2e1c1c1c2e1c1c1c2e1c1c1c2e1c1c1c2e1c1c1c1c2e1c1c
-1c1c1c1c1c1c2e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c06061c0606060606061c1c1c1c1c061c1c1c1c
-1c1c1c1c1c06060606061c0606061c061c061c1c061c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c30050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05050505050505050505050505051c1c1c2e0505050505050505050505061c5959595959
-59595959595959595959595959595959595959595959ae060e0e0d000002ec0fec0f5959
-595959593030050505050505050505052e1c1c3030051c1c595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959303005050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505051c1c1c1c1c1c0505050505050505
-051c06595959595959595959595959595959595959595959595959595959643725db0000
-014f4f4f4fec595959595959303005050505050505051c1c1c1c593030051c1c59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595c5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595930300505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050505050505050505050505050505050505051c1c59591c1c
-1c1c05050505050505061c59595959595959595959595959595959595959595959595959
-5959258b4e122500004f13133e0f59595959595930300505050505052e1c1c1c59595930
-30051c1c5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959593030050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05051c06595959591c1c1c1c050505050506065959595959595959595959595959595959
-59595959595959595959438b1212db00004f3e1313ec5959595959593030050505051c1c
-1c1c59595959593030051c1c595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-303005050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505051c1c5959595959591c1c1c1c050505061c595959595959595959
-595959595959595959595959595959595959dbbb7e124300004f133e130f595959595959
-303005052e2e1c1c595959595959593030051c0659595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595930300505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050505050505051c0659595959595959591c061c0605060659
-5959595959595959595959595959595959545959595959595959438b7e7e2500007a1313
-3eec5959595959593030303030305959595959595959593030051c1c5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959593030050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050505050505050505050505050505061c5959595959595959
-5930303030061c595959595959595959595959595459595959595959595959595959258b
-12124300004f3e731364595959595959303005053030303059595959595959303005061c
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959303005050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505051c06
-595959595959595930303030050606595959595959545959595959595959595959595959
-595959595959db8b127e2500007a13133eec595959595959303005050505303030305959
-5959593030051c1c59595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595930fa0505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505061c595959595959303030300505051c1c59595959595959595959595959
-5954595959595959595959595959438b12124300004f7395130f59595959595930300505
-0505050530303030595959303005061c5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959593030050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05050505050505050505050505051c065959595930303030050505050506065959595959
-59595959595959595959595959595959595959595959dbbb127e2500004f133e13ec5959
-595959593030050505050505050530303030593030051c1c595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595930fa05050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05050505050505050505050505050505050505050505061c595930303030050505050505
-05061c595959595959595959595959595959595959595959595959595959438b12124300
-008b73957364595959595959303005050505050505050505303030303005061c59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595930300505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050505050505050505050505050505050505051c0630303030
-0505050505050505051c0659595959595959595959595959595959595459595959595959
-595943bb127e2500004f13133eec59595959595930300505050505050505050505053030
-30051c1c3030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-3030303030303030303030303030303030303030303030303030303030fa050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505061c30300505050505050505050505061c5959595959595959595959595959595959
-59595959595959595959db8b12124300008b217313645959595959593030050505050505
-050505050505050530050630303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303005050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05050505050505050505063005050505050505050505050505061c595959595959595959
-59595959595959595959595959595959595943bb127e2500007a73133eec595959595959
-30301c1c1c1c1c1c1c1c1c1c1c06060606061c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-1c2e2e2e2e2e2e2e2e2e2e2e2e2e2e0e2ef10ef10ef10ef10ef10ef10ef10ef10ef10ef1
-0ef10ef10ef10ef10ef10ef10ef10ef10ef10ef10ef10ef12e0e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e1c1c1c1c1c1c1c060606061c1c061c061c061c061c060606061c59
-5959595959595959595959595959595959595959595959595959db8b1212430000a32173
-1364595959595959301c1c1c1c0606060606060606060606060606061c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c061c061c061c0606061c0606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-06060606060606060606061c061c061c061c061c1c061c06061c06061c06061c061c061c
-061c061c1c061c061c061c1c061c1c061c1c061c061c1c061c1c061c1c061c061c06061c
-1c061c061c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c061c1c061c1c1c1c061c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c061c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c061c061c1c1c06
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c2e1c2e1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e1c2e2e2e1c2e2e1c2e1c2e2e2e2e2e2e
-2e2e2e2e2e1c2e2e1c2e1c1c1c1c1c1c1c1c1c1c1c060606060606060606060606060606
-0606060606060659595959595959595959595959595959595459595959595959595943bb
-217e2500009673133eec5959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959db8b1212430000bb21730273ecec64ecec64bf8f0fbf8f368f368f36aeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae22aed7d7aed7d7d7d7d7d7d7d713ec
-6464646464f864646425256443648b7e127e25001d007a1313733e4f504f4f4f7a4f347a
-4f7a4f4f4fc306060606060606060606061c061c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c061c06061c060606060606060606060606060606060606061c06061c06
-061c06061c06061c060606060606061c0606060606060606060606060606060606060606
-06060606060606060606060606060606060606060606060606061c0606061c06061c0606
-06061c0606060606061c060606061c06060606060606060606060606061c060606060606
-0606060606060606060606060606060606061c0606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-0606060606060606060606060606060606060606060606060606061c061c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c061c0606060606060606060606060606060606061c06061c1c1c1c1c1c1c
-1c1c1c1c1c1c7a7a7a7a7a7a7a7a8b5a8b8b8b38bbbb1212124300061d008b7373021313
-73130295027302212121212173860e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e5c0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e5c0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e4f02137302022121123712121212127e12b512db0006
-898700256473730273737321217e121212122121138f0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0ef10ea37321b51212127e1212127e1212
-21121243db000606f81d890000646425252564d3432543434343434343640d0d0d0d0d0d
-0d050d050d05050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050d050d050d
-050d0d0d0d0d0d0d0d050d050d050d0d050d050d050d050d050d050d050d050d050d0d0d
-050d050d050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d
-0d0d0d0d0d0d0d0d0d0d0d050d050d050d050d050d050d050d050d050d0d050d050d050d
-050d050d0d0d0d0d0d0d0d0d0d0d050d050d050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d
-0d0d0d050d050d050d0d0d0d0d0d0d050d050d050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d
-0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d
-0d0d0d0d0d0d0d0d0d0d0d050d050d050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050505050505050505050505050505050505050d050d0d0d0d
-0d0d0d0d0d0d0d0d0d0d050d050d050d0505050505050505050505050d051343432543db
-43db43db43dbdbdb43dbdb00000000061d891d1d1d000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000060600
-%%PageTrailer
-%%Trailer
-%%EOF
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_collector.gif b/lib/et/doc/src/sim_trans_contents_viewer_collector.gif
deleted file mode 100644
index 77115b71ab..0000000000
--- a/lib/et/doc/src/sim_trans_contents_viewer_collector.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_collector.png b/lib/et/doc/src/sim_trans_contents_viewer_collector.png
new file mode 100644
index 0000000000..545697bf38
--- /dev/null
+++ b/lib/et/doc/src/sim_trans_contents_viewer_collector.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_collector.ps b/lib/et/doc/src/sim_trans_contents_viewer_collector.ps
deleted file mode 100644
index 3ef1921fa2..0000000000
--- a/lib/et/doc/src/sim_trans_contents_viewer_collector.ps
+++ /dev/null
@@ -1,1407 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/sim_trans_contents_viewer_collector.ps
-%%CreationDate: Mon Oct 14 17:27:25 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 406 232
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 217.359744 translate
-391.247539 -217.359744 scale
-% Image geometry
-468 260 8
-% Transformation matrix
-[ 468 0 0 260 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 468 string def
-/gstr 468 string def
-/bstr 468 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 82198 ASCII Bytes
-colorimage
-r;V<JJH16$[f?Ok0f^sKJ,~>
-r;V<JJH16$[fH=oJ,~>
-r;V<JJH16$[fH>IJ,~>
-rr;uunc&S<J[C!8K<tV-mJd0^mJd0^nc/Uhs#C'6J,~>
-rr;uunc&SGMnXbRJ\(Zg!&X*C!28f[!28r_rrE$dJ,~>
-rr;uunc&SuJaS*WKC/_KmJd0^mJd0^nc/Uhrc<S~>
-s8N-#s8W)KqVM,3!%EJWXc%a_f7O,Rs3:GkqVM/4!i5k@qpkQ"r8n'Vs3:GkqVDD<s8N'Z3Ih~>
-s8N-#s8W)LrS%8-ro3q>!&U.0JWYMGlB)-)s3CVlrmq&%rndY6s5jBVs3CVlrmq&%rndY6s5jBV
-s3CVlrmq&%rn[h<s8N'e7">~>
-s8N-#s8W)KqVM,3!+LN9J_l%9!b22SqpkQ"r8n'Vs3:GkqVM/4!i5k@qpkQ""m5jb!-<43~>
-!ri9#rRLc$qW7c,JTJAC!.4]d!.4]d!.4]d!.4]d!/(8l!/(8l!/(8l!/(8l!/(8l!/pht!/pht
-IuAYpF,PBdF,PBdF,PBdF,PBdF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#m
-F-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#m
-F-M#mF-M#mEsn4ZF*!RmF*!Re.KB:qqVM,3!Mobmeb\/"joM:XqpkQ"rT41+!&9!~>
-"9/B$df.hrgA]t.ir/!>1kC(kI/nitI/nitI/nitI/o!#I/o!#I/o!#I/o-'I=I*)I=7*+I=7*+
-I=7*+I=76/I=76/I=76/I=7B3I=7B3I=7B3I=7B3I=7N7I=7N7I=7N7I=7N7I=7N7I=7N7I=7N7
-I=7Z;I=7Z;I=7Z;I=7Z;I=7Z;I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=3?2
-KmeB?KmeB?KmeB?KmeB?KmeB?KmeB?KmeB?KmeB?I5M!'df.hrgA]t.ir8'@U&Y,?rmq&%rndY6
-roO6Ts8LIGf)=>%hYuL:k0<rpJ,~>
-!ri9#rRLc$qW7ceJ^(aM!7h(n!7h(n!7h(n!7h(n!7h(n!7h(n!7h(n!7h(n!7h(n!7h(ns4..o
-s4..os4..os4..oJ)8`#c/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!q
-c/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!q
-c/.!qc/.!qc/.!qc/.!qc/-]Ss81@ChYZF9V#U>BqVM,3!Mobmeb\/$joWd-F+=~>
-!ri9#rmgl%qrRtJjsbjrr+Z:SK6,%I!-A-S!-A-S!-A-S!-A-S!.4][!.4][!.4][!.4][ItMfW
-C4gSBC4gSBC4gSBC5[.JC5[.JC5[.JC5[.JC5[.JC5[.JC6WdSC6WdSC6WdSC6WdSC6WdSC6WdS
-C6WdSC6WdSC6WdSC6WdSC6WdSC7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[
-C7K?[C)iabC208[C208[C208[C208[C208[C208[C+92\eb\/"joXtHs8:FDhYZF:m\Km\eb\/#
-joWd-0n9~>
-!ri9#rmq&%rndY6roO:IjtqX7r-8?lNIf5t!.Fil!.Fil!.Fil!.k,p!.k,pIt`;rH%gZlH&6rp
-H&6rpH&[5tH&[5tH'*N#H'*N#H'Nf'H'Nf'H'Nf'H's5/H's5/H's5/H's5/H's5/H's5/H(BM3
-H(BM3H(BM3H(BM3H(BM3H(BM3H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7GqPeA
-H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7Gr5QLdf.hrgA]t.ir8'ClCn7+
-df.hrgA]t.ir8'ClCn7+df.hrgA]t.irA-Bc2^7_~>
-!ri9#rmgl%qrRtJk$in\r5JZ[`l.r&rl"l^rl"l^rl"l^rl"l^rl"l^rl"l^rl+o^s2G#_s2G#_
-s2BK<c,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZP
-c,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZP
-c,IZPc,IZPc,IX9e]l(Pe]l(Pe]l(Pe]l(Pe]l'Bs8:FDhYZF:m\Km\eb\/"joXtHs8:FDhYcL;
-blDg8~>
-!<E0!eb\/"k5XiMjsd0Bs5)RH%#`)>PlLd.hVN!^pA`c["nqt2CA.]*C&i>SC&i>SC&i>SC&i>S
-C&iV[C&iV[C4CSOC;luiC2/BBC2/BBC2/ZJC2/ZJC2/ZJC2/uSC2/uSC2/uSC2/uSC2/uSC2/uS
-C2/uSC2/uSC208[C208[C208[C208[C208[C208[C208[C208[C208[C20PkC20PkC20PkC20Pk
-C20PkC20PkC20PkC20PkC2,&jHYR;kHYR;kHYR;kHYR;kHYR;kHYR;kHYR;kHYR;kHYR:Es8CLE
-hYZI8mK'-`rRLX.roX7K!MoboeH4Sn62f[?62fpIm_&UN~>
-!<E0!f)=>%hYuO6k5X]IjtrrXs5)RS%$ehTSbiB7hVNBtpA3Ea"nqe8FnY\0FT?^dFT?jhFT?jh
-FansfF`i7\F`iC`F`iC`FiLG,F`i[hF`i[hF`iglF`igpF`istF`j+#F`j+#F`j+#F`j+#F`j7'
-F`j7'F`j7'F`j7'F`j7'F`jC+F`jC+F`jC/F`jC/F`jC/F`jO3F`jO3F`jO3F`jO3F`jO3F`jO3
-F`jO3F`jO3F`fI9JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ)l
-qU5AorS%8-ro3q>s69ZZqU5AoqEY$JroX7G!hoJ=rmh2*5X='&hZ#tDir8'AlFHtG~>
-!<E0!eb\/"k5XiMk$k4,s7Y9f%+Xdbec5[;p@cJEs8U`js8W,<s8W#9!6tM^!6tM^!6tM^!6tM^
-!6tM^s3:S_s36&4mbZ4-`QcZH`RW5P`RW5P`RW5P`RW5P`RW5P`RW5P`RW5P`RW5P`RW5P`RW5P
-`RW5P`RW5P`RW5P`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY
-`SSkY`SSkY`SSkY`SSkY`SSl>`?F*_`Pp]Y`Pp]Y`Pp]Y`Pp]Y`Pp]Y`Pp]Y`Pp]Y`Pl<drRLc$
-qr[qH!Moboeb;B/k5XiMV#UDD!o?4/rSIQ?rT41L]`<Q~>
-!s&AOec+G*63#g?k5RaHmK)H!oO7iRPi6'PK9Yk7!J?X%@KP*)3T"9XKE%0%k5S=Fc-87Xp@^4M
-K9Y/#s7QRM@eTLMraGkBraGkBraGkBraPnls'btLraL@uC1:Y!C1:YRs*J4%C1:Y)C1:Y)C1:Y)
-C1:Y1C1:Y1C1:Y1C1:Y1C1:Y:C1:Y:C1:Y:C1:Y:C1:Y:F(/UCF(/UCF(/UCF(/UKF(/UKF(/UK
-F(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/T)S9&.KS9&.KS9&.KS9&.K
-S9&.KS9&.KS9&.KS9&.KS9&.KS9+[=!@e'Jeb\/"k5OcLV#UGE!8dH9s5s=K!MobpeH"J)63#g?
-63$*ImK(!$J,~>
-!s&APf)FD'5l]^?iWA717/lHPi\^:E!KEZ/D#oWen8/2cSa(%ng<rOLD%VX$R8E&G=\-id88\(o
-4Dg(Kghm)b"?^Ppp,r=k!-/!T!-S9X!-S9XJ!HRAD1-D@D1-D@D1Q\DD6EniD1utHD2ECPD2ECP
-D2i[TD38sXD38sXD3]B`D3]B`D3]B`D4,ZdD4,ZdD4,ZdD4,ZdD4,ZdD4PrhD4PrhD4PrhD4Prh
-D4PrhD4u5lD4u5lD4u5lD4u5lD5DMpD5DMpD5DMpD5DMpD(VT0D/H+pD/H+pD/H+pD/H+pD/H+p
-D/H+pD/H+pD/H+pD/H+pD/H+pD/H+prbVZmqYo(EgA]t.ir8*>l2dUTrmh)'q`t*Js5s=G!MTAh
-ec=G&5l]^>7/uELl2eHrJ,~>
-!s&AOec+G*63#g?k5RaHmK)HZoXt:Me`"1Bc.2<s!R90[]`RWaKAX?Sc2Z%QpA^%tk2q<0s8R/R
-c.1U_s8N4C^&S+RqRlmJrk/<Nrk8?^s1JEOrk/<Nrk/<Nrk3g<s2D[r`P&t0`P&t0`P&t0`P&t0
-`P&t0`P&t0`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8
-`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&r*e]#58e]#58e]#58
-e]#58e]#58e]#58e]#58e]%O$!Fl*.eb\/"k5OcLV#UGE!8dH9s5s=K!MobpeH"J)63#g?63$*I
-mK(!$J,~>
-!W`8NrndT>rT=,Gs%<=Z!Tkj'=p"Et9&a"UpA[bT=p"Et9'TU[3T"!Qk05VQp@^4=;E6a@p@^4E
-pA[b@>6":!0j=;E1&G,S@fBO2@fBO6CA.["CAqCdC1:@MF(/<VF(3DV@U`MEHX^/^HX^/^HX^/^
-K48"fK48"fMeZF!MeZF!MeZF!MeZF!MeZF!MeZF!MeZF!P\OB*P\OB*P\OB*P\OB*P\OB*P\OB*
-P\OB*P\OB*S8)52S8)52S8)52S8)52S8)52S8)52S8)52S8)52/Y$QZ>+B>2>+B>2>+B>2>+B>2
->+B>2>+B>2>+B>2>+B>2>+B>2>+AbFs4,ZrhYZI6mKKEde^`O5pH\fArU'ibs4,ZVhY0;9k5OcL
-]`<Q~>
-!W`8Orn@<9ro*q?rBpbQmc$(qB`e#)=lO,spA.q^B`e#)=mB]%84;?L''@V)=n_\S@:_ttC%h6_
-C%hC+h.co_#<Z_op,m&'D>n5LD>n7!EG]E(FnYZ7H#780H#780I;N\4JT9,tEH,],KlLg@M/d6D
-M/d6DNHJrLO`bAPO`bAPQ$$eTQ$$eTQ$$eTQ$$eTR<<4XR<`L\R<`L\R<`L\SU"p`SU"p`SU"p`
-SU"p`SU"p`Tm:?dTm:?dTm:?dTm:?dTm:?dTm:?d3MC_4Bq]fdBq]fdBq]fdBq]fdBq]fdBq]fd
-Bq]fdBq]fdBq]fdBq]fdBq]fdBq]fdBq]5tqUX6rgA]t.ir8*>l3?[MqUX6OgAF566icBKl3?[M
-qUX6OgAF566icBKl2eHrJ,~>
-!W`8NrndT>rT=,Gs%<=Z!Tmk`[/^.+UuJc]rrAkb[/^.+V!>>eKAX$Kp?$Fds8R/A["F"<s8R/I
-s8SnN[/^./F0tuIF8N<E^&GA=^&GAA^&S,.^&GD=^&PJ>^&PHh`P(F%[(WiR`P&Xc`P&Xc`P&Xc
-`P&Xcc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKk
-e\/>se\/>se\/>se\/>se\/>se\/>se\/>se\/>se\/>se\/>se\/>se\/>s-.T]9[+2js[+2js
-[+2js[+2js[+2js[+2js[+2js[+2Nms4,ZrhYZI6mKKEde^`O5pH\fArU'ibs4,ZVhY0;9k5OcL
-]`<Q~>
-!<E/uhY]\>k5RaH9)n;[jsg1*#'8Z$mZ^VVrr2t>qGI]kk5YJLC/USis6cEV;ZGSWKC8c0;RHH'
-s)SY+s6c+L;Vp8_mf/eT[/U(0F*ldDs6bgA;CBH`K2PUKmS`cY;GqSms6c+LV#PL6`W(9_`P#/j
-hZ*#.;GuB.XPWnR"G?_q3Q;!t#\s)5;H!5^0spr[s)SV*s6c+L;Vp93hGX(Iqbdflk5YJLC/USi
-s6cEV;ZHG(0iI`=0iE)Ls6cCT;OlnLs6as8rr7FoSF6FFS5O**hVPX%;N(Qi;GqR>;GqR>;GqjN
-;GqjN;GqjN;Gr-V;Gr-V;Gr-V;GrE^;GrE^;GrE^;GrE^;GrE^;GrEf;GrEf;GrEf;Gr`o;Gr`o
-;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Go66C/RroC/RroC/RroC/RroC/Rro
-C/RroC/RroC/RroC/RroC/RroC/RroC/QMSeb\/"k5=WKV"W@<hY0>6mK03Xec"A#5lg'GmK(!$
-J,~>
-!<E/ugAXA;6il<0r'^SQ!TGs5AHmkFqX1%g^Ae-4L&,[email protected],h"d/6LTk1t;
-s8Rc^hYQZ6AS'l\Om`(>A\S0Ds+LU4qZ#uKqIM&"s-7/,[dI`#qIO5lhYQZ6A[;>iA]k%,A^8/(
-L#2[oTk.fpijRkFAH\:uI7VZ_rs3oDqIO73p,p(gs8Rc]hYQZ6AS'l\[c1llqYOh3Woj0Xl?Qs@
-lMp.Lral-''0Kk"p,loChYQZ:AS%n(qZ#i3^Ae.]M5ok@m]'iDD;sQhk%0hXH"CQ<EFi^8EFi^<
-EFi^<EFi^@F_,-HF_,-HF_,-LF_,-LF_,-LF_,-LF_,-PF_,-PH"CQTH"CQTH"CQTH"CQXH"CQX
-H"CQXH"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CPATm:3\Tm:3\Tm:3\Tm:3\Tm:3\
-Tm:3\Tm:3\Tm:3\Tm:3\Tm:3\Tm:3\Tm:3+p=B2rrndY6roX4Fs6]r^p=B5srBU6Jrp'OO!ho>=
-rS%69r'UPIrosRQ\c@6~>
-!<E/uhY]\>k5RaH9)n;[k$n4p#0$$1p=6P,rr2u;qQpX\pAb0d]sQ>`s7Y"B[/]h'c1_1f[,1f^
-s2>H8s7Y!M[.a4<pA`[MhZ!QT`<>W/s7X_6ZmY#9c*Xk7p9al"['[g?s7Y!MhZ(R%k5WE-k2s%i
-mf3"2[']Q#hY-oT"O6tBKBE15#eg9<[']l5F5Hors2>E7s7Y!M[.a4Mp9al"qm6a]pAb0d]sQ>`
-s7Y"B[/^.>F0tuIF0rpSs7Y!M[+4mMs7XFgrr7Gleb9%:e[3$'p@dYB[*AWH['[fc['[fc['[fc
-['[fc['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\As['\As
-['\As['\As['\As['\As['\B&['\B&['\B&['\B&['\B&['VR<`O*#&`O*#&`O*#&`O*#&`O*#&
-`O*#&`O*#&`O*#&`O*#&`O*#&`O*#&`O'+Jeb\/"k5=WKV"W@<hY0>6mK03Xec"A#5lg'GmK(!$
-J,~>
-!<E/thYKP;9)e5ZhC8A#$tAquC;p3V@eTh"3D03I25L9/HYSd2SH$Q3^&O<p;YL.I[/]P[@eTh"
-9(q[f`W'+>pAa!Vs6`0^pA\#Nk5TL+F';35;CIJ']h22jUbVT:0k0kEC;p3VHiK!rmf/2;p3TF*
-mV9`@>#P(ohP;n*;BrRK5tYV[s&(TFp+]J=p+^%Ms&)J_mV9`@>#P(ohP;mgjtZg4I\d##HYSd2
-SH$Q3^&O<p;YKf=;YKf=@eT5)`W',;s5&*;PX/LHs&,*]`EKtTS6Ahas5'P+HiL0>F';I>F(/$F
-HX]lNHX]lNHX]lNK47_VK47_VK47_VMdfR^MdfR^MdfR^MeZ-fMeZ-fMeZ-fMeZ-fMeZ-fP\O)o
-=d3Z!;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo
-;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;CV>9hYZI4mK'[email protected]!)!1W!MoGdhYTS=
-k5=WJ]`<Q~>
-!<E0!gAg"05kmbHmK)0$r*9_Fp?le7s(Q?DqHZ?dr*;1_s5JTPPuXOXb%\`mSR#Ops5LKel:c'g
-qHZqkmVTi@BjLH4ijSmP9PsM">sRQPH!tu0;#=NHOoN-l?0\FTp@^U_p?le7s(R2eO]CiLO]Ct'
-=n_9#_Z+=UpAa!L5lP%6])PT'EVB675kan6?2!tSD>*g3;"j<o_Z+=UpAa!L5j%&grEXlTs5JTP
-PuXOXb%\`mSR#Opp,lXSp,[email protected][5XC%hC/RK(QH_Z-<@?2"<TW^)F@Y#'CX?!Vkm
-?!W"q?!W/$?!W/$?!W;(?!WG,?!WG,?!WG0?!WS4?!WS4?!WS4?!WS4?!W_8?!W_8?!W_8?!W_8
-?!UU$EEuk<F^8:@F^8:@F^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:D
-F^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^890pAN_EhYuO6k5OZFmK'$TrRq<<hVS7kroO8M
-lK\B:!MT5cgAg"05l="Mk5OZGmK'm!J,~>
-!<E/thYKP;9)e5ZhI?Da%(-'.Ut,L@[/^/aH_gS@2:_`pXIQYUc2ZXbec3UiXT/=gec5'%[/^/a
-KE(Y@ec2GHs8VN;s6c,Ys8S"(pA^qHUm.DHX=2'feXW`7c$TKjF0tu@Ut,L@`W*<@pA_Lqs/_Ib
-p8$7=UoaUrm`g+XX<ZU%K:K=Ks,1sus)Y:As)YRIs,2O0p8$7=UoaUrm`g+PmW8?.Ib"JdXIQYU
-c2ZXbec3UiXT/<AXT/<A[/]iqec2Gqs6ctY[#;$cs,48ak*4Erc*XSPs6e-Y`W*oI]sOlB]sOlB
-]sOlB`O)_J`O)_J`O)_J`O)_J`O)_J`O)_J`O)_J`O)_Jc*XRRc*XRRc+U3[c+U3[c+U3[c+U3[
-=j=X]XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[
-XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XCCo"hYZI4mK'[email protected]!)!1W!MoGdhYTS=
-k5=WJ]`<Q~>
-!<E/uhZ)a:62aFUmf2t]hC8@p$^C[e3K*oi62(",62O80mf-0>5s[Nns%5:Ts5l=6pA[E5p@^45
-p@^5*s.hZ5s+<W2s$8C5p+]25p+\kqs/]]/62F2$pA[F"s&(lNp+_g3UcFA5K1c0W;ZH0u>5pmQ
-s.hZ5s+<W2s$8A"r^nE[s"Qf3p@^4,p@^45p@^45p@^5*s.hZ5s+<W2s$8A"8hi(!8q6:/;DCI'
-3Tg?63ElIF3D0#=0hV050pM^63K*oimf-0>5s[Lsp@^6's%5:Ts5l=6pA[E58lG].8lA8RC0F5%
-F';1.F';1.HWj$6HWj$6HWj$6K3Cl>K47GFK47GFK47GFK47GFK47GFK47GFMdf:NMdf:NMdf:N
-Mdl]Y;2\mU8rI.N8rI.N8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW
-8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEfa8c^C7r8.>5qsOLX!MoGfh>fk=k5XiL9)e8Yp&Uu_
-r8%G9r':<Tr9aX[]`<Q~>
-!W`8Srnd\7qEtNYmdBZ:hDG.5$_@<t8<s43<VH,K<VooVmf-QX9MeFFs&DHus5m!XpA[fOp@^UO
-p@^V:s/JVTs+sbLs%G]Op,lLOp,l@;s/p?A:f[Bq-scE?:jr@P8G;a>Sc>]\Q2c\Ds2&@DlFq-8
-8=BLX8<s43<VH8[5Y1lW,L6<O<E]%h4B;+K4B_CO4B_CO4IQ5L8<s43<VH8[5Y,$C5lFi8mf-QX
-9MeFFs&DHus5m!Xp@^UOp@^V>s/Jb\s,$1D>sMCd9NCf[4QcZD6tQD\9Nh)c83g0hs2J&M=]p#]
-=]p/a=]p;i=]p;i=]pGm=]pSu=]pSu=]p`$=]p`$=]p`$=]p`$=]pl(=]pl(=]pl,=]pl,=]q#0
-=]q#0s&i3aEEQG0EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4
-EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EW0)C2"oYWrndY6roX4FrpKgW#,1bEg>:[Oro3q>
-s69SPrpKgW"/5GBgA]q/iql.DlMg2Qo""gO~>
-!<E/uhZ)a:62aFUmf2t]hI?DY$dJ^jK>mklSH&V1SGT*>pA^%tPa%+"s+>s*s6bf@s8R^us8RGA
-s8R/Zs2BW0s/_ajs+>[us*LRAs)X_(s2D(0PaqTGs8OC'^&O=Ts8R/bs2BW0s/_ajeXZ[5c)gql
-`W*o0`W*$0s8RFmMuKLsk5TLuV#UI9SH&V1V#UI9V#UI9`W*o0`W*$0s8RFmMkk]HrM4r:s,25g
-P`,88K7g9*mYdn@s)Y"9s)ZHb`Il/0XS2[PH^p=YV#UI9pA]btXT.^HV#UIAH^(W3eVgN)UpR5!
-UqNk*UqNk*UqNk*UqNk*UqO.2UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:
-UrB_@Uf#+<Unku:Unku:Unl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8B
-Unl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BrhKR(pAEeEk54THp&Uu_rS@N?qr[qH!)!7Ys7QJh
-pAEbIk57LF9)S)Yp:UHV~>
-!<E0!hYlU:62aFUmf)n\hC8@p!3H+u"IqdOp+cD9s8N*S62jLVrt7%P9)noG9(qs59(qs59(qs5
-XSi)3S3clB0hV050hV050hPoos8UVjq+;"$s+@]80gYO,0s(<Q$_0N5p5@2/k*4^WXSi)$S3clB
-1&OWX`W%Yb9(qs59(qs59(qs59(qs5XSi)$S3clB1&+B@rrFi?r_!4j%P^7As8OfGp@^45p@^5B
-r;Qkhs8OhP8q1%<p+cUI0gT:Ks"S!Vp+^#S9)ljj8kNi%8kO/.8kO/.8kO/.8kOG68kOG68kO_F
-8kO_F8kO_F8kO_F8kO_F8kO_F8kO_F8kP"N8kP"N8kP"N8kP"N8kP"N8kP"N8kP"N8kP=W8kP=W
-8kP=W8kP=W8kP=W8kP=W8kLn(@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W
-@S07W@S07W8h'K4h>jAL62jIXV!d[Mp&Uu_rS@N?r9""H!_VnKrq6AgpANhJk57OE9)e8Yp&Vi,
-J,~>
-!<E0!hYuL7k57UK8FGpFnc@H$r)j$&r;Qnj9_S0BqH<ju!C0Za=VU`44B5Pas$0`\p,l@Kp,lLO
-p,oMUrtCqsp@^UKp@^UOp@^UOEQ8%Yg3rd"$GQOs]&#PLp@^VOr;R.q9\T&sf"U:7i]OCArrnre
-p@^UKrE0i[s$0^ip@^UOp@^UOp@^UOp@^VOr;Qqk9_S0B<V]etrrGAbr`Kg/s#a:as8P>ep@^UO
-p@^VOr;V8;s8P>i?!1<Ap@^WFs#a:us8P?(p@^Uc@9roQ86K)@AQ`/aAQ`/aBj"SiBj"SmBj"Sq
-D-:"uD-:#$D-:#$D-:#$D-:#$D-:#(D-:#(D-:#(EEQG,EEQG0EEQG0EEQG0EEQG0EEQG4EEQG4
-EEQG4EEQG4F]hk8F]hj0R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8
-R<;Y8R<;Y8R<;Y8R9;B;gA]q/SbYYTV=*dNncGNUgA]q17,m5*k5OWI8FGpFncGNUgA]q/iqZ"A
-mf2hY\c@6~>
-!<E0!hYlU:62aFUmf)n\hI?DY!7h#I"ML'"s)\%4s8N+@SGo>art9CCV#UIAV#UI9V#UI9V#UI9
-eboF\]p/QsF/8j9F/8j9F/61ns8VN#q4nASs/b)FF.E:1F4L3g$b_emp9`u,m_/%0eboFM]p/Qs
-F8VgJk5TLuV#UI9V#UI9V#UI9V#UI9eboFM]p/QsF82R2rrI22rhTSo%We/9s8RGAs8R/9s8R/j
-r;Ql4s8R0=UjoKGs)\5?F.BW;s*M-Qs)YQKV#SttUnkB!Unk]*Unk]*Unk]*Unk]*Unk]*Unku:
-Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unl8BUnl8B
-Unl8BUnl8BUnl8BUnl8BUnffk[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB
-[%sMB[%sMBUgj&rh>jAL62jIXV!d[Mp&Uu_rS@N?r9""H!_VnKrq6AgpANhJk57OE9)e8Yp&Vi,
-J,~>
-!s&AXhYZI69)n>Xp&X#!r(7$Ts.oTJ"$-)K1&=KDmf-Jh8f$Rh8kNRmjtTL%p+]25p+]25p+_g3
-V#<"]3VN/$9(qs59(qs58kMBAV#TjKqFV0;s4-h$0hV050pM^6r@n^@XT..QPlK:00pM^6r@nC7
-p@^6=8cc$nr_!4a%l$]Mp+]25p+]25p+_g3V#<"M3VN/$pdtVUs'#@n''B3d8n.h_0hV050hV05
-0pM^6r@nB9s'#CoIp,bDp+b_08m6!0jtTd-p+]H;@fN5a8nqO%8on0.8on0.8on0.8pa`68pa`6
-8qUSF8qUSF8qUSF8qUSF8qUSF8qUSF8qUSF8rI.N8rI.N8rI.N8rI.N8rI.N8rI.N8rI.N8sEdW
-8sEdW8sF'_8sF'_8sF'_8sF'_8i2cI8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_
-8kP=_8kP=_8kP=_8h'K5h>l^962X=Tmeuh[V"XfE!Tl]Hk5F]K9()ZO!MoGgh>l^962X=Tmf)n\
-]`<Q~>
-!s&AXhYuO6k5IaM8FGpFncJO=2#L>TRK'Gg49J.Jp,r1O!p]esrDaWqs&E'5s5lFDp@^UKp@^UK
-p@^V:s/u;_'1hij4B;+K4B;+K4B5BX=f)/`;#40#IK.adPsA@Cp,ncCY5LHk8?W!HV3V)7Y!AET
-Y5LHb8G;a>r)Ed's8H$up('8cp@^UKp@^UKp@^V:s/u;_"%`.Z4SVnXlMkGo<>+Ho<E3c5jucZ;
-p,l@Kp,ncCY5LJ4lMkEu<E3I1p@^W6s&EcQs5lFLp@^UW<GDK55ZMr8<E4<U<E4HY<E4HY<E4Ta
-<E4`e<E4li<E4li<E4li<E4li<E5#q<E5#q<E5#q<E5#q<E5/u<E5/u<E5/u<E5/u<E5<$<E5<$
-<E5<(<E5H,<E5H,<E5H,<E5H,s&D%HEE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,
-EE-#,EE-#,EE-#,EE-#,EE+jdrn[Y7q*b6R!:KjW!qr>Yrn[_97,n4.rosRQ8FHKJ!qr>Yrn[Y7
-q*b6R!:KjW!P/8]~>
-!s&AXhYZI69)n>Xp&X#Zr1!i-s2FqX",$XRF8DC.pA^BUS/1huK:K%CmW4ous)X_1s)X_1s)Z0Z
-`VjikKE(smSH&V1SH&V1S=Gh.`W,XrqO@u$s5s$gH^t-9F2e0urGrC"ec4dN[/]:5Hc?$(rGr'n
-s8R0<S/0ZTK:JJ3s)X_1s)X_1s)X_1s)Z0Z`Vji[KE(smpm_EZs-3JP'))?XS?2bYF.E:1F.E:1
-F2e0urGr&6s-3MQJ#&V7s)[o6K<2H[mW53(s)Y!+XT-7dS?/NVS@#)^S@#)^S@#)^S@#)^S@u"o
-S@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oSAhS"SAhS"SAhS"SAhS"SAhS"
-SAhS"SAhS"SAhS"SAhS"SAhS"S2A3dS=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"
-S=IR"S=IR"S=IR"S7;3kh>l^962X=Tmeuh[V"XfE!Tl]Hk5F]K9()ZO!MoGgh>l^962X=Tmf)n\
-]`<Q~>
-!W`8Wqr[qHs%<=Zr:U0J.JudG;XXRTH^'.Tk5T0oqar`9s5o5dP[^0_]kYOdM_Ritp+]25p+]2%
-s(Z$2s."G#K1bk20hV050hUU.C/V-cC4lQC1&4Eemf3;Q3D0#=0iIH>S9pKQ8pgU<@UfB;C,o2[
-s."G#K1bk21&OWfF8pSQ9(qs59(qs59(qs59'6.g@da8dH^'.Tp@^459'5:68q*<1k)4SN@\!J3
-C;p420hV050hV050iIH>S:d&YSH%`0H^nhCk5T1ls1NKms,/U(p@^458u2Jr3GM_i8nqO%8on0.
-8on0.8pa`68pa`68qUSF8qUSF8qUSF8qUSF8qUSF8qUSF8qUSF8rI.N8rI.N8rI.N8rI.N8mR?a
-8kP"N8kP"N8kP=W8kP=W8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_
-8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kLQ+hVRDWrB^<Qr:U>jp>4Zgk!B"/r9aPWr:U;ip>4Zg
-k5@UGmeocVp&Vi,J,~>
-!W`8Wro3q>s69\S8FGpFo)JCag,/_-$XrK"SV<>c<Ta=(@Ja%^U&X8;JXL5Cs2&p$s-5]Hp@^UK
-p@^[email protected]&/N7p,l@Kp,l@;s)hbUM04[ThE:U6,jPF09Lr1Wp,ldOqON>*M,f90s)E&Y
-s*7"@meWK.Q&/N7p,r7Q,(9KB:f[5_4B;+K4B;+K4B:PDF`$RCSV<>c<VH,K<E82Dr)J3>s5oGp
-R;&5l_KF$$Prr(?p,l@Kp,lpSqONV6M4st3Ob'3C<Ta=(Y5c@eb5[_l<VH,K<E5mqD+&MT<E4<U
-<E4<U<E4HY<E4Ta<E4`e<E4li<E4li<E4li<E4li<E5#q<E5#q<E5#q<E5#q<E5/u<E5/u<E5/u
-<E3=eD,jT$D,jT$EE-#(EE-#(EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,
-EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-!qo%r6_iqc(B8H/2[p'.5]hVR8O7/l?JlMp8P
-8H/2[p'%/\hVR8OrC$\N!(?fWrpg-a\c@6~>
-!W`8Wqr[qHs%<=Zr:U0J@f2`(V"Xi-]u@[TpA^YYqj]Ogs6dS-`N7&YeZ@p5[!S>Cs)X_1s)X_(
-s.$1as2D[j]q#-&F.E:1F.Dt(S>=]KXM+YrHhj0WpAb/FMk'hIF/8O0`P'7(SA"t&S>?2bUk>K:
-s2D[j]q#-&F8VOP[/ZqdSH&V1SH&V1SH&V1SG)uQXS2\5]u@[Ts8R/1SF6+KS:8`_m_-!HXMt4i
-XQKPiH^t-9F.E:1F/8O0`P'7(c2[4F[*>\BpA^Z-s4+L=s0R-Cs8R/1SB_(uK<1l=S@#)^S@#)^
-S@#)^S@#)^S@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS6a+8
-S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"
-S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=F'^hVRDWrB^<Qr:U>jp>4Zgk!B"/r9aPWr:U;ip>4Zg
-k5@UGmeocVp&Vi,J,~>
-!<E/sk54TDp&X#!qaq3)^%VKoMa<9ps(_C&1lL5js5mcVPii#.PVG0jp@^45p@^45Mt[0c>.sY0
-mYaC)p+]25p+]0tpA\mPpAaj*;DIu>,cq$b0gSG*p+]0K^%VKoMa:8@s#ECFs#EA;@_ML8mYaC)
-p+cG:s4&5X9(qs59(qs59(qs58rNECC0J=Es6be2p@^459(qs5r(;ErhZ*W<@R67@s5oP#3D0#=
-0hV050hPogpAaQ=8rMR+s5mcVPkP,lPii#.S2!#rp@^45C>RJq>#IsbC0F5%F';1.F';1.HWj$6
-HWj$6HX]T>K47GFK47GFK47GFK47GFK47GFK47GFK47GFMdf:NMdf:NMdf:NMdl]Y;2\mU8rI.N
-8rI.N8sEdW8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_
-8sF'_8sF'_8sF'_8sF)i8cgI0hYuX=Ud7<D8cYsjp&_&XhYu[:62F4Op&_&XhYlU:62g6O9)SA`
-]`<Q~>
-!<E0!ir8*>lMg5No)A=`g,/\'$YdKOs6>S7NUlpc9`%XCQ/;Q;iakfOk5X_34@E$>p,l1Fp,l02
-o(m??_Y4#pNC`d:4AbbF4A_%.qJj[Ks7XT<5l"5%Y5cL(9MkHV4A]b/pAaE;86Puh6qmIW6qC-g
-_Y4#pNC`d:4SqtTef[L[p@^UFp@^UFp@^UFNUlpcBu9TDlA\@.p,l/Jp@^WH:k"\ds8(_d9UY&C
-lBOJ";"jTF;"jTF:hdf?s6>S?Q/;Q;iakfOo(m?sk5X_;4@E$>p,l/ghUXf#>u4@?>u4@?@8KdG
-@8KdK@8KdOAPc3SAPc3WAPc3WBi%W_Bi%W_Bi%W_Bi%W_Bi%WcBi%WcBi%WcBi%WcBi%WgD?!F0
-O_mokO_mokO_mokQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>o
-Q#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#6Ls!]9?%ro*pOr'^NT!ikh^rq6Demb[s&qaCBRs760_!ho&=
-ro+"A6q%%>!q&TMrpp*_!P/8]~>
-!<E/sk54TDp&X#ZqihG`eb9%:[#;Wks.oLU1pl]Ns6c,0^$bpoZu^kas8R/)s8R/)^%VK%Ut,2=
-p9]bXs)XG)s)XF<pA^rNpAb0LMgP8a,gHA>F-Mphs)XF#eb9%:[#:ISs*K\(s*KZgUt,2=p9]bX
-s)\(%s5kG^PlLc)PlLc)PlLc)PeHejUnlQ7s7WgXs8R/)PlLc)r02Z;mf3=TP`*6Cs7Wg@K9ZE9
-F-Q_)F-NKNpAainMmVpPs6c,0^%VK%`U<d"]lSgjs8R/)V!dAdS=Gh.XIPN>XIPN>XIPN>XIPN>
-[%rqN[%rqN[%rqN[%rqN[%rqN[%rqN[%rqN]qgmW]qgmW]qgmW]qgmW]qgmW]qk[m;8&ciPeElW
-PeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElW
-PeElWPeElWPeElWPeEmlPQG=^hYuX=Ud7<D8cYsjp&_&XhYu[:62F4Op&_&XhYlU:62g6O9)SA`
-]`<Q~>
-!<E/tk54TDp&b9E.JcX;5rnp!"$oOF1&CnOF%SIk0`jX53W:`53W;YN1&jlG1&jiL5qt)[5rnp!%
-RE]A0hP%m0hP&(0eksSr\4C5qYp_?8kM)u3W;YN1&jiH5rnp!#XM'T0el9m0erZ"!C8aF0`s^60
-erPt(1Q]r8kLfm8kLfm8kLfm8kMB(0gS)cr\4L@8hi("9)gXC8cUmM0`jX53W:`53W;YN1&jlG1
-&acF3W:`75tX091&k,S5qt)d3W:a_3D*aY0em.5p.@>C8kNi%8kO/.8kO/.8kO/.8kOG68kOG>8
-kO_F8kO_F8kO_F8kO_F8kO_F8kO_F8kO_F8kP"N8kP"N8kP"N8kP"N8kP"N8kP"N8kP"N8kP=W8
-kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_s%4Z'C._*_C._*_C._*_C._*_C._*_C._*_C
-._*_C._*_C._*_8h'3*k54TDp&b8imec/Dmec\Zs.o)[k54TDp&Vi,J,~>
-!s&A\ir8*>lMg5No)A=aqURM":]X6Tr]C9R:e3_FrrRIB8GtXP9Me.V49.eK;#`ZX;#`ZX:^'BP
-4A8F6r]CZ]:cpj::cpj::e3]29L/S>!'pD\"aNp@6p*a6;#`ZX:]X6Tr]CHW:f'8::f'8:r_NVh
-5lNkJ85ME2qbS&BnsN<N4?QG:4?QG:4?QG:83B".9L/S>"%Z6N4T81W4SqqT8GtXP9Me.V49.eK
-;#`ZX;#`ZW:]Nc[49J,N83m/:Ip#cB4?QG.4?Pks:ha&p4Dgqc>tA6t:iTc;:j$2C:jHJG:jlbK
-:jlnO:k<1S:k`IW:k`IW:k`U[:l/m_:l/m_:l/m_:lT0c:lT0c:lT0c:lT0c:m#Tk:m#Tk:m#Tk
-:m#Tk:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:c"AR:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo
-:f*Eo:f*Eo:f*Eo:f*Eo:f*ER2"(A&roX4FrpKdVrq6EiU$hp>roX4FrpKdVrq6EiU$hp>roX4F
-rpKdVrq6B(!.Y~>
-!<E/tk54TDp&b9E@eko^HiA'gK8YA'qYpVmMhD"M"+,raKDoolKDpf/F8q0uF8q.%K6)*dMgPGE%
-YK[\F,PrtF,Ps/F)ut\rc8'dqYp_pMi2q'HiAs'F8h'tHiA'lK8YY/F,PrtF8_!sHiA'gK8Xelq
-hl5[p:ZBBF*!7tF*!7tF*!7tK6)*dMgPGE"+uMQF8h*tF8LjqKDoooH]*f7rc8'lrepets,6nur
-egc'rc8O$Mh?@tF*ih0K6)*lKDoqAK8Z7aF*!kjp5=9^Mi4BqMi4BqMi4BqMi4[,Mi4[,Mi4[,M
-i4[,Mi4[,Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi59=Mi59=M
-i59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=s,/8<S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S
-;W<=S;W<=S;W<=Mdl,Ok54TDp&b8imec/Dmec\Zs.o)[k54TDp&Vi,J,~>
-!<E/uk54TDpAb-neLBuRqCqt1bsD1\!'/Rq!b.Z[_Ee/or]pNVr]q5r8jPa@8jPaH8jPaH8jPaH
-8t8d6r]u$C;F*T`;F*T`;F*Ti;F*Ti;F*Ti>!YH$>!YH$>!YH$>!YH$>!YH$>!YH,>!YH,>!YH,
->!YH,>!YH,>!YH,>!YH,>!YH4>!YH4@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<
-@R3;<@R3;<@R3;<@R3:"Mdet<Mdet<Mdet<Mdet<Mdet<Mdet<Mdet$mel5Emec_XrrJq`r9!nE
-qtC'i!Mo/]k54TDp&b9-!.Y~>
-!W`8[roX4FrpKdVrq?Bg!S0*t:]OMl49/(#:]OMl49/(*:]b@%8B+I+<W5gE=]J9p>ua]t>ua]t
-@9HE'AQ_i+Bj"8/D-`uH5Zpo[EEuC;F^\*CH!sNGI:5rKI:Z5OJRqYSKk4(WKk4(WKkX@[M.od_
-M.od_M.od_M.od_NG23cNG23cNG23cO_IWgO_mokO_mokO_mokQ#0>oQ#0>oQ#0>oQ#0>o5*]t]
-:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo2"'A_
-roX4FrpKdVrq?Bg"/5/Bir8*>lMg5No)A@_q?*GZio9t"rp'LNrpp'^!rBJ.J,~>
-!<E/uk54TDpAb-neRJ$+qJuXhc&;F>!/&g[!h?rV_M\DYregc@repf@s,6oAs,.;UP`(HiP`(Hi
-Pf8l.rel9%P`(HqP`(HqP`(I$S;W<,S;W<,S;W<,S;W<,S;W<4S;W<4S;W<4S;W<4S;W<4S;W<4
-S;W<4S;W<4S;W<4S;W<4S;W<4S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=
-S;W<=S;W<=S;W<=S;W:F]pt"=]pt"=]pt"=]pt"=]pt"=]pt"=]pt!imel5Emec_XrrJq`r9!nE
-qtC'i!Mo/]k54TDp&b9-!.Y~>
-!<E0!k54TDpAY'meL?&8r]pNE_a+8pr]pNVr]q5r8jPa@8jPa@8jPaH8jPaH8jPa8r]u$C;F*T`
-;F*T`;F*T`;F*Ti;F*Ti>!YH$>!YH$>!YH$>!YH$>!YH$>!YH,>!YH,>!YH,>!YH,>!YH,>!YH,
->!YH,>!YH4>!YH4@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<
-@R3:#Mdet<Mdet<Mdet<Mdet<Mdet<Mdet<Mdet<.IR/sqsO@Trr3"pmeu;Fmec_WrrJq`rT="F
-qtC'i!PJJ`~>
-!<E0!k5OZFmf)eVpAXmhehhqOs%EGa7)qt$;#X.<<DZ@_<DZ@_=\qdc>uaQl@9#upAQ;DtBj",'
-:fU1_D-9P+EEu73F^7[7H!O*;H!sB?I:[email protected]@S
-M.K@SNFbdWNG2'[NG2'[NG2'[O_IK_O_IK_O_IK_Q"`ocQ"`oc5*]hU9U0<c9U0<c9U0<c9U0<c
-9U0<c9U0<c9U0<c9U0<c9U0<c9U0<c9U0<c9U0<c9U0<c9U0<c9Jl1sroX4FrpKdVrq??f!ho&A
-roX4FrpKdVrq??f!ho&AroX4FrpKdVrq?Bg!P/8]~>
-!<E0!k54TDpAY'meRF)^rdt2t_h.rIrdt3/re(6/s+>fcMh?YHMh?YHMh?YHMh?Y?Mh?YPMh?YP
-Mh?YPP_4UaP_4UaP_4UaP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4Uq
-P_4UqP_4UqP_4UqP_4UqS:cI$S:cI$S:cI$S:cI$S:cI$S:cI$S:cGK[%)c$[%)c$[%)c$[%)c$
-[%)c$[%)c$[%)c$[%)c$[%)c$[%)c$[%)c$[%)c$@da3WqsO@Trr3"pmeu;Fmec_WrrJq`rT="F
-qtC'i!PJJ`~>
-!W`8_qsO@Tr;QfJ.=k*B8qT_<.IQ?\qsO@Tr;QkpmcN[/mec_Urr](bk2uR/qtC!g!PJJ`~>
-!W`8_rp'LNrpp'^rqcZp!R`fU=b9e.<<G)Ck2u[.rpKdVrq??fs8N1plK77.lMg5No)A@^qZ$Qt
-U$Ce&rp'LNrpp'^rqZ]r\c@6~>
-!W`8_qsO@Tr;QfJ@Y(>+Uk>HF@d`C@qsO@Tr;QkpmcN[/mec_Urr](bk2uR/qtC!g!PJJ`~>
-!!)DN!%EI)JI$l6!%I<"!2T"H!2T"H!!%N~>
-!!)DK!&T64JI$l6!&X)*!28eB!28eB!!%N~>
-!!)DN!+LKbJI$l6!+P>[!2T"H!2T"H!!%N~>
-!<E0!joD3.s+13$s1/.5V#TT>]`<Q~>
-!<E0!joD*+s+13$s1/.5U&X9;\c@6~>
-!<E0!joD3.s+13$s1/.5V#TT>]`<Q~>
-!<E0!joD3.s+13$s1847K;AP0k.LbF~>
-!<E0!joD*+s+13$s1847JYE,+k.1PC~>
-!<E0!joD3.s+13$s1847K;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:8G>!<1^P!!:jS!;tRN!:/A:!9Mr7!:SY;!!_-W!8?-,!.ijTg<\LQ
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:8G>!<1^P!;Y@K!:8G>!<1^P!9W#8!:SYA!;bFL!<:dQ!.ijTg<\LQ
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[Oe`,-Z
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*o%O*Drn@APs4[DO
-rn@;Ns4[JQ"53_TgAM$OgA_-Sg&M-DgA_0OgA_-Tg&M-,r;clOr;clOrr</T!!(aO!.ijTg>^id
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[Oe`,-Z
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%j440^"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)TDrW)oN
-rrE)Qrr<;X!!(a,!!(aL!<:dQ!!(aP!!:jS!;"qE!<(XO!"[c`!8?-,!8?-,!8?-,!8@8Ls4[JQ
-J_G\/j4aNa"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%j440^"f21\k.LbF~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc9/ec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA1d\g&M-,!!(a,!!(^Q!8?-,!:\_A!<:dQ!<:dQ
-!;tRN!!(aP!<:dQ!;tRN!<:dQ!;"qB!#!uc!87DQg=cN,g=cN,g=cN,gAV*PgAV)'g4@u9gAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc9/ec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^rc1s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo@j3Ern@AP$JGI[g&M-,g&M-,qZ-*=rVurPqZ-ZMqu?fP
-!!*#PrrDuNrrE)QrrDZErrE#Orr<>Y!!(a,!!(a,qZ$]O!!)rNrW%N'J_K,;s+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^rc1s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^rf2s+:KN
-s5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQn(RdArn@AP%,([]g&M-,g&M-,!!)KArrE&Prr<,S!!)rN
-rrE)Qrr<,S!!*#PrrDuNrrE)QrrDZErrE#Orr<D[!!(a,!!(a,!!)rNrrDrMrW%N'J_K/<s+(?I
-s5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^rf2s+:KN
-s5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc92ec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)WErrE&P
-rr<Va!!(a,!!(^Q!8?-,!87DQrn@APs4[JQ#20%Wg=cN,o@j3ErS%8O#MK.Xg=cN,gAV*PgA_-S
-g&M-PgA_0QgA_/(g4@u<gAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc92ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%imn']"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*n_3m@rn@;Nrn@>O
-!8@AOrS%2Ms4[JQs4[JQo@j3ErS%8O!nmVSrn@APs4[DOs4[JQrS%2MJ_G\/inFE`"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%imn']"f21\k.LbF~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD3.eUc8%e]lY4K*Kl%s5rIW!.Y~>
-!<E0!joD*+g4@t/g<J@>JHji%s5rIT!.Y~>
-!<E0!joD3.eUc8%e]lY4K*Kl%s5rIW!.Y~>
-!<E0!joV@/eU_IdC4U-JCAucPK*VG,V#TT>]`<Q~>
-!<E0!joV71g4=g+JUrC#Jc=BlJHu5/U&X9;\c@6~>
-!<E0!joV@/eU`X0Mh-f7MuM8qK*VG,V#TT>]`<Q~>
-!<E0!joV@/eU_IdC4U-KC&m]$ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!joV71g4=g+JUrC$JH5`LgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!joV@/eU`X0Mh-f8MZEeVec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:bs+1$`s8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*Cbs8RZI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXT#=$!;rqs!.h5&XQ6J_mf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gA]h+!;tRL!.ijTg>pufs8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k5ONC!;u!X!.j9`k2b\)s8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gPsq>gMrrW)hsquHbuquHAjquHYrq>^MsrW)r!rVur"q>^MsquGr^
-!W];%rN#u!rN#u!JZOF(jfJLMrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/qZ-TKq>gQLq>gNKrW)iLquHcNquHBCquHZKq>^NLrW)rOrVurPq>^NLquGs7
-!W^pSrRq5OrRq5OJ_G\/jkBb7rn@C'rPJU7s4[L(r5/L6#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JqZ-TWq>gQXq>gNWrW)iXquHcZquHBOquHZWq>^NXrW)r[rVur\q>^NXquGsC
-!W_?_rT4([rT4([J`_OGjlZUCrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!#lq'.!3E7%XK2F"X8i7rX8i7tX8i7iX8i7rX8i8!X9/I(
-X8r1"!!*#"!!)u!!!*#"!!)/_!W];%rN#u!rN#u!JZOF(jfJLMrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO#lr]5!8?-,g=cQ)g&M-Kg&M-Mg&M-Bg&M-Kg&M-Og&h?/
-g&V')!!*#P!!)uO!!*#P!!)08!W^pSrRq5OrRq5OJ_G\/jkBb7rn@C'rPJU7rn@C'rPJU7#25dN
-k2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[#ls,M!9WDDk2l[Ajo>DWjo>DYjo>DNjo>DWjo>D[joYVG
-joG>A!!*#\!!)u[!!*#\!!)0D!W_?_rT4([rT4([J`_OGjlZUCrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!#lq'.!3E7%XK2F#X9&C'!;`bs!;iht!:[&i!;W\r!<&u$
-!3E7%r2]kuri?)"rN#u!ri?)"poOJqnuMonXK2F#X8i8!X8i6OXF[J7XT._fec1:$^&S-2ec1:#
-^&S*:eYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO#lr]5!8?-,g=cQ*g&_9.!;bCL!;kIM!:\\B!;Y=K!<(UR
-!8?-,r7V,Nrn7>PrRq5Orn7>PptG`Jo%F0Gg=cQ*g&M-Og&M,(g4@u>gAh3PgAca'_Z0Z7gAca&
-_Z0W?g7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[#ls,M!9WDDk2l[BjoPPF!;bgX!;kmY!:]+N!;YaW!<)$^
-!9WDDr8mtZroO1\rT4([roO1\pu_SVo&^#Sk2l[Bjo>D[jo>C4k(2[Vk5YJ\ec1:$^&S-2ec1:#
-^&S*:eYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;`bu!3?1sX8i7tX8i7iX8i7rX9/I(X8r1"!!*#"
-!!)u!!s#F(!;rnu!;NYq!:m2n!3E7%rN#u!rN#u!JZOF(jfJLMrmh%$rk8@3r71h"rk8@3#1]OL
-k2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;bCN!87GLg&M-Mg&M-Bg&M-Kg&h?/g&V')!!*#P
-!!)uO!s%'/!;tON!;P:J!:nhG!8?-,rRq5OrRq5OJ_G\/jkBb7rn@C'rke^8r7_1%rke^8#25dN
-k2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;bgZ!9O:Xjo>DYjo>DNjo>DWjoYVGjoG>A!!*#\
-!!)u[!s%KG!;tsZ!;P^V!:o7S!9WDDrT4([rT4([J`_OGjlZUCrmh%$rk8@3r71h"rk8@3#1]OL
-k2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"r;c\q!!)nt!!*#"!!)nt!!)nt!!)Mi!!)hrr;cbs!!*#"!!)u!
-r;cbs!!)5a!!*#"!!)u!!!)u!!!%SOJZRt7s6fm:s+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V')!!*#Pr;c]J!!)oM!!*#P!!)oM!!)oM!!)NB!!)iKr;ccL!!*#P!!)uO
-r;ccL!!)6:!!*#P!!)uO!!)uO!!%T(J_K5>s8W)Ps+13es8VuMs+10ds8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG>A!!*#\r;c]V!!)oY!!*#\!!)oY!!)oY!!)NN!!)iWr;ccX!!*#\!!)u[
-r;ccX!!)6F!!*#\!!)u[!!)u[!!%T4J`c(Vs8W)Ks+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;ikq!;iht!;iht!<&u!!;3Dn!<&u!!<0&%!3E7%
-qlBi!X8r1"!s#F(!;rnu!<&u!!:?if!<0&"!<&u!!<&u!!.h5&XQ?P`mf(c:KE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;kLJ!;kIM!;kIM!<(UO!;5%G!<(UO!<1[S!8?-,
-qq;)Og&V')!s%'/!;tON!<(UO!:AJ?!<1[P!<(UO!<(UO!.ijTg?%&gs8LaPJcEUes8(ILJcEUe
-rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;kpV!;kmY!;kmY!<)$[!;5IS!<)$[!<2*_!9WDD
-qrRq[joG>A!s%KG!;tsZ!<)$[!:AnK!<2*\!<)$[!<)$[!.j9`k2kb*s8LRKKE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)u!!W];%r2]kurN#u!ri?)"rN#u!mB$0bri?)"rN#u!JZOF(jfJLMrmh%$!knX6q:5Lt
-s1SI4#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)uO!W^pSr7V,NrRq5Orn7>PrRq5OmFqF;rn7>PrRq5OJ_G\/jkBb7rn@C'!lG!;q:bk"
-s2+g9#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)u[!W_?_r8mtZrT4([roO1\rT4([mH49GroO1\rT4([J`_OGjlZUCrmh%$!knX6q:5Lt
-s1SI4#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)qu!!)nt!!)u!!!*#"!!)u!!!)u!rrDMh!!)u!!!)u!!!%SOJZRt7s6fm:s+:Bds8VlE
-s+:Wks8UWFs5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)rN!!)oM!!)uO!!*#P!!)uO!!)uOrrDNA!!)uO!!)uO!!%T(J_K5>s8W)Ps+(6gs8VlJ
-s+(Kns8UfHs5rIT!.Y~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)rZ!!)oY!!)u[!!*#\!!)u[!!)u[rrDNM!!)u[!!)u[!!%T4J`c(Vs8W)Ks+:Bds8VlE
-s+:Wks8UWFs5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gMrquHbur;Zi!r;cl!quHbuq#L/jq#LGrq>gGp!!)quq>^Msq#LAp
-rrDPirW)nur;_DMJZRq6s6fm:s+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!joqI4g4=h/qZ-TKq>gNKquHcNr;ZiOr;clOquHcNq#L0Cq#LHKq>gHI!!)rNq>^NLq#LBI
-rrDQBrW)oNr;_E&J_K2=s8W)Ps+14MommFds8UfHs5rIT!.Y~>
-!<E0!joqR2eVf@JqZ-TWq>gNWquHcZr;Zi[r;cl[quHcZq#L0Oq#LHWq>gHU!!)rZq>^NXq#LBU
-rrDQNrW)oZr;_E2J`c%Us8W)Ks+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCf*LKE(u%V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb/mJJcGc(U&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCf*LKE(u%V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXO4*L!;NYq!.h57XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g<nUS!;P:J!.ijegAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k0`;k!;P^V!.j9qk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqR2eS8j#quHVqrW)ktqZ-Vsq>^MsquDJQ!!)bp!!)bp!!%SOP-"]Ormh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/quHWJrW)lMqZ-WLq>^NLquDK*!!)cI!!)cI!!%T(P1os9rn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JquHWVrW)lYqZ-WXq>^NXquDK6!!)cU!!)cU!!%T4P32fErmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7pX8i7tX8i8!X8i8"X8i8!X8i8"X8i6RX8i7eX8i6OXHK[bmf(c:KE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Ig&M-Mg&M-Og&M-Pg&M-Og&M-Pg&M,+g&M->g&M,(g611is8LaPJcGcD
-gAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DUjo>DYjo>D[jo>D\jo>D[jo>D\jo>C7jo>DJjo>C4k*"m,s8LRKKE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&"!<&u!!<0&"!;NYq!4Ap.!!',"!;iks!<0)!
-!<0)!!;ESm!;rqt!;iks!!0/$JZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[P!<(UO!<1[P!;P:J!4CP\!!(aP!;kLL!<1^O
-!<1^O!;G4F!;tRM!;kLL!!1dRJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*\!<)$[!<2*\!;P^V!4Cth!!)0\!;kpX!<2-[
-!<2-[!;GXR!;u!Y!;kpX!!23^J``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&%!3E7%r2]kupoOJq[&j9-ri?)"rN#u!ri?)"
-ri?)"r2]kuorJ,npT+>pr2]kuriH,"JZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[S!8?-,r7V,NptG`J[+bN[rn7>PrRq5Orn7>P
-rn7>Pr7V,Np"BBGpY#TIr7V,Nrn@APJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*_!9WDDr8mtZpu_SV[-%AgroO1\rT4([roO1\
-roO1\r8mtZp#Z5SpZ;GUr8mtZroX4\J``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7rX8i8"X8i8!XS`(sXSi.sX8i7"X8i8!X8i8"X8i7uX9em.X8o?'!3E7%
-orJ,npT+>prN#u!r2]kuJZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Kg&M-Pg&M-OgACsLgAM$Lg&M,Pg&M-Og&M-Pg&M-Ng'Ic5g&Tj\!8?-,
-p"BBGpY#TIrRq5Or7V,NJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DWjo>D\jo>D[k555Xk5>;Xjo>C\jo>D[jo>D\jo>DZjp;%MjoFQ+!9WDD
-p#Z5SpZ;GUrT4([r8mtZJ``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8"XS`(sX8i8!X8i8"X9/I(X8r1"!!)u!!!'1'!!)u!!!*#"q>gPs
-"ota+!3E7%orJ,npT+>prN#u!r2]kuJZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-PgACsLg&M-Og&M-Pg&h?/g&V')!!)uO!!'1U!!)uO!!*#Pq>gQL
-"p!B2!8?-,p"BBGpY#TIrRq5Or7V,NJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\k555Xjo>D[jo>D\joYVGjoG>A!!)u[!!'1a!!)u[!!*#\q>gQX
-"p!fJ!9WDDp#Z5SpZ;GUrT4([r8mtZJ``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!'1'!!)u!!!*#"
-!!)eq"9>M'X8qmo!!)bp!!)u!!!)qu!!%SOP-"]Ormh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!'1U!!)uO!!*#P
-!!)fJ"9@-Ug&Ud!!!)cI!!)uO!!)rN!!%T(P1os9rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!'1a!!)u[!!*#\
-!!)fV"9@QajoG&9!!)cU!!)u[!!)rZ!!%T4P32fErmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)u!rrBF-!!)u!
-!!)u!!!)u!!!*#"rr<,%!!)Ym!!*#"!!)nt!!)qu!!*#"rr@VOP-"]Ormh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)uOrrBF[!!)uO
-!!)uO!!)uO!!*#Prr<,S!!)ZF!!*#P!!)oM!!)rN!!*#Prr@W(P1os9rn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)u[rrBFg!!)u[
-!!)u[!!)u[!!*#\rr<,_!!)ZR!!*#\!!)oY!!)rZ!!*#\rr@W4P32fErmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!joqR2eS8j#q#CDrr;Zi!r;Zi!qZ-Vsq>^Msq#LAprrBI.rW)u"rW)nur;cetrr<,%!!)Vl
-rW)ktquH\srW!#$!!%SOPH=fPrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/q#CEKr;ZiOr;ZiOqZ-WLq>^NLq#LBIrrBI\rW)uPrW)oNr;cfMrr<,S!!)WE
-rW)lMquH]LrW!#R!!%T(PM6':rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!joqR2eVf@Jq#CEWr;Zi[r;Zi[qZ-WXq>^NXq#LBUrrBIhrW)u\rW)oZr;cfYrr<,_!!)WQ
-rW)lYquH]XrW!#^!!%T4PNMoFrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXQQ\[!.h5&XSJstmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g?72b!.ijTgA0J&s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k3(n%!.j9`k5"0>s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXP0`U!.h5&XT#=$mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g=k6\!.ijTgA]h+s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k1\qt!.j9`k5ONCs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMnsXSW"qXSi.uXSr5!XSr3NXT,@%!9pQb!.h5<XT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1dLgA:mJgAM$NgAV*OgAV)'gAfk,!9r2;!.ijjgAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#&Xk5,/Vk5>;Zk5GA[k5G@3k5XQD!9rVG!.j:!k5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!)u!!!*#"rrE&"rr@VOjfAF^JZP3>s6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!)uO!!*#PrrE&Prr@W(jk9\7J_HIEs8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!)u[!!*#\rrE&\rr@W4jlQOCJ``<]s8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!s#F(!;ii%!3E7%X8o@$!<'#!!3E:%!"#_,!3?/#X8i7%
-rW)hsrW)ktquH\srW)hsr;cJkquH_trr<5(!!')#!.h5JXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!s%'/!;kIS!8?-,g&Tk+!<(XO!3FoS!"%?Z!87DQg&M-,
-rW)iLrW)lMquH]LrW)iLr;cKDquH`Mrr<5V!!(^Q!.ik#gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!s%KG!;km_!9WDDjoFQC!<)'[!3G>_!"%cf!9O7]jo>DD
-rW)iXrW)lYquH]XrW)iXr;cKPquH`Yrr<5b!!)-]!.j:/k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX9/I(X8r4#!!)u!!s#F(!;ii(!3E7%X8o=%X8r4#rrB+$rr<>+!!')#XK2C%
-ri?)"rN#u!ri?)"ri?)"rN#u!qlBbtr2]kurN#u!oW/#mqQ0\s"KVS'X8mgQV6'^brmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&h?/g&V**!!)uO!s%'/!;kIV!8?-,g&Th,g&V**rrB+Rrr<>Y!!(^Qg=cN,
-rn7>PrRq5Orn7>Prn7>PrRq5Oqq;#Mr7V,NrRq5Oo\'9FqV(rL"PNhUg&Q]XV:ttLrn@C's8VfH
-s+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjoYVGjoGAB!!)u[!s%KG!;kmb!9WDDjoFNDjoGABrrB+^rr<>e!!)-]k2lXD
-roO1\rT4([roO1\roO1\rT4([qrRkYr8mtZrT4([o]?,RqW@eX"Qf[ajoBtpV<7gXrmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juXSi.tX8i8"X8i8"X8i7tX9em.X8o?'!3E7%V5st'XK2E'X8o?'!<&u!!<0&"
-!;ro#!3E7%p8e5opT+>poW/#mqQ'l$XK2E'X8mgQV6'^brmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSgAM$Mg&M-Pg&M-Pg&M-Mg'Ic5g&Tj\!8?-,V:l4Ug=cP\g&Tj\!<(UO!<1[P
-!;tOQ!8?-,p=]KHpY#TIo\'9FqUu,Rg=cP\g&Q]XV:ttLrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bk5>;Yjo>D\jo>D\jo>DYjp;%MjoFQ+!9WDDV</'ak2l[+joFQ+!<)$[!<2*\
-!;ts]!9WDDp>u>TpZ;GUo]?,RqW7t^k2l[+joBtpV<7gXrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX9/I(X8r4#r;cet!!)nt#lq'.!3E7%XK2DuX9em.X8o?'!3E7%rN#u!riGqr
-riH%uqQ'YsqlK\qoW/#mqQ'l$XK2E'X8mgQV6'^brmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&h?/g&V**r;cfM!!)oM#lr]5!8?-,g=cP'g'Ic5g&Tj\!8?-,rRq5Orn@2K
-rn@;NqUtoLqqCrJo\'9FqUu,Rg=cP\g&Q]XV:ttLrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjoYVGjoGABr;cfY!!)oY#ls,M!9WDDk2lZ?jp;%MjoFQ+!9WDDrT4([roX%W
-roX.ZqW7bXqr[eVo]?,RqW7t^k2l[+joBtpV<7gXrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7sX8i8"X8i8"X8i7tX9/I(X8r1"!!&js#lq'.!3E7%XK2F#X8i8"X8i7m
-X8i7tX8i7uX8i8!X8i7mX8i7sX9J[+X8o?'!.h5JXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Lg&M-Pg&M-Pg&M-Mg&h?/g&V')!!&kL#lr]5!8?-,g=cQ*g&M-Pg&M-F
-g&M-Mg&M-Ng&M-Og&M-Fg&M-Lg'.Q2g&Tj\!.ik#gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DXjo>D\jo>D\jo>DYjoYVGjoG>A!!&kX#ls,M!9WDDk2l[Bjo>D\jo>DR
-jo>DYjo>DZjo>D[jo>DRjo>DXjothJjoFQ+!.j:/k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i7sX8i8!X8i8"X8i8!X8i8"X8i7uX8i8!XT&:$X9em.X8o?'!3E7%rN#u!
-rN#u!rN$)$XK2F#X8i7tX8i7uX8i8"XT&:mX8i8"X8i8"X9J[+X8o?'!.h5JXT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Lg&M-Og&M-Pg&M-Og&M-Pg&M-Ng&M-OgA_/Rg'Ic5g&Tj\!8?-,rRq5O
-rRq5OrRq>Rg=cQ*g&M-Mg&M-Ng&M-PgA_0Fg&M-Pg&M-Pg'.Q2g&Tj\!.ik#gAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DXjo>D[jo>D\jo>D[jo>D\jo>DZjo>D[k5PF^jp;%MjoFQ+!9WDDrT4([
-rT4([rT41^k2l[Bjo>DYjo>DZjo>D\k5PGRjo>D\jo>D\jothJjoFQ+!.j:/k5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSi.tXSr4uX8i8"XSi.uXSr5!XSr5!XT&:%XSr2%X8i7%quHburW)nur;chu
-quHYrquH\srW!#$!!)YmrW)r!rW!,'!!')#!.h5KXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gAM$MgAV*Ng&M-PgAM$NgAV*OgAV*OgA_/SgAV'Sg&M-,quHcNrW)oNr;ciN
-quHZKquH]LrW!#R!!)ZFrW)rOrW!,U!!(^Q!.ik$gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5>;Yk5GAZjo>D\k5>;Zk5GA[k5GA[k5PF_k5G>_jo>DDquHcZrW)oZr;ciZ
-quHZWquH]XrW!#^!!)ZRrW)r[rW!,a!!)-]!.j:0k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXN[d@!.h59XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g<A:G!.ijggAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k02u_!.j9sk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXPU&Y!.h5&XS]+!mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g>:Q`!.ijTgABV(s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k2,8#!.j9`k54<@s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMqrXSi-MXR3(h!:R#g!;iks!.h5>XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1gKgAM#&g?mSo!:SY@!;kLL!.ijlgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#)Wk5>:2k3_:2!:T(L!;kpX!.j:#k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i6OXR<.i!:?if!;W\r!.h5>XT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M,(g@!Yp!:AJ?!;Y=K!.ijlgAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>C4k3h@3!:AnK!;YaW!.j:#k5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!jq"9<eS8j#X8o?'!3E7%X8r.!!!)u!rrALhrr<8)!!')#!3H/"s/c2"orS&kri?,#XSr4s
-XSr4rX8i7rX8i6OXI60imf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jq"0>g4=h/g&Tj\!8?-,g&V$(!!)uOrrAMArr<8W!!(^Q!8@DPs4[GPp"K<Drn7AQgAV*L
-gAV*Kg&M-Kg&M,(g6p[ps8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jq"9<eVf@JjoFQ+!9WDDjoG;@!!)u[rrAMMrr<8c!!)-]!9X7\s5s:\p#c/ProO4]k5GAX
-k5GAWjo>DWjo>C4k*bB3s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i8!XT&9gXT&8*X8i7%!3E7%rN#u!orJ,nrN#u!riH,"ri?)"
-rN#u!ri?)"qlBbtq5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M-OgA_/@gA_-Xg&M-,!8?-,rRq5Op"BBGrRq5Orn@APrn7>P
-rRq5Orn7>Pqq;#Mq:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>D[k5PFLk5PDdjo>DD!9WDDrT4([p#Z5SrT4([roX4\roO1\
-rT4([roO1\qrRkYq;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9em.X8o?'!3E7%rN#u!orJ,nq5aPrrN#u!ri?)"r2]ku
-r2]kuq5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'Ic5g&Tj\!8?-,rRq5Op"BBGq:YfKrRq5Orn7>Pr7V,N
-r7V,Nq:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjp;%MjoFQ+!9WDDrT4([p#Z5Sq;qYWrT4([roO1\r8mtZ
-r8mtZq;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9J[+X8o?'!<0&%!3E7%o;qljrN#u!rN#u!riGqrr2]ku
-q5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'.Q2g&Tj\!<1[S!8?-,o@j-CrRq5OrRq5Orn@2Kr7V,N
-q:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjothJjoFQ+!<2*_!9WDDoB,uOrT4([rT4([roX%Wr8mtZ
-q;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9J[+X8o?'!<0&%!3E7%n#QKhri?)"rN#u!ri?)"p8e5o
-q5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'.Q2g&Tj\!<1[S!8?-,n(IaArn7>PrRq5Orn7>Pp=]KH
-q:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjothJjoFQ+!<2*_!9WDDn)aTMroO1\rT4([roO1\p>u>T
-q;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i7uXT&9gX9J[+X8o?'!<'#!!;!8l!<&u!!<0&"!<&u!!<&u!
-!<&u!!;rnu!;W\r!.h5>XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-NgA_/@g'.Q2g&Tj\!<(XO!;"nE!<(UO!<1[P!<(UO!<(UO
-!<(UO!;tON!;Y=K!.ijlgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>DZk5PFLjothJjoFQ+!<)'[!;#=Q!<)$[!<2*\!<)$[!<)$[
-!<)$[!;tsZ!;YaW!.j:#k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juXS`(sXSi.rXT&9hXSr2'X8i7%!!)u!!!)VlquH_trW)u"rW)nur;cetquH\s
-quD;LS#lYXrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSgACsLgAM$KgA_/AgAV'Ug&M-,!!)uO!!)WEquH`MrW)uPrW)oNr;cfMquH]L
-quD<%S(doBrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bk555Xk5>;Wk5PFMk5G>ajo>DD!!)u[!!)WQquH`YrW)u\rW)oZr;cfYquH]X
-quD<1S*'bNrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXS/^q!.h5&XQ$>]mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g@j5#!.ijTg>^ids8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4[p;!.j9`k2PP's8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXS/^q!.h5&XQ$>]mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g@j5#!.ijTg>^ids8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4[p;!.j9`k2PP's8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXSAmq!<'"o!.h5&XRN=kmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gA'D#!<(XH!.ijTg@3hrs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4n*;!<)'T!.j9`k4%O5s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMX8o@#!;rqs!;rqs!;rqs!:m2k!;`eq!:m2k!;NYq!:m2k!;NYq!;!;j!<'"r
-!:m5k!;rqt!:m5i!;iks!;iht!;W_q!;rqs!;rqs!5,E5mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g&Tk*!;tRL!;tRL!;tRL!:nhD!;bFJ!:nhD!;P:J!:nhD!;P:J!;"qC!<(XK
-!:nkD!;tRM!:nkB!;kLL!;kIM!;Y@J!;tRL!;tRL!5.%cs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:joFQB!;u!X!;u!X!;u!X!:o7P!;bjV!:o7P!;P^V!:o7P!;P^V!;#@O!<)'W
-!:o:P!;u!Y!:o:N!;kpX!;kmY!;YdV!;u!X!;u!X!5.Ios8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSW"rXSr4uXSW"qXSr2#X8r7$q>^MsqZ+%*!!)u!!!*#"!!)u!!!*#"!!)u!
-!!*#"!!)u!!!)YmrrDqt!!)u!!!)YmrrDkr!W];%o;qrlq5aVtX8qmo!!)u!!!*#"!!)u!!!)Vl
-!W];%rN#u!ri?)"oW/#mrN#u!rN#u!q5jSrqQ'YsqQ'YsrN#u!ri?)"rN#u!]r_8%rmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gA:mKgAV*NgA:mJgAV'Qg&V-+q>^NLqZ+%X!!)uO!!*#P!!)uO!!*#P!!)uO
-!!*#P!!)uO!!)ZFrrDrM!!)uO!!)ZFrrDlK!W^pSo@j3Eq:YlMg&Ud!!!)uO!!*#P!!)uO!!)WE
-!W^pSrRq5Orn7>Po\'9FrRq5OrRq5Oq:biKqUtoLqUtoLrRq5Orn7>PrRq5O^"WMdrn@C's8VfH
-s+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5,/Wk5GAZk5,/Vk5G>]joGDCq>^NXqZ+%d!!)u[!!*#\!!)u[!!*#\!!)u[
-!!*#\!!)u[!!)ZRrrDrY!!)u[!!)ZRrrDlW!W_?_oB-&Qq;q_YjoG&9!!)u[!!*#\!!)u[!!)WQ
-!W_?_rT4([roO1\o]?,RrT4([rT4([q<%\WqW7bXqW7bXrT4([roO1\rT4([^#o@prmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i7uX8i7uX8i8!X8i8"X8i8"XT&;!X8i8!X9/I(X8r4#!!'I/!!)u!
-!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)\n!W];%qlBbtrN#u!orJ2pX8r't!W];%oW/)oX8r't
-!W];%oW/#mrN#u!q5aPro;hunX8r4#!!)u!!!)\n!!)u!!!*#"!!)hr!W];%qlBbtq5aPrrN#u!
-ri?)"rN#u!]r_8%rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&M-Ng&M-Ng&M-Og&M-Pg&M-PgA_0Og&M-Og&h?/g&V**!!'I]!!)uO
-!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)]G!W^pSqq;#MrRq5Op"BHIg&Us&!W^pSo\'?Hg&Us&
-!W^pSo\'9FrRq5Oq:YfKo@a6Gg&V**!!)uO!!)]G!!)uO!!*#P!!)iK!W^pSqq;#Mq:YfKrRq5O
-rn7>PrRq5O^"WMdrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[jo>DZjo>DZjo>D[jo>D\jo>D\k5PG[jo>D[joYVGjoGAB!!'Ii!!)u[
-!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)]S!W_?_qrRkYrT4([p#Z;UjoG5>!W_?_o]?2TjoG5>
-!W_?_o]?,RrT4([q;qYWoB$)SjoGAB!!)u[!!)]S!!)u[!!*#\!!)iW!W_?_qrRkYq;qYWrT4([
-roO1\rT4([^#o@prmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!<&u!!<&u!!<&u$!3E7%r2]kurN-#!
-\?#Z1ri?)"rN#u!ri?)"rN#u!q5aPro;holqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8q^j
-!!)ks!!)Vl!s#F(!<&u!!<&u!!:[&i!<0&"!;EPp!;iht!;*>m!;W\r!55K6mf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!<(UO!<(UO!<(UR!8?-,r7V,NrS%8O
-\Cpo_rn7>PrRq5Orn7>PrRq5Oq:YfKo@a0Eqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UTq
-!!)lL!!)WE!s%'/!<(UO!<(UO!:\\B!<1[P!;G1I!;kIM!;+tF!;Y=K!57+ds8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!<)$[!<)$[!<)$^!9WDDr8mtZrT=+[
-\E3bkroO1\rT4([roO1\rT4([q;qYWoB$#QqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFl4
-!!)lX!!)WQ!s%KG!<)$[!<)$[!:]+N!<2*\!;GUU!;kmY!;,CR!;YaW!57Ops8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!;NVt!3E7%rN#u!r2]kurN-#!\Z>c2
-rN#u!rN#u!ri?)"rN#u!qQ'YsnuMfkqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8qak!!)hr
-!!)Vl!s#F(!<&u!!<0)"!:d,j!<&u"!3H/"qlBbtqlBeuXSr4qX8i7rX8i75XT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!;P7M!8?-,rRq5Or7V,NrS%8O\_7#`
-rRq5OrRq5Orn7>PrRq5OqUtoLo%F'Dqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UWr!!)iK
-!!)WE!s%'/!<(UO!<1^P!:ebC!<(UP!8@DPqq;#Mqq;&NgAV*Jg&M-Kg&M,cgAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!;P[Y!9WDDrT4([r8mtZrT=+[\`Nkl
-rT4([rT4([roO1\rT4([qW7bXo&]oPqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFo5!!)iW
-!!)WQ!s%KG!<)$[!<2-\!:f1O!<)$\!9X7\qrRkYqrRnZk5GAVjo>DWjo>Cok5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X8i8"X8i8"X8i8"X8i8"X8i7uXSi.sXSi.tX8i7uX8i7-X8i7uX8i8!
-X8i8"X8i8!X8i7tX8i7uXSW"qX8i7tX8i8!X8i8"XSW"qX8i7tX8i8"X8i7kX8i7tX8i8"X8i7j
-X8i7qX8i7mX8i8"X8i7uXSr2#X8qgm!!)qurrE&"!!)qu!!)ntrrE&"!!)nt!!)hr!!'X4s6fm:
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-Pg&M-Pg&M-Pg&M-Pg&M-NgAM$LgAM$Mg&M-Ng&M,[g&M-Ng&M-O
-g&M-Pg&M-Og&M-Mg&M-NgA:mJg&M-Mg&M-Og&M-PgA:mJg&M-Mg&M-Pg&M-Dg&M-Mg&M-Pg&M-C
-g&M-Jg&M-Fg&M-Pg&M-NgAV'Qg&U]t!!)rNrrE&P!!)rN!!)oMrrE&P!!)oM!!)iK!!'Xbs8W)P
-s+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\jo>D\jo>D\jo>D\jo>DZk5>;Xk5>;Yjo>DZjo>Cgjo>DZjo>D[
-jo>D\jo>D[jo>DYjo>DZk5,/Vjo>DYjo>D[jo>D\k5,/Vjo>DYjo>D\jo>DPjo>DYjo>D\jo>DO
-jo>DVjo>DRjo>D\jo>DZk5G>]joFu7!!)rZrrE&\!!)rZ!!)oYrrE&\!!)oY!!)iW!!'Xns8W)K
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXS`(sXS`(tXSi.nX8i8!X9/I(X8r4#!!)qu!!'F.!!)nt!!)u!!!*#"!!)u!
-!!)qu!!)Mi!!)nt!!)u!!!)Vl!!)nt!!*#"!!)Sk!!)nt!!*#"!!)Sk!!)eq!!)Vl!!*#"!!)eq
-!!)Vl!!)nt!!)u!!!)qu!!)nt!!)u!!!)qu!!)hr!!'U3s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSgACsLgACsMgAM$Gg&M-Og&h?/g&V**!!)rN!!'F\!!)oM!!)uO!!*#P!!)uO
-!!)rN!!)NB!!)oM!!)uO!!)WE!!)oM!!*#P!!)TD!!)oM!!*#P!!)TD!!)fJ!!)WE!!*#P!!)fJ
-!!)WE!!)oM!!)uO!!)rN!!)oM!!)uO!!)rN!!)iK!!'Uas8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bk555Xk555Yk5>;Sjo>D[joYVGjoGAB!!)rZ!!'Fh!!)oY!!)u[!!*#\!!)u[
-!!)rZ!!)NN!!)oY!!)u[!!)WQ!!)oY!!*#\!!)TP!!)oY!!*#\!!)TP!!)fV!!)WQ!!*#\!!)fV
-!!)WQ!!)oY!!)u[!!)rZ!!)oY!!)u[!!)rZ!!)iW!!'Ums8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r7$!!)u!!!)u!!!)u!!!)u!!s#F(!;rnu!4Js/!;`bs
-!<&u!!<0&"!<&u!!<&u!!:Quh!;iht!<&u!!;!8l!;ikp!;!8l!;ikp!;*>m!;EPp!;!;h!;W\r
-!;*>m!;`bs!<&u!!;rnu!;iht!<&u!!<&u!!;W\r!4f32mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V-+!!)uO!!)uO!!)uO!!)uO!s%'/!;tON!4LS]!;bCL
-!<(UO!<1[P!<(UO!<(UO!:SVA!;kIM!<(UO!;"nE!;kLI!;"nE!;kLI!;+tF!;G1I!;"qA!;Y=K
-!;+tF!;bCL!<(UO!;tON!;kIM!<(UO!<(UO!;Y=K!4gh`s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGDC!!)u[!!)u[!!)u[!!)u[!s%KG!;tsZ!4M"i!;bgX
-!<)$[!<2*\!<)$[!<)$[!:T%M!;kmY!<)$[!;#=Q!;kpU!;#=Q!;kpU!;,CR!;GUU!;#@M!;YaW
-!;,CR!;bgX!<)$[!;tsZ!;kmY!<)$[!<)$[!;YaW!4h7ls8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r4#!!*#"rrE&"!!)u!!!)u!!s#F(!<&u!!;rqu!55H6
-!<&u!!<0&"!<&u!!<0&"!<&u!!<0&"!<&u!!;!8l!;iht!<&u!!;!8l!;EPp!:m2k!;EPp!;ikt
-!;rnu!<&u!!;iht!;`es!;NVq!;W\r!;ikt!;rnu!<&u!!<&u!!<0&"!;rnu!;`bs!<0&"!<0&"
-!<&u!!<0&"!<&u!!55K6mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V**!!*#PrrE&P!!)uO!!)uO!s%'/!<(UO!;tRN!57(d
-!<(UO!<1[P!<(UO!<1[P!<(UO!<1[P!<(UO!;"nE!;kIM!<(UO!;"nE!;G1I!:nhD!;G1I!;kLM
-!;tON!<(UO!;kIM!;bFL!;P7J!;Y=K!;kLM!;tON!<(UO!<(UO!<1[P!;tON!;bCL!<1[P!<1[P
-!<(UO!<1[P!<(UO!57+ds8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGAB!!*#\rrE&\!!)u[!!)u[!s%KG!<)$[!;u!Z!57Lp
-!<)$[!<2*\!<)$[!<2*\!<)$[!<2*\!<)$[!;#=Q!;kmY!<)$[!;#=Q!;GUU!:o7P!;GUU!;kpY
-!;tsZ!<)$[!;kmY!;bjX!;P[V!;YaW!;kpY!;tsZ!<)$[!<)$[!<2*\!;tsZ!;bgX!<2*\!<2*\
-!<)$[!<2*\!<)$[!57Ops8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSi.tXSi,!XSMqqX98O)X8o@$!<'"q!!'+t!;ikt!55K2!<'"t!;rqs!<'"r
-!;3Gk!;rqs!;*Aj!;`er!;3Gk!;`er!;rqu!;rqq!;iht!;`es!;W_q!<'"u!;`es!;rqq!;rqt
-!<'"s!;iks!<'"r!<0(s!55K6mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%O5g4=h/gAM$MgAM!OgA1gJg&qE0g&Tk+!<(XJ!!(aM!;kLM!57+`!<(XM!;tRL!<(XK
-!;5(D!;tRL!;,"C!;bFK!;5(D!;bFK!;tRN!;tRJ!;kIM!;bFL!;Y@J!<(XN!;bFL!;tRJ!;tRM
-!<(XL!;kLL!<(XK!<1^L!57+ds8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp%X3eVf@Jk5>;Yk5>8[k5#)Vjob\HjoFQC!<)'V!!)0Y!;kpY!57Ol!<)'Y!;u!X!<)'W
-!;5LP!;u!X!;,FO!;bjW!;5LP!;bjW!;u!Z!;u!V!;kmY!;bjX!;YdV!<)'Z!;bjX!;u!V!;u!Y
-!<)'X!;kpX!<)'W!<2-X!57Ops8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSr2#X8r7$r;churW)u"rW)u"q>gPsq>^MsrW)u"rW)u"q>gMrrVuu#!.h5&
-XIZHmmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRgAV'Qg&V-+r;ciNrW)uPrW)uPq>gQLq>^NLrW)uPrW)uPq>gNKrVuuQ!.ijT
-g7?sts8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ak5G>]joGDCr;ciZrW)u\rW)u\q>gQXq>^NXrW)u\rW)u\q>gNWrVuu]!.j9`
-k+1Z7s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8"XT&;#X8i8!X8i8"XT&;"X8i8"X9J[+X8o?'!<0&"!<&u%!3E7%!<0&"
-!<0&+!3E7%XK2E'X8r7$rr@VOJZPEDs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-PgA_0Qg&M-Og&M-PgA_0Pg&M-Pg'.Q2g&Tj\!<1[P!<(US!8?-,!<1[P
-!<1[Y!8?-,g=cP\g&V-+rr@W(J_H[Ks8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D\k5PG]jo>D[jo>D\k5PG\jo>D\jothJjoFQ+!<2*\!<)$_!9WDD!<2*\
-!<2*e!9WDDk2l[+joGDCrr@W4J``Ncs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!W];%qlC&'XK2E'!3E7%ri?;(XK2E'X8r7$!!)u!#QUs-!3?1%X8r7$
-#lq'.!3E7%XK2F#X8i7uXT&9OXF[IKXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!W^pSqq;;Ug=cP\!8?-,rn7PVg=cP\g&V-+!!)uO#QWT4!87G,g&V-+
-#lr]5!8?-,g=cQ*g&M-NgA_/(g4@tRgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!W_?_qrS.ak2l[+!9WDDroOCbk2l[+joGDC!!)u[#QX#L!9O:DjoGDC
-#ls,M!9WDDk2l[Bjo>DZk5PF4k(2Zjk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3?1%X8r.!!!)nt!s#F(!<&u&!3?1%X8r.!!!)qu!!)bp
-rr@VOJZPZKs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!87G,g&V$(!!)oM!s%'/!<(UT!87G,g&V$(!!)rN!!)cI
-rr@W(J_HpRs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9O:DjoG;@!!)oY!s%KG!<)$`!9O:DjoG;@!!)rZ!!)cU
-rr@W4J``cjs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)ntr;cet"TYX*!3?1tX8i7tXSi-MXF[IC
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oMr;cfM"T[91!87GMg&M-MgAM#&g4@tJ
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oYr;cfY"T[]I!9O:Yjo>DYk5>:2k(2Zb
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)nt!s#F(!<&u&!3E7%X8r.!!!)bp!!%SO
-JZPEDs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oM!s%'/!<(UT!8?-,g&V$(!!)cI!!%T(
-J_H[Ks8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oY!s%KG!<)$`!9WDDjoG;@!!)cU!!%T4
-J``Ncs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt!s#F(!<0)"!;iht!;iht!<&u$!3E7%riH,"qlBbtr2]kurN#u!
-JZOF(SZMkZrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V!'!!)oM!s%'/!<1^P!;kIM!;kIM!<(UR!8?-,rn@APqq;#Mr7V,NrRq5O
-J_G\/S_F,Drn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG8?!!)oY!s%KG!<2-\!;kmY!;kmY!<)$^!9WDDroX4\qrRkYr8mtZrT4([
-J`_OGS`]tPrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!*#"rrDqt!!)nt!!)u!!s#F(!<0)"!;iht!;rqu
-!<0&"!;rqu!.h5&XJDrtmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!*#PrrDrM!!)oM!!)uO!s%'/!<1^P!;kIM!;tRN
-!<1[P!;tRN!.ijTg8*I&s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!*#\rrDrY!!)oY!!)u[!s%KG!<2-\!;kmY!;u!Z
-!<2*\!;u!Z!.j9`k+q/>s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSi.tXSi.uXSr5!X8i8!XS`(tXSMnsXSr5!X8i8!XS`(tX8r=&rW)hsrr@VO
-JZPZKs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hRgAM$MgAM$NgAV*Og&M-OgACsMgA1dLgAV*Og&M-OgACsMg&V3-rW)iLrr@W(
-J_HpRs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@ak5>;Yk5>;Zk5GA[jo>D[k555Yk5#&Xk5GA[jo>D[k555YjoGJErW)iXrr@W4
-J``cjs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8i\X8i7WX8i7qXT&:kX8i7`XT&;!XSW"qX8i7rX8i6OXLtY7mf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g:g&M-0g&M-JgA_0Dg&M-9gA_0OgA:mJg&M-Kg&M,(g:Z/>s8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?Ijo>D<jo>DVk5PGPjo>DEk5PG[k5,/Vjo>DWjo>C4k.KjVs8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#rW)u"rW(u[!!'p<!!)bp!!(lW!!)bp!!)Sk!!)5a!W];%rN#u!rN#u!rN-#!
-qQ0\sJZQMcs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/rW)uPrW)!4!!'pj!!)cI!!(m0!!)cI!!)TD!!)6:!W^pSrRq5OrRq5OrS%8O
-qV(rLJ_Icjs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@JrW)u\rW)!@!!'q!!!)cU!!(m<!!)cU!!)TP!!)6F!W_?_rT4([rT4([rT=+[
-qW@eXJ`aW-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp7d5eS8j#X8i8"X8i7[X8i7<X8i7AX8i7QX9&C'!;NVq!<0&$!3?1tX9&C'!.h5aXT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp7[7g4=h/g&M-Pg&M-4g&M,jg&M,og&M-*g&_9.!;P7J!<1[R!87GMg&_9.!.ik:gAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp7d5eVf@Jjo>D\jo>D@jo>D!jo>D&jo>D6joPPF!;P[V!<2*^!9O:YjoPPF!.j:Fk5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp\'9eS8j#X8o=%XK2F"XSr5!XSr5!XSr4oXS`(sXT&;#XT&;!XSi.uXT&8#XSr4tXS`(s
-XSi.rXSr2%X8o?'quHYrrW)hsr;churr<&#rW)PkrW)hsrVuu#!;*Al!;ikq!;*>p!3E7%q5aPr
-qlBbtq5aPrJZQMcs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp[s;g4=h/g&Th,g=cQ)gAV*OgAV*OgAV*HgACsLgA_0QgA_0OgAM$NgA_-QgAV*MgACsL
-gAM$KgAV'Sg&Tj\quHZKrW)iLr;ciNrr<&QrW)QDrW)iLrVuuQ!;,"E!;kLJ!;+tI!8?-,q:YfK
-qq;#Mq:YfKJ_Icjs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp\'9eVf@JjoFNDk2l[Ak5GA[k5GA[k5GATk555Xk5PG]k5PG[k5>;Zk5PD]k5GAYk555X
-k5>;Wk5G>_joFQ+quHZWrW)iXr;ciZrr<&]rW)QPrW)iXrVuu]!;,FQ!;kpV!;,CU!9WDDq;qYW
-qrRkYq;qYWJ`aW-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp\'9eS8j#X8o=%XK2F#X8i8"X8i8"X8i7uX8i7nX8i7rX9\g-!3E7%XK2F#X8i8"XT&;"
-X8i8"X8i8!X8i8"X8i8!X8i8!X8i8"XT&;"X8i7pX8i7uX8i8!X8i8"XT&;"X8i7kX8i7uX8i8"
-XT&:kX8i7uX8i8!X8i7mX9/I(X8r't!!)nt!!)hr!!%SO]WD/$rmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!jp[s;g4=h/g&Th,g=cQ*g&M-Pg&M-Pg&M-Ng&M-Gg&M-Kg'@]4!8?-,g=cQ*g&M-PgA_0P
-g&M-Pg&M-Og&M-Pg&M-Og&M-Og&M-PgA_0Pg&M-Ig&M-Ng&M-Og&M-PgA_0Pg&M-Dg&M-Ng&M-P
-gA_0Dg&M-Ng&M-Og&M-Fg&h?/g&Us&!!)oM!!)iK!!%T(]\<Dcrn@C's8VfHs+14M#25dNk2s5T
-J,~>
-!<E0!jp\'9eVf@JjoFNDk2l[Bjo>D\jo>D\jo>DZjo>DSjo>DWjp1tL!9WDDk2l[Bjo>D\k5PG\
-jo>D\jo>D[jo>D\jo>D[jo>D[jo>D\k5PG\jo>DUjo>DZjo>D[jo>D\k5PG\jo>DPjo>DZjo>D\
-k5PGPjo>DZjo>D[jo>DRjoYVGjoG5>!!)oY!!)iW!!%T4]]T7ormh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!jp\'9eS8j#X8o?'!3?2"X8i7uX9em.X8o?'!3E7%orJ,nq5jSrp8e5ori?)"rN#u!ri?)"
-oW/#mri?)"r2]kuri?)"pT+>prN#u!qlBl"XK2F#X8i7kX8i8!X8i7uX8i7kX8i7uX8i7iX8i8"
-X8i7rX8i7tX8i7rX8i6OXLtY7mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp[s;g4=h/g&Tj\!87GPg&M-Ng'Ic5g&Tj\!8?-,p"BBGq:biKp=]KHrn7>PrRq5Orn7>P
-o\'9Frn7>Pr7V,Nrn7>PpY#TIrRq5Oqq;,Pg=cQ*g&M-Dg&M-Og&M-Ng&M-Dg&M-Ng&M-Bg&M-P
-g&M-Kg&M-Mg&M-Kg&M,(g:Z/>s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp\'9eVf@JjoFQ+!9O:\jo>DZjp;%MjoFQ+!9WDDp#Z5Sq<%\Wp>u>TroO1\rT4([roO1\
-o]?,RroO1\r8mtZroO1\pZ;GUrT4([qrRt\k2l[Bjo>DPjo>D[jo>DZjo>DPjo>DZjo>DNjo>D\
-jo>DWjo>DYjo>DWjo>C4k.KjVs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp\'9eS8j#X8o?'!3?2"XSMqsX9J[+X8o?'!;3Dn!;W\r!;W_o!<0&"!<&u!!<'"t!;rqr
-!<0&"!;NVq!;EPp!<&u!!;ii"!3E7%rN#u!nuMfkrN#u!r2]kunuMfkqlK_roW/#mri?)"qQ'Ys
-qQ'Ysq5aPrJZQMcs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp[s;g4=h/g&Tj\!87GPgA1gLg'.Q2g&Tj\!;5%G!;Y=K!;Y@H!<1[P!<(UO!<(XM!;tRK
-!<1[P!;P7J!;G1I!<(UO!;kIP!8?-,rRq5Oo%F'DrRq5Or7V,No%F'DqqCuKo\'9Frn7>PqUtoL
-qUtoLq:YfKJ_Icjs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp\'9eVf@JjoFQ+!9O:\k5#)XjothJjoFQ+!;5IS!;YaW!;YdT!<2*\!<)$[!<)'Y!;u!W
-!<2*\!;P[V!;GUU!<)$[!;km\!9WDDrT4([o&]oPrT4([r8mtZo&]oPqr[hWo]?,RroO1\qW7bX
-qW7bXq;qYWJ`aW-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r7$rrE&"!!)eq"9>M'X8qmo!!)hr!!)ks!!)u!!!*#"!!)u!!!)hr!!*#"
-!!)u!!!*#"!!)eq!!)bp!!)u!!!)nt!s#F(!<&u!!:m2k!<&u!!;rnu!:m2k!;EPp!;3Gj!;iht
-!;`bs!;W\r!.h5aXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V-+rrE&P!!)fJ"9@-Ug&Ud!!!)iK!!)lL!!)uO!!*#P!!)uO!!)iK!!*#P
-!!)uO!!*#P!!)fJ!!)cI!!)uO!!)oM!s%'/!<(UO!:nhD!<(UO!;tON!:nhD!;G1I!;5(C!;kIM
-!;bCL!;Y=K!.ik:gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoGDCrrE&\!!)fV"9@QajoG&9!!)iW!!)lX!!)u[!!*#\!!)u[!!)iW!!*#\
-!!)u[!!*#\!!)fV!!)cU!!)u[!!)oY!s%KG!<)$[!:o7P!<)$[!;tsZ!:o7P!;GUU!;5LO!;kmY
-!;bgX!;YaW!.j:Fk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r7$rrE#!!!)u!!!*#"rr<,%!!)Ym!!*#"!!)u!!!)ks!!*#"rrE&"!!)u!
-!!*#"!!)u!!!*#"!!*#"rrE#!!!)u!!!*#"!!*#"!!)nt!!)qu!!)u!!!*#"!!)u!!!)Sk!!)qu
-!!*#"rrDVk!!)qu!!)u!!!)Pj!!)ks!!)ks!!)hr!!%SO]WD/$rmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!jp.U6g4=h/g&V-+rrE#O!!)uO!!*#Prr<,S!!)ZF!!*#P!!)uO!!)lL!!*#PrrE&P!!)uO
-!!*#P!!)uO!!*#P!!*#PrrE#O!!)uO!!*#P!!*#P!!)oM!!)rN!!)uO!!*#P!!)uO!!)TD!!)rN
-!!*#PrrDWD!!)rN!!)uO!!)QC!!)lL!!)lL!!)iK!!%T(]\<Dcrn@C's8VfHs+14M#25dNk2s5T
-J,~>
-!<E0!jp.^4eVf@JjoGDCrrE#[!!)u[!!*#\rr<,_!!)ZR!!*#\!!)u[!!)lX!!*#\rrE&\!!)u[
-!!*#\!!)u[!!*#\!!*#\rrE#[!!)u[!!*#\!!*#\!!)oY!!)rZ!!)u[!!*#\!!)u[!!)TP!!)rZ
-!!*#\rrDWP!!)rZ!!)u[!!)QO!!)lX!!)lX!!)iW!!%T4]]T7ormh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!joqR2eS8j#rW)r!!!)qur;cetrr<,%!!)VlrW)nur;c_rrW!&%!!',"!<9/"!<9.u!;rqt
-!!95%!<'"t!;rqt!;rqr!<'"t!<0)!!<9/"!;3Gk!<'"u!!95%!;3Gk!<0(t!:d/i!;iht!;rqr
-!<'"s!.h5cXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqI4g4=h/rW)rO!!)rNr;cfMrr<,S!!)WErW)oNr;c`KrW!&S!!(aP!<:dP!<:dN!;tRM
-!!:jS!<(XM!;tRM!;tRK!<(XM!<1^O!<:dP!;5(D!<(XN!!:jS!;5(D!<1^M!:eeB!;kIM!;tRK
-!<(XL!.ik<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!joqR2eVf@JrW)r[!!)rZr;cfYrr<,_!!)WQrW)oZr;c`WrW!&_!!)0\!<;3\!<;3Z!;u!Y
-!!;9_!<)'Y!;u!Y!;u!W!<)'Y!<2-[!<;3\!;5LP!<)'Z!!;9_!;5LP!<2-Y!:f4N!;kmY!;u!W
-!<)'X!.j:Hk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uDKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcBJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uDKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH3RZrs=8Vs4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJHE^gs7k=JJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcEUes7tCKJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcEUes8(ILJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc<Ods81OMJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc<Ods8:UNJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc3Ics8C[OJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc3Ics8LaPJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*Cbs8UgQJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:as8ITI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJbm7`Jc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMmXaeWmaU\(ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+s+13$s4%)JgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:s+13$s4%)Jec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!jo_F0eS9['JaS*We*d4cs+Bh@#1]OLk2s>WJ,~>
-!<E0!jo_=2g4=hTJcC<$e,TF$s+0\>#25dNk2s5TJ,~>
-!<E0!jo_F0eVf"YJcC<$e,TEts+Bh@#1]OLk2s>WJ,~>
-!<E0!joD3.eUc8%e]lVEKCAgEeYN6-k.LbF~>
-!<E0!joD*+g4@t/g<J=OJa`UCg7eQ/k.1PC~>
-!<E0!joD3.eUc8%e]lVEKCAgEeYN6-k.LbF~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joM:.JV/N+JV2=%ldZ07s5rIW!.Y~>
-!<E0!joM10JUrB'JUu1!le2N9s5rIT!.Y~>
-!<E0!joM:.JV/N+JV2=%ldZ07s5rIW!.Y~>
-!<E0!joM:.JV/N+JV2@&!<;B8"f21\k.LbF~>
-!<E0!joM10JUrB'JUu4"!<;B="ektYk.1PC~>
-!<E0!joM:.JV/N+JV2@&!<;B8"f21\k.LbF~>
-!<E0!jo_F0K7id/!WTias+13$s7H<m^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_=2JV!F0!WU#fs+13$s7H<m_Z0Z._Z0Z%g'+2Mk2s5TJ,~>
-!<E0!jo_F0K7id/!WTias+13$s7H<m^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+14CrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<E0!jo_=2JV!L2s8N+N_L_`<s+14CrrI\frVuT.s8VE="ektYk.1PC~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+14CrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<?U-5m#ShKD3(Ys8R]Q^&S+`eUc8%ebI\pK)iU^s7j;-s6J2=6"3,G!!%N~>
-!<@-<9ENq!JbR%\s8RWO_Z0Xeg4@t/gA'D%JH3Ras7jJ2s6JAB9Q<a"!!%N~>
-!<BM*PQKBfKD3(Ys8R]Q^&S+`eUc8%ebI\pK)iU^s7j;-s6J2=PdH[>!!%N~>
-!!)tU"$tIiKDE4Zrrpr*K>%<bJ^o>%J^sPGs+:Hfs8UX"rVu`-s8VE8"[S&U@R1!E~>
-!!)t_"&.F"Jbd1]rrq,-J\qHeJ_G\/J_KnQs+(<is8Ug,rVu`2s8VE="\b2$ED-@_~>
-!!)u:"-h>gKDE4Zrrpr*K>%<bJ^o>%J^sPGs+:Hfs8UX"rVu`-s8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7j'7rVulIs+:Bds8RZ#J^o>%psoCs!knX6rRLlHr4W.1ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!^8rVulNs+(6gs8RZ(J_G\/ptGb!!lG!;rS%5Mr5/L6le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7j'7rVulIs+:Bds8RZ#J^o>%psoCs!knX6rRLlHr4W.1ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7j-9rVufGs+:Bds8RZ#J^o>%psoCs!knX6qpkZFrk8@3ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!d:rVufLs+(6gs8RZ(J_G\/ptGb!!lG!;qqD#Krke^8le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7j-9rVufGs+:Bds8RZ#J^o>%psoCs!knX6qpkZFrk8@3ldZ0'`O*":!.Y~>
-!<A&W@Kf'JK7gkNrVu`Es+:Bds8RZ#J^o>%psoCs!knX6q:5HD!knX6ldZ/)Mdg-]!.Y~>
-!<ADaE<T%iJUt\TrVu`Js+(6gs8RZ(J_G\/ptGb!!lG!;q:bfI!lG!;le2M9Q#Ue;!.Y~>
-!<C+<Ziu]EK7gkNrVu`Es+:Bds8RZ#J^o>%psoCs!knX6q:5HD!knX6ldZ0'`O*":!.Y~>
-!<A&W@KAdFqh+[os+:Bds8RZ#J^o>%psoCs!knX6pso=qs8VE8"[S&U@R1!E~>
-!<ADaE</beqgnOrs+(6gs8RZ(J_G\/ptGb!!lG!;ptG[ts8VE="\b2$ED-@_~>
-!<C+<ZiQEAqh+[os+:Bds8RZ#J^o>%psoCs!knX6pso=qs8VE8"dI!5[$1Q@~>
-!<A&W@Kf'JK7gkNrIasss+:Bds8RZ#J^o>%psoCs!knX6q:5Fr!knX6ldZ/)Mdg-]!.Y~>
-!<ADaE<T%iJUt\TrIOh!s+(6gs8RZ(J_G\/ptGb!!lG!;q:bdu!lG!;le2M9Q#Ue;!.Y~>
-!<C+<Ziu]EK7gkNrIasss+:Bds8RZ#J^o>%psoCs!knX6q:5Fr!knX6ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7j-9rIb$us+:Bds8RZ#J^o>%psoCs!knX6qpkXtrk8@3ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!d:rIOn#s+(6gs8RZ(J_G\/ptGb!!lG!;qqD""rke^8le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7j-9rIb$us+:Bds8RZ#J^o>%psoCs!knX6qpkXtrk8@3ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7j'7rIb+"s+:Bds8RZ#J^o>%psoCs!knX6rRLk!r4W.1ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!^8rIOt%s+(6gs8RZ(J_G\/ptGb!!lG!;rS%4$r5/L6le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7j'7rIb+"s+:Bds8RZ#J^o>%psoCs!knX6rRLk!r4W.1ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7j!5rIY:(K7gl;s+/^OeUc9Gec17)^&S,_ebt-s^&S,ueHJ6s@U_V'J,~>
-!<ADaE<AngJV!X6rIG.+JUt]<s+/mTg4@uQgAc^,_Z0YigAQU!_Z0Z%g'(08EH+YPJ,~>
-!<C+<ZicQCK7j!5rIY:(K7gl;s+/^OeUc9Gec17)^&S,_ebt-s^&S,ueHM2V['Z%tJ,~>
-!<A&W@KSpHK7ip3r.>'as8RZ#J^o>%psoCs!knX6rIamYs8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!R4r.+pds8RZ(J_G\/ptGb!!lG!;rIOa\s8VE="\b2$ED-@_~>
-!<C+<ZicQCK7ip3r.>'as8RZ#J^o>%psoCs!knX6rIamYs8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7ij1rdt9cs8RY&JV/N+p4EL]s8R_(p:^M+ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!L2rdb-fs8RY$JUrB'p43@`s8RY$p;6k0le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7ij1rdt9cs8RY&JV/N+p4EL]s8R_(p:^M+ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7id/!e\2dJV/N+JV3WJ!knVdoY(;)ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!F0!eJ5gJUrB'JV!KF!lFtgoYUY.le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7id/!e\2dJV/N+JV3WJ!knVdoY(;)ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7eaTJcC<$df8X`"[S&U@R1!E~>
-!<ADaE<AngJUrCPJcC<$df8Xe"\b2$ED-@_~>
-!<C+<ZicQCK7eaTJcC<$df8X`"dI!5[$1Q@~>
-!<A&W@KJjGK7X&Rs+13ts6J2=6&T2]5lcE~>
-!<ADaE<8hfJV!iPs+13ts6JAB9U0U;9E9S~>
-!<C+<ZiZKBK7X&Rs+13ts6J2=Pf:#:PQ64~>
-!<A&W@K8]FeUc8%e[a366&T2]5lcE~>
-!<ADaE<&[`g4@t/g:>o@9U0U;9E9S~>
-!<C+<ZiH>AeUc8%e[a36Pf:#:PQ64~>
-!<A&V@dua8Uk,=mUtMOD@e)ebMuI/d5lcE~>
-!<AD`EUc_RTn/ngU"Q+>EUld'Q2Yb(9E9S~>
-!<C+;[.0B3Uk,=mUtMOD[.9F]`W!4FPQ64~>
-!\j\5rF5AV!+LNZJcC<$g&LT#raGpp!7cT~>
-!^m$RrGhFo!-*SiJcC<$g&LT-rc&!5!8;r~>
-!cn@\rNu18!47=WJcC<$g&LT]rj2`k!7cT~>
-!\j\5mpZ8_J`_OGJ`bYJ!/p;T!^Qh:J,~>
-!^m$Rmr8>$J`_OGJ`bYJ!1!"m!_`UJJ,~>
-!cn@\n$E(ZJ`_OGJ`bYJ!6+E6!gE]8J,~>
-"?A1:5sb$M!'u1uJ`_OGg#`9mnRDMa!W^d$J,~>
-s$Qng9MFtr!).t+J`_OGg#`:"nT"S&!W^s.J,~>
-s)S5APa(^F!0i&sJ`_OGg#`:Rn[/=\!W^d$J,~>
-">Mnk!!)LSJ\?WJJ\BaM!+PIarrE&KJ,~>
-r^?bdn4\DEJ\$EDft%0'nP&r_rn;l~>
-rcA)>n<AL;J\?WJft@BmnWa%RrmcN~>
-s#L*6!',T1JH16$[fH?VJ,~>
-r'Z)9JH16$[fH?[J,~>
-rc8*TF+F=B!.b-Z!;tAt~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.gif b/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.gif
deleted file mode 100644
index d0d6031b22..0000000000
--- a/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.png b/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.png
new file mode 100644
index 0000000000..06ff60280f
--- /dev/null
+++ b/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.ps b/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.ps
deleted file mode 100644
index 7ad54e9932..0000000000
--- a/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.ps
+++ /dev/null
@@ -1,1371 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/sim_trans_contents_viewer_mgr_actors.ps
-%%CreationDate: Mon Oct 14 17:26:33 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 406 232
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 217.359744 translate
-391.247539 -217.359744 scale
-% Image geometry
-468 260 8
-% Transformation matrix
-[ 468 0 0 260 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 468 string def
-/gstr 468 string def
-/bstr 468 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 78558 ASCII Bytes
-colorimage
-!AQV60nB=U!.b-Z!!G#:0ek\=~>
-r'Z)9JH16$[fH=oJ,~>
-"DW"!C3+q+JH16$[fH>IJ,~>
-r]0uYnc&U&JcC<$KDtqba8c/>!]_tqJ,~>
-r^?bdnc&U'JcC<$KDtqca8c/>r^;8~>
-rcA)>nc&U&JcC<$KDtqba8c/>!cr*tJ,~>
-s"OQTs8VWG!53s6J^oD'!56G0s6]pg3B;T~>
-s$Qngs8VWC!5=$8J_#J)!5?M-s6]pg6puP~>
-s)S5As8VWG!53s6J^oD'!56G0s6]pgF)uj~>
-!]^8\n(n&XJ^o>%K@Kt8`SL[8!',Q~>
-!^m%gn(IcUJ_#D'K@U%:`S(C1!(;>~>
-!cnAAn(n&XJ^o>%K@Kt8`SL[8!-<Y~>
-!\j]Tn(n&XJ^sYJ!6'N>MU_^?`SL[8!',Q~>
-!^m%gn(IcUJ_'_L!QriAer/)Z^;\e-_>luS~>
-!cnAAn(n&XJ^sYJ!6'N>MU_^?`SL[8!-<Y~>
-!<E/fh>k6dec1lieHNpfe\-<VrfmH5!J>`neH)JZJ^s>A!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/fg&Sjaf)LlgedTEhf"Q]`R?<W_eq&CHecDJYJ_'DC!5@XMpR1^.s-`i>s-`f=!NlEQ~>
-!<E/fh>k6dec1lieHNpfe\-<VrfmH5!J>`neH)JZJ^s>A!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&iRItJ^$sPQ`P(Qes-2Bj&]K+(eVedneWc<KeUr5!e]#58eH*Y&
-m*u0EHc:Qdo@3iSkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/tf)M08f)M0:ec<GVdK.4niR.bD[d_]G_RAaXs,l0d&]0+-dZ&[pcB47;dXcttd_`H+dK.4n
-m*YsDID19\o?mWQkLTBqp=B21s47.:rRM"P!.Y~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&iRItJ^$sPQ`P(Qes-2Bj&]K+(eVedneWc<KeUr5!e]#58eH*Y&
-m*u0EHc:Qdo@3iSkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/uhYiuChYiuDh>k7]eH(;LiRIs]HgoPdK6tSf"cJVqeUr5GeHLSPe^];!^"!.9HgB2_P`(+C
-o@3iSkMGs'p>5P6rS@RV!.Y~>
-!<E/uf);$8f);$9ec<GVdf4mWdf4mfdf4m;dKPJmdaE\tqpPLqs3gpu^!cq3ld>g!M1O+HdK%#E
-f(YU+f(YU2ecDoRJ,~>
-!<E/uhYiuChYiuDh>k7]eH(;LiRIs]HgoPdK6tSf"cJVqeUr5GeHLSPe^];!^"!.9HgB2_P`(+C
-o@3iSkMGs'p>5P6rS@RV!.Y~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`VS*mXG_FPMp9eRMgLA`rmh%,"hfP8[+1uOHiM%o
-MgL)`e^]S9]n:[=eYN1ks2>,!H[CCYqUHs`HbIt[XFo&UHe$ZcMgL)`eZ=,:eXV!*eXWGc`J](q
-[+3]bMl_j8eHER4^"&YPHO.lKHe$Z!He"qkHiM%nMgL)`e^]S9XGbV]Hi)@nM[R4NHaL/4HaM>R
-`K^=Js4..-!N_4UeIKQ_H[C[ie^^aZH[C[qV#G]E`N4uEMlcp.s,.;eMq,e)H[CCYe\-=CJ^sDC
-!57RPpRLp5q4.B>!NZ9O~>
-!<E/uf)1s9f)1s8ec<G]dK[RNI>+uTU&KH?_YV[gY).RTM9=8LM1(5`rmLh+"hKD=ZI5HGIK..n
-OaVqhdaF,7\qP^@d\6Ygs2"o$JUN6\qU-aZICdkTV1m?KJ^Vu`OaVqhd].`4d[>O#d[?fW_NB8#
-ZI70\NMVX5dKI.0]$d#GI0duHJ^VttJ^U7kIK..mOaVqhdaF,7V2`oSJc!mqN=31KJZcG8J[3_P
-_NFeFs3gq,!MtePdLO9ZJUNNldaG:TI=6spU&KHD_QJ`DM6?j+s,@G`NRG\+JUN6\d^FS8J^X2=
-!5@XIpR1^*q3h03!NlEQ~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`VS*mXG_FPMp9eRMgLA`rmh%,"hfP8[+1uOHiM%o
-MgL)`e^]S9]n:[=eYN1ks2>,!H[CCYqUHs`HbIt[XFo&UHe$ZcMgL)`eZ=,:eXV!*eXWGc`J](q
-[+3]bMl_j8eHER4^"&YPHO.lKHe$Z!He"qkHiM%nMgL)`e^]S9XGbV]Hi)@nM[R4NHaL/4HaM>R
-`K^=Js4..-!N_4UeIKQ_H[C[ie^^aZH[C[qV#G]E`N4uEMlcp.s,.;eMq,e)H[CCYe\-=CJ^sDC
-!57RPpRLp5q4.B>!NZ9O~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u1UjJ$,[%t[BH^)4.H`YK:K6rNHH\9S^H[EHFK7gk%
-Hc=6^H]+D@K?_A^HbI[^HaLJn^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifVP^CBo
-K6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO(P@'mS9oU@S9on5c%CYf
-c%CAfc%CA$V#&=b]r\oSH]-.EH],8<UrC<"HbH5%PeE<.XNf"BH]+]EMgMhE[(X`'H^oZ3oZ[BL
-kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/tdeB1.dK%#Zc3h^FKt<Ot`l<RX_YVP7V1"3+[]7?II?hO3IB(T<JUNBKI>,tdJUPDTJVC\#
-IE'Q`I>OYGL!I\hIDX9dIC?ku^A?,&[XFRhcAACCJUu+hJVC\#IE&jHWm6<HWm61(b(58XQ$pZt
-JUNBOrQZU\IE'RPJUPD\JUu+lJUu+dJUPDTJVC\#IE'Q`I>OfGM2D,T(P.!oTm_?KTm_X?b(58`
-c@p\lc@LD#V>AId^952YI>Q7GI>P8<WlE&0IDW"4Q+iN3Wm8n@I>OfGM1)hH[_C&,IA)5;oZdHN
-kL'?uq9f82o[<W)qpGMJ!.Y~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u1UjJ$,[%t[BH^)4.H`YK:K6rNHH\9S^H[EHFK7gk%
-Hc=6^H]+D@K?_A^HbI[^HaLJn^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifVP^CBo
-K6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO(P@'mS9oU@S9on5c%CYf
-c%CAfc%CA$V#&=b]r\oSH]-.EH],8<UrC<"HbH5%PeE<.XNf"BH]+]EMgMhE[(X`'H^oZ3oZ[BL
-kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEq98tnHc>s..t`2fc,G$^c-:lf`Q`aVc-:lfc)c8^c)c8n
-c%CA^c$Of^c%CAfc&6q=^%]bsK6tkVHc=6^Hd/X=SB\-^XNc*V`I!6%]mJ#*H^r?^H`YJEHi)%g
-P^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%nK7!=:'n^kPc$OfVc$Of^XF$J^c%CAfc%CB:bm25$
-K7hF$Hc>p-%>0#PK6tS^`I!6^c%CBBbl`lNSA"mG!IL&^c1K6\^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/sdeT=/dK%#Zc3^Y%TusNdY0MTLq9B%qIDYs..uA\ocGk9hcH^uh`m0-dcH^ulcE;Shb-$/q
-c@LD`c@LPlc@LPlcA?t?_Y;@UJKr=OIDX9\J^1EHTusNdY0MH\`dNQ/_L9S0IA+fdIBLkHIEMK5
-!L8*4cMrIqcMrIqcMrIqcMrG'cE;Shb-$/qc@LDdpWaP*IEKidIEKidJ^1QLS^,N7IEp,hIEM<0
-#K"3+L!GC#_Yh^ZJJ-7bIE'RPI>Q7pJUP\dcA?t?_Yqa\I?fB/oZdHNkL'?uq9f82o[<W)qpGMJ
-!.Y~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEq98tnHc>s..t`2fc,G$^c-:lf`Q`aVc-:lfc)c8^c)c8n
-c%CA^c$Of^c%CAfc&6q=^%]bsK6tkVHc=6^Hd/X=SB\-^XNc*V`I!6%]mJ#*H^r?^H`YJEHi)%g
-P^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%nK7!=:'n^kPc$OfVc$Of^XF$J^c%CAfc%CB:bm25$
-K7hF$Hc>p-%>0#PK6tS^`I!6^c%CBBbl`lNSA"mG!IL&^c1K6\^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!F=s*O[gs*Oais*Odj$\NfNc%CAfc%CAfV#5QQUs4O=c-:lf
-c-:lfc-=4lH[C[aq998:H`W`qc-:lfc(t8a$`)%*K<1<%K<1!UV#5QAUs4O=qoo/+HiD8#K6tkf
-K6tkfK6tkfK6tk=r-JOAc%CB:bnYkXc-:lfc-:lfc(o]^c-:lfc-:lfprs)XK7f)/K?\aiqoo7r
-Hd-narltIis31RsHiD7r`KY^rMnRB[H^'*+oZ[BLr7(e\q4%Gup=0/5q:,J8p!rl.r7(hL!.Y~>
-!<E/rdefI0dK%#Zc2a^=I06=kJV!XBs*agj!J,[ucMr=mcMrIqcMrIqcMrFrcDCGe';a!*J^2Pl
-J^2PlJ^2QXQ$n(?^A6%]SUIZ3NR#h#J^1+iI1)msOb'ZtR>%Z#cDCGe"/X:oJc!^nQ$rYWs+13q
-s+13qs+13qs+(3rV>P`DV9XXCp<N\hs3CXqs3CXq$dPSsU!Cr;IEp,hJb[Lr\qP]pI>,spIJ_=i
-JHF,JIK%OlIK.UmJc<q$_NfOtNP<]`I?fB/oZdHNr6bSVq3_5op<ir/q9f82p!WZ(r6bVK!.Y~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!F=s*O[gs*Oais*Odj$\NfNc%CAfc%CAfV#5QQUs4O=c-:lf
-c-:lfc-=4lH[C[aq998:H`W`qc-:lfc(t8a$`)%*K<1<%K<1!UV#5QAUs4O=qoo/+HiD8#K6tkf
-K6tkfK6tkfK6tk=r-JOAc%CB:bnYkXc-:lfc-:lfc(o]^c-:lfc-:lfprs)XK7f)/K?\aiqoo7r
-Hd-narltIis31RsHiD7r`KY^rMnRB[H^'*+oZ[BLr7(e\q4%Gup=0/5q:,J8p!rl.r7(hL!.Y~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!F=!eYj5rQQ+1Hc=7KH\9SfK6tkfK6tkfK6tkEH^t#Y$%mTL
-c%CAfc%CBAblbq\H\;.=%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?(8Q;rc-:lf
-c-:lfc-:lfc-:lfc)c8^r657pHhP]!K6tkfK6tkfK6tkEH^r@*H[F#^K7!C<$&a/Tc%CYnK6t<0
-bmf;Pc%CA^c,G$^c-:lfr65JcUjIa=`I",+c1K6\^&6FTSG(J5SGC\8SG(M-SGgt=X8mb~>
-!<E/qdf#U1dK%#Zc2t.sU&<49JbdRmKmg]6c5)7b`m2SPM9aCtJ^2PlJ^2PlJ^1EHU&<49JcF$q
-JcF$qJc3jr`h@g7q9BD[I>rfXcH^ulcE;Shr6>\DI>t)'I>srGY'm#AcMrImc5*+%`m2k\J^2Pl
-J^2PlJ^2PlJ^1EHU&<49JbIChJcF$qJcF$qJIBc+I@8C'JUPhhJV!UA$&sMYc@pttKmg]5cMrG'
-cA?thcGk9hcH^ulr6>PeTm_X?`dOP3cLfB^^AQFRRJ,&/RJG82RJ,)'RJkP7XoNt~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!F=!eYj5rQQ+1Hc=7KH\9SfK6tkfK6tkfK6tkEH^t#Y$%mTL
-c%CAfc%CBAblbq\H\;.=%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?(8Q;rc-:lf
-c-:lfc-:lfc-:lfc)c8^r657pHhP]!K6tkfK6tkfK6tkEH^r@*H[F#^K7!C<$&a/Tc%CYnK6t<0
-bmf;Pc%CA^c,G$^c-:lfr65JcUjIa=`I",+c1K6\^&6FTSG(J5SGC\8SG(M-SGgt=X8mb~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMqTUjuH\8E5XMq8fPeE<.XNf"BHd0ffHd0ffHaLbEH_e$M
-[*=5Mc-:lfc-:lf[*>DR]sN-Eprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51c%CB?
-boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWn.K6tkfK6tkfK6tk^H[DQHH[F#^
-K7!C<*/f0FXF#<-XF#T$]r]2tK6su$H^)4.H`YK:K7!UB$)FrA[!R_U[!TK;c1K6\^&6FTSG(J5
-SGC\8SG(M3SH%.<SGgt=X8mb~>
-!<E/pcMs1*c2bTVapZ4CIAOBTZHA#P[`83e1obtXY-t@IWdU/DQ$oLOb(5,db(5,db)(PT_M*E7
-[]ZpYJUttdJUttdM1)hPTsDD<I>RaA,DCPo`lcGTJ]budIAOBTZHBV(IC?_8IC@;<Kmff+Y-Q3$
-Jc!S1\p^a(b(5,db(5,db(5,db)(PT_M*E7[]ZpYJV!gCs,$Wqs+13ms+13ms+(R#_L6j+M1'fp
-b(5-=arH7dWiCJq^8cU8Y-t@Ib)(PTV1"W?Q$oLOb(5-CapFcI^9W0Db-$0$J]dW-!5ABVpQbHt
-!1!B*!1!9'rK[E.rK[?,!NlEQ~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMqTUjuH\8E5XMq8fPeE<.XNf"BHd0ffHd0ffHaLbEH_e$M
-[*=5Mc-:lfc-:lf[*>DR]sN-Eprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51c%CB?
-boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWn.K6tkfK6tkfK6tk^H[DQHH[F#^
-K7!C<*/f0FXF#<-XF#T$]r]2tK6su$H^)4.H`YK:K7!UB$)FrA[!R_U[!TK;c1K6\^&6FTSG(J5
-SGC\8SG(M3SH%.<SGgt=X8mb~>
-!<E/feH!;[bmMFSH[CCHc*W+M^&#t]XG_FPMoErBK6r6Prll^@Hd0ffHd0gBK6t;NP^@b0XNcBE
-c-:lfc-<VJHbGYrH[D!rprrl9H^+NS&VGGTc,GooH\8EEc$Of^c$Og:bm;:QH[CCHc%CB>c2W_%
-bnu([c-:lfc-:lfc-<VJHbIC_H[CCHc%CBBblNHDqook.Hd0ffHd0ffHd0g:K7gO`Hd0ffHhbi%
-["E^qUjJWVXG_FPMoErJK6t;5K6r6PrlkIrHiD7qP_4=0Pf:n*Mh0.EblGHTeH!;YS,g7reb>U,
-ec20<ec20;eH)`OJ,~>
-!<E/fc2bTUapQ"NJUN6Tb-HSL])'PWWel.PM8%-/KmeZTrlY7ls2t@ms2l=eJUtDLQ%=@;Y0)<H
-b0#9db0%#@J\%+tI=[ZtprWZ3I?FNOs+13m)8_YiI>+iH`dN9Xb'e]Xb0%SdJUN6Tb(5-?b5[J$
-b5[%mb5[%mb5[%mapbS,J\&^`JUN6Tb(5-Cb5[%ib5[%mb5[%mb5[%mapG5%KsHD`b0#9dprXD]
-KmfMcI@86XM1'f/^<3a4J\%\3I>+^#b5[%lap=8`I=[Ztb)MC3b4EaU^AQ7V[eZ0g[eA#@Q1`H&
-Q2T#.Q2Jo.XoNt~>
-!<E/feH!;[bmMFSH[CCHc*W+M^&#t]XG_FPMoErBK6r6Prll^@Hd0ffHd0gBK6t;NP^@b0XNcBE
-c-:lfc-<VJHbGYrH[D!rprrl9H^+NS&VGGTc,GooH\8EEc$Of^c$Og:bm;:QH[CCHc%CB>c2W_%
-bnu([c-:lfc-:lfc-<VJHbIC_H[CCHc%CBBblNHDqook.Hd0ffHd0ffHd0g:K7gO`Hd0ffHhbi%
-["E^qUjJWVXG_FPMoErJK6t;5K6r6PrlkIrHiD7qP_4=0Pf:n*Mh0.EblGHTeH!;YS,g7reb>U,
-ec20<ec20;eH)`OJ,~>
-!<E/feH!;Qc2)be^!4guHN:b0blYk:XN\oiH\;4?qKi4Ugs#o%K>iDdo?@9K`74mi!.Y~>
-!<E/fc2bTKb5-Md]$8CoI/pk/ao]G2V9R-a`dNR<b5-Md]%kF0We&$<b4EaU^;S:tXoNt~>
-!<E/feH!;Qc2)be^!4guHN:b0blYk:XN\oiH\;4?qKi4Ugs#o%K>iDdo?@9K`74mi!.Y~>
-!<E/fblGG.`<+#lUs[-c[$7AfMgLu>`;udJJ]73!!56=q!NZ9O~>
-!<E/faoK/,`WF/oU!^ja[ZRSiNI@MG`W;dIJ]@9#!5?Co!NlEQ~>
-!<E/fblGG.`<+#lUs[-c[$7AfMgLu>`;udJJ]73!!56=q!NZ9O~>
-!<E/fblGG.`QlF+]p+.rK;=(;]Ysla`6A=a!.Y~>
-!<E/faoK/,`m2R-^6*tpKqX(;]Z'rc`6&+`!.Y~>
-!<E/fblGG.`QlF+]p+.rK;=(;]Ysla`6A=a!.Y~>
-!<E/fblGG.`IZ!\`;mTiblOmGJ,~>
-!<E/faoK/,`du-^`W3`kaoSXFJ,~>
-!<E/fblGG.`IZ!\`;mTiblOmGJ,~>
-!!%S&JV/N+YCcfTJ,~>
-!!%S$JUrB'YCQZRJ,~>
-!!%S&JV/N+YCcfTJ,~>
-!<E0!joD3.s+13$s1/.5V#TT>]`<Q~>
-!<E0!joD*+s+13$s1/.5U&X9;\c@6~>
-!<E0!joD3.s+13$s1/.5V#TT>]`<Q~>
-!<E0!joD3.s+13$s1847K;AP0k.LbF~>
-!<E0!joD*+s+13$s1847JYE,+k.1PC~>
-!<E0!joD3.s+13$s1847K;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:8G>!<1^P!!:jS!;tRN!:/A:!9Mr7!:SY;!!_-W!8?-,!.ijTg<\LQ
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:8G>!<1^P!;Y@K!:8G>!<1^P!9W#8!:SYA!;bFL!<:dQ!.ijTg<\LQ
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[Oe`,-Z
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*o%O*Drn@APs4[DO
-rn@;Ns4[JQ"53_TgAM$OgA_-Sg&M-DgA_0OgA_-Tg&M-,r;clOr;clOrr</T!!(aO!.ijTg>^id
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[Oe`,-Z
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%j440^"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)TDrW)oN
-rrE)Qrr<;X!!(a,!!(aL!<:dQ!!(aP!!:jS!;"qE!<(XO!"[c`!8?-,!8?-,!8?-,!8@8Ls4[JQ
-J_G\/j4aNa"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%j440^"f21\k.LbF~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc9/ec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA1d\g&M-,!!(a,!!(^Q!8?-,!:\_A!<:dQ!<:dQ
-!;tRN!!(aP!<:dQ!;tRN!<:dQ!;"qB!#!uc!87DQg=cN,g=cN,g=cN,gAV*PgAV)'g4@u9gAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc9/ec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^rc1s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo@j3Ern@AP$JGI[g&M-,g&M-,qZ-*=rVurPqZ-ZMqu?fP
-!!*#PrrDuNrrE)QrrDZErrE#Orr<>Y!!(a,!!(a,qZ$]O!!)rNrW%N'J_K,;s+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^rc1s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^rf2s+:KN
-s5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQn(RdArn@AP%,([]g&M-,g&M-,!!)KArrE&Prr<,S!!)rN
-rrE)Qrr<,S!!*#PrrDuNrrE)QrrDZErrE#Orr<D[!!(a,!!(a,!!)rNrrDrMrW%N'J_K/<s+(?I
-s5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^rf2s+:KN
-s5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc92ec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)WErrE&P
-rr<Va!!(a,!!(^Q!8?-,!87DQrn@APs4[JQ#20%Wg=cN,o@j3ErS%8O#MK.Xg=cN,gAV*PgA_-S
-g&M-PgA_0QgA_/(g4@u<gAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc92ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%imn']"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*n_3m@rn@;Nrn@>O
-!8@AOrS%2Ms4[JQs4[JQo@j3ErS%8O!nmVSrn@APs4[DOs4[JQrS%2MJ_G\/inFE`"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%imn']"f21\k.LbF~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD3.eUc8%e]lY4K*Kl%s5rIW!.Y~>
-!<E0!joD*+g4@t/g<J@>JHji%s5rIT!.Y~>
-!<E0!joD3.eUc8%e]lY4K*Kl%s5rIW!.Y~>
-!<E0!joV@/eU_IdC4U-JCAucPK*VG,V#TT>]`<Q~>
-!<E0!joV71g4=g+JUrC#Jc=BlJHu5/U&X9;\c@6~>
-!<E0!joV@/eU`X0Mh-f7MuM8qK*VG,V#TT>]`<Q~>
-!<E0!joV@/eU_IdC4U-KC&m]$ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!joV71g4=g+JUrC$JH5`LgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!joV@/eU`X0Mh-f8MZEeVec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:bs+1$`s8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*Cbs8RZI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXT#=$!;rqs!.h5&XQ6J_mf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gA]h+!;tRL!.ijTg>pufs8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k5ONC!;u!X!.j9`k2b\)s8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gPsq>gMrrW)hsquHbuquHAjquHYrq>^MsrW)r!rVur"q>^MsquGr^
-!W];%rN#u!rN#u!JZOF(jfJLMrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/qZ-TKq>gQLq>gNKrW)iLquHcNquHBCquHZKq>^NLrW)rOrVurPq>^NLquGs7
-!W^pSrRq5OrRq5OJ_G\/jkBb7rn@C'rPJU7s4[L(r5/L6#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JqZ-TWq>gQXq>gNWrW)iXquHcZquHBOquHZWq>^NXrW)r[rVur\q>^NXquGsC
-!W_?_rT4([rT4([J`_OGjlZUCrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!#lq'.!3E7%XK2F"X8i7rX8i7tX8i7iX8i7rX8i8!X9/I(
-X8r1"!!*#"!!)u!!!*#"!!)/_!W];%rN#u!rN#u!JZOF(jfJLMrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO#lr]5!8?-,g=cQ)g&M-Kg&M-Mg&M-Bg&M-Kg&M-Og&h?/
-g&V')!!*#P!!)uO!!*#P!!)08!W^pSrRq5OrRq5OJ_G\/jkBb7rn@C'rPJU7rn@C'rPJU7#25dN
-k2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[#ls,M!9WDDk2l[Ajo>DWjo>DYjo>DNjo>DWjo>D[joYVG
-joG>A!!*#\!!)u[!!*#\!!)0D!W_?_rT4([rT4([J`_OGjlZUCrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!#lq'.!3E7%XK2F#X9&C'!;`bs!;iht!:[&i!;W\r!<&u$
-!3E7%r2]kuri?)"rN#u!ri?)"poOJqnuMonXK2F#X8i8!X8i6OXF[J7XT._fec1:$^&S-2ec1:#
-^&S*:eYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO#lr]5!8?-,g=cQ*g&_9.!;bCL!;kIM!:\\B!;Y=K!<(UR
-!8?-,r7V,Nrn7>PrRq5Orn7>PptG`Jo%F0Gg=cQ*g&M-Og&M,(g4@u>gAh3PgAca'_Z0Z7gAca&
-_Z0W?g7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[#ls,M!9WDDk2l[BjoPPF!;bgX!;kmY!:]+N!;YaW!<)$^
-!9WDDr8mtZroO1\rT4([roO1\pu_SVo&^#Sk2l[Bjo>D[jo>C4k(2[Vk5YJ\ec1:$^&S-2ec1:#
-^&S*:eYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;`bu!3?1sX8i7tX8i7iX8i7rX9/I(X8r1"!!*#"
-!!)u!!s#F(!;rnu!;NYq!:m2n!3E7%rN#u!rN#u!JZOF(jfJLMrmh%$rk8@3r71h"rk8@3#1]OL
-k2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;bCN!87GLg&M-Mg&M-Bg&M-Kg&h?/g&V')!!*#P
-!!)uO!s%'/!;tON!;P:J!:nhG!8?-,rRq5OrRq5OJ_G\/jkBb7rn@C'rke^8r7_1%rke^8#25dN
-k2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;bgZ!9O:Xjo>DYjo>DNjo>DWjoYVGjoG>A!!*#\
-!!)u[!s%KG!;tsZ!;P^V!:o7S!9WDDrT4([rT4([J`_OGjlZUCrmh%$rk8@3r71h"rk8@3#1]OL
-k2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"r;c\q!!)nt!!*#"!!)nt!!)nt!!)Mi!!)hrr;cbs!!*#"!!)u!
-r;cbs!!)5a!!*#"!!)u!!!)u!!!%SOJZRt7s6fm:s+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V')!!*#Pr;c]J!!)oM!!*#P!!)oM!!)oM!!)NB!!)iKr;ccL!!*#P!!)uO
-r;ccL!!)6:!!*#P!!)uO!!)uO!!%T(J_K5>s8W)Ps+13es8VuMs+10ds8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG>A!!*#\r;c]V!!)oY!!*#\!!)oY!!)oY!!)NN!!)iWr;ccX!!*#\!!)u[
-r;ccX!!)6F!!*#\!!)u[!!)u[!!%T4J`c(Vs8W)Ks+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;ikq!;iht!;iht!<&u!!;3Dn!<&u!!<0&%!3E7%
-qlBi!X8r1"!s#F(!;rnu!<&u!!:?if!<0&"!<&u!!<&u!!.h5&XQ?P`mf(c:KE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;kLJ!;kIM!;kIM!<(UO!;5%G!<(UO!<1[S!8?-,
-qq;)Og&V')!s%'/!;tON!<(UO!:AJ?!<1[P!<(UO!<(UO!.ijTg?%&gs8LaPJcEUes8(ILJcEUe
-rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;kpV!;kmY!;kmY!<)$[!;5IS!<)$[!<2*_!9WDD
-qrRq[joG>A!s%KG!;tsZ!<)$[!:AnK!<2*\!<)$[!<)$[!.j9`k2kb*s8LRKKE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)u!!W];%r2]kurN#u!ri?)"rN#u!mB$0bri?)"rN#u!JZOF(jfJLMrmh%$!knX6q:5Lt
-s1SI4#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)uO!W^pSr7V,NrRq5Orn7>PrRq5OmFqF;rn7>PrRq5OJ_G\/jkBb7rn@C'!lG!;q:bk"
-s2+g9#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)u[!W_?_r8mtZrT4([roO1\rT4([mH49GroO1\rT4([J`_OGjlZUCrmh%$!knX6q:5Lt
-s1SI4#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)qu!!)nt!!)u!!!*#"!!)u!!!)u!rrDMh!!)u!!!)u!!!%SOJZRt7s6fm:s+:Bds8VlE
-s+:Wks8UWFs5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)rN!!)oM!!)uO!!*#P!!)uO!!)uOrrDNA!!)uO!!)uO!!%T(J_K5>s8W)Ps+(6gs8VlJ
-s+(Kns8UfHs5rIT!.Y~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)rZ!!)oY!!)u[!!*#\!!)u[!!)u[rrDNM!!)u[!!)u[!!%T4J`c(Vs8W)Ks+:Bds8VlE
-s+:Wks8UWFs5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gMrquHbur;Zi!r;cl!quHbuq#L/jq#LGrq>gGp!!)quq>^Msq#LAp
-rrDPirW)nur;_DMJZRq6s6fm:s+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!joqI4g4=h/qZ-TKq>gNKquHcNr;ZiOr;clOquHcNq#L0Cq#LHKq>gHI!!)rNq>^NLq#LBI
-rrDQBrW)oNr;_E&J_K2=s8W)Ps+14MommFds8UfHs5rIT!.Y~>
-!<E0!joqR2eVf@JqZ-TWq>gNWquHcZr;Zi[r;cl[quHcZq#L0Oq#LHWq>gHU!!)rZq>^NXq#LBU
-rrDQNrW)oZr;_E2J`c%Us8W)Ks+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCf*LKE(u%V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb/mJJcGc(U&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCf*LKE(u%V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXO4*L!;NYq!.h57XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g<nUS!;P:J!.ijegAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k0`;k!;P^V!.j9qk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqR2eS8j#quHVqrW)ktqZ-Vsq>^MsquDJQ!!)bp!!)bp!!%SOP-"]Ormh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/quHWJrW)lMqZ-WLq>^NLquDK*!!)cI!!)cI!!%T(P1os9rn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JquHWVrW)lYqZ-WXq>^NXquDK6!!)cU!!)cU!!%T4P32fErmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7pX8i7tX8i8!X8i8"X8i8!X8i8"X8i6RX8i7eX8i6OXHK[bmf(c:KE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Ig&M-Mg&M-Og&M-Pg&M-Og&M-Pg&M,+g&M->g&M,(g611is8LaPJcGcD
-gAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DUjo>DYjo>D[jo>D\jo>D[jo>D\jo>C7jo>DJjo>C4k*"m,s8LRKKE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&"!<&u!!<0&"!;NYq!4Ap.!!',"!;iks!<0)!
-!<0)!!;ESm!;rqt!;iks!!0/$JZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[P!<(UO!<1[P!;P:J!4CP\!!(aP!;kLL!<1^O
-!<1^O!;G4F!;tRM!;kLL!!1dRJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*\!<)$[!<2*\!;P^V!4Cth!!)0\!;kpX!<2-[
-!<2-[!;GXR!;u!Y!;kpX!!23^J``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&%!3E7%r2]kupoOJq[&j9-ri?)"rN#u!ri?)"
-ri?)"r2]kuorJ,npT+>pr2]kuriH,"JZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[S!8?-,r7V,NptG`J[+bN[rn7>PrRq5Orn7>P
-rn7>Pr7V,Np"BBGpY#TIr7V,Nrn@APJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*_!9WDDr8mtZpu_SV[-%AgroO1\rT4([roO1\
-roO1\r8mtZp#Z5SpZ;GUr8mtZroX4\J``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7rX8i8"X8i8!XS`(sXSi.sX8i7"X8i8!X8i8"X8i7uX9em.X8o?'!3E7%
-orJ,npT+>prN#u!r2]kuJZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Kg&M-Pg&M-OgACsLgAM$Lg&M,Pg&M-Og&M-Pg&M-Ng'Ic5g&Tj\!8?-,
-p"BBGpY#TIrRq5Or7V,NJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DWjo>D\jo>D[k555Xk5>;Xjo>C\jo>D[jo>D\jo>DZjp;%MjoFQ+!9WDD
-p#Z5SpZ;GUrT4([r8mtZJ``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8"XS`(sX8i8!X8i8"X9/I(X8r1"!!)u!!!'1'!!)u!!!*#"q>gPs
-"ota+!3E7%orJ,npT+>prN#u!r2]kuJZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-PgACsLg&M-Og&M-Pg&h?/g&V')!!)uO!!'1U!!)uO!!*#Pq>gQL
-"p!B2!8?-,p"BBGpY#TIrRq5Or7V,NJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\k555Xjo>D[jo>D\joYVGjoG>A!!)u[!!'1a!!)u[!!*#\q>gQX
-"p!fJ!9WDDp#Z5SpZ;GUrT4([r8mtZJ``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!'1'!!)u!!!*#"
-!!)eq"9>M'X8qmo!!)bp!!)u!!!)qu!!%SOP-"]Ormh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!'1U!!)uO!!*#P
-!!)fJ"9@-Ug&Ud!!!)cI!!)uO!!)rN!!%T(P1os9rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!'1a!!)u[!!*#\
-!!)fV"9@QajoG&9!!)cU!!)u[!!)rZ!!%T4P32fErmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)u!rrBF-!!)u!
-!!)u!!!)u!!!*#"rr<,%!!)Ym!!*#"!!)nt!!)qu!!*#"rr@VOP-"]Ormh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)uOrrBF[!!)uO
-!!)uO!!)uO!!*#Prr<,S!!)ZF!!*#P!!)oM!!)rN!!*#Prr@W(P1os9rn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)u[rrBFg!!)u[
-!!)u[!!)u[!!*#\rr<,_!!)ZR!!*#\!!)oY!!)rZ!!*#\rr@W4P32fErmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!joqR2eS8j#q#CDrr;Zi!r;Zi!qZ-Vsq>^Msq#LAprrBI.rW)u"rW)nur;cetrr<,%!!)Vl
-rW)ktquH\srW!#$!!%SOPH=fPrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/q#CEKr;ZiOr;ZiOqZ-WLq>^NLq#LBIrrBI\rW)uPrW)oNr;cfMrr<,S!!)WE
-rW)lMquH]LrW!#R!!%T(PM6':rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!joqR2eVf@Jq#CEWr;Zi[r;Zi[qZ-WXq>^NXq#LBUrrBIhrW)u\rW)oZr;cfYrr<,_!!)WQ
-rW)lYquH]XrW!#^!!%T4PNMoFrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXQQ\[!.h5&XSJstmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g?72b!.ijTgA0J&s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k3(n%!.j9`k5"0>s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMnsXSW"qXSi.uXSr5!XSr3rX8i6OXF[J*XT._fec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!jp%O5g4=h/gA1dLgA:mJgAM$NgAV*OgAV)Kg&M,(g4@u1gAh3PgAca(s7Y1HJcG`Sg7eQ/
-k.1PC~>
-!<E0!jp%X3eVf@Jk5#&Xk5,/Vk5>;Zk5GA[k5G@Wjo>C4k(2[Ik5YJ\ec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!)u!!!*#"rrE&"rrAjr!!%SOJZRM*s6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!)uO!!*#PrrE&PrrAkK!!%T(J_Jc1s8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!)u[!!*#\rrE&\rrAkW!!%T4J`bVIs8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!s#F(!;ii%!3E7%X8o@$!<'#!!3<4!!<'#!!<9/#!<'"t
-!<0)"!!',"!;rqr!;<Mo!!TG(!3?/#riH)!$EO4-XK2C%XK2C%JZPZKs6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!s%'/!;kIS!8?-,g&Tk+!<(XO!3=iO!<(XO!<:dQ!<(XM
-!<1^P!!(aP!;tRK!;>.H!!V'V!87DQrn@>O$JGI[g=cN,g=cN,J_HpRs8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!s%KG!;km_!9WDDjoFQC!<)'[!3>8[!<)'[!<;3]!<)'Y
-!<2-\!!)0\!;u!W!;>RT!!VKb!9O7]roX1[$K_<gk2lXDk2lXDJ``cjs8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johL1eS8juX9/I(X8r4#!!)u!!s#F(!;ii(!3E7%X8o=%X8r4#rrB(#!!)hr#QUq+XK2E'
-X8r4#!!*#"rrE&"!!*#"!!)u!!!)\nrr<;*!!')#XK2F$XT&;!X9AU*!3E7%JZP]Ls6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&h?/g&V**!!)uO!s%'/!;kIV!8?-,g&Th,g&V**rrB(Q!!)iK#QWQYg=cP\
-g&V**!!*#PrrE&P!!*#P!!)uO!!)]Grr<;X!!(^Qg=cQ+gA_0Og'%K1!8?-,J_HsSs8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjoYVGjoGAB!!)u[!s%KG!;kmb!9WDDjoFNDjoGABrrB(]!!)iW#QWuek2l[+
-joGAB!!*#\rrE&\!!*#\!!)u[!!)]Srr<;d!!)-]k2l[Ck5PG[jokbI!9WDDJ``fks8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXSi.tX8i8"X8i8"X8i7tX9em.X8o?'!3E7%UoXOrq5jSrp8e5ori?)"rN#u!
-ri?)"n>llqXK2E'X8o=%r2]kurN-#!JZPQHs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSgAM$Mg&M-Pg&M-Pg&M-Mg'Ic5g&Tj\!8?-,UtPeKq:biKp=]KHrn7>PrRq5O
-rn7>PnCe-Jg=cP\g&Th,r7V,NrS%8OJ_HgOs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bk5>;Yjo>D\jo>D\jo>DYjp;%MjoFQ+!9WDDUuhXWq<%\Wp>u>TroO1\rT4([
-roO1\nE'uVk2l[+joFNDr8mtZrT=+[J``Zgs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX9/I(X8r4#r;cet!!)nt#lq'.!3E7%XK2DtX8i7rX8i7rXS`(tX8i8!X8i8!
-XSi.kX9\g-X8o?'!3?1uX8i8!X8i6OXIuZpmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&h?/g&V**r;cfM!!)oM#lr]5!8?-,g=cP&g&M-Kg&M-KgACsMg&M-Og&M-O
-gAM$Dg'@]4g&Tj\!87GNg&M-Og&M,(g7[1"s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjoYVGjoGABr;cfY!!)oY#ls,M!9WDDk2lZ>jo>DWjo>DWk555Yjo>D[jo>D[
-k5>;Pjp1tLjoFQ+!9O:Zjo>D[jo>C4k+Ll:s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7sX8i8"X8i8"X8i7tX9/I(X8r1"!!&gr!!)hr!!)ks!!)u!!!*#"!!)u!
-!!)hr!!)\n#QUs-!3E7%X8r1"!!)u!!!%SOTWJ1]rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Lg&M-Pg&M-Pg&M-Mg&h?/g&V')!!&hK!!)iK!!)lL!!)uO!!*#P!!)uO
-!!)iK!!)]G#QWT4!8?-,g&V')!!)uO!!%T(T\BGGrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>DXjo>D\jo>D\jo>DYjoYVGjoG>A!!&hW!!)iW!!)lX!!)u[!!*#\!!)u[
-!!)iW!!)]S#QX#L!9WDDjoG>A!!)u[!!%T4T]Z:Srmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7sX8i8!X8i8"X8i8!X8i8"X8i7uX8i8!XT&:#X8i8"X8i8!X8i7sX8i8"
-XT&;"X8i8!X8i8"X8i8!X8i7nX9em.X8o?'!3E7%riH,"rN#u!JZPNGs6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Lg&M-Og&M-Pg&M-Og&M-Pg&M-Ng&M-OgA_/Qg&M-Pg&M-Og&M-Lg&M-P
-gA_0Pg&M-Og&M-Pg&M-Og&M-Gg'Ic5g&Tj\!8?-,rn@APrRq5OJ_HdNs8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!johL1eVf@bjo>DXjo>D[jo>D\jo>D[jo>D\jo>DZjo>D[k5PF]jo>D\jo>D[jo>DXjo>D\
-k5PG\jo>D[jo>D\jo>D[jo>DSjp;%MjoFQ+!9WDDroX4\rT4([J``Wfs8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!jp%X3eS8j#XSi.tXSr4uX8i8"XSi.uXSr5!XSr5!XT&:"XSr4uXSi.rXSr2%X8i7%rW)u"
-rW)u"quHDkrW!2)!!')#!3E:$!!0/$riH%uJZPTIs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp%O5g4=h/gAM$MgAV*Ng&M-PgAM$NgAV*OgAV*OgA_/PgAV*NgAM$KgAV'Sg&M-,rW)uP
-rW)uPquHEDrW!2W!!(^Q!8?0+!!1dRrn@;NJ_HjPs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp%X3eVf@Jk5>;Yk5GAZjo>D\k5>;Zk5GA[k5GA[k5PF\k5GAZk5>;Wk5G>_jo>DDrW)u\
-rW)u\quHEPrW!2c!!)-]!9WGC!!23^roX.ZJ``]hs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXM(\8!.h5@XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g:c2?!.ijngAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k.TmW!.j:%k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXM1b9!.h5?XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g:l8@!.ijmgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k.]sX!.j:$k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXOXEI!;ESn!.h5>XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g==pP!;G4G!.ijlgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k1/Vh!;GXS!.j:#k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXPU&Y!.h5&XS]+!mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g>:Q`!.ijTgABV(s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k2,8#!.j9`k54<@s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMqrXSi-MXR3(h!:R#g!;iks!.h5>XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1gKgAM#&g?mSo!:SY@!;kLL!.ijlgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#)Wk5>:2k3_:2!:T(L!;kpX!.j:#k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i6OXR<.i!:?if!;W\r!.h5>XT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M,(g@!Yp!:AJ?!;Y=K!.ijlgAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>C4k3h@3!:AnK!;YaW!.j:#k5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!jq"9<eS8j#X8o?'!3E7%X8r.!!!)u!rrALhrr<8)!!')#!3H/"s/c2"orS&kri?,#XSr4s
-XSr4rX8i7rX8i6OXI60imf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jq"0>g4=h/g&Tj\!8?-,g&V$(!!)uOrrAMArr<8W!!(^Q!8@DPs4[GPp"K<Drn7AQgAV*L
-gAV*Kg&M-Kg&M,(g6p[ps8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jq"9<eVf@JjoFQ+!9WDDjoG;@!!)u[rrAMMrr<8c!!)-]!9X7\s5s:\p#c/ProO4]k5GAX
-k5GAWjo>DWjo>C4k*bB3s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i8!XT&9gXT&8*X8i7%!3E7%rN#u!orJ,nrN#u!riH,"ri?)"
-rN#u!ri?)"qlBbtq5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M-OgA_/@gA_-Xg&M-,!8?-,rRq5Op"BBGrRq5Orn@APrn7>P
-rRq5Orn7>Pqq;#Mq:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>D[k5PFLk5PDdjo>DD!9WDDrT4([p#Z5SrT4([roX4\roO1\
-rT4([roO1\qrRkYq;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9em.X8o?'!3E7%rN#u!orJ,nq5aPrrN#u!ri?)"r2]ku
-r2]kuq5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'Ic5g&Tj\!8?-,rRq5Op"BBGq:YfKrRq5Orn7>Pr7V,N
-r7V,Nq:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjp;%MjoFQ+!9WDDrT4([p#Z5Sq;qYWrT4([roO1\r8mtZ
-r8mtZq;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9J[+X8o?'!<0&%!3E7%o;qljrN#u!rN#u!riGqrr2]ku
-q5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'.Q2g&Tj\!<1[S!8?-,o@j-CrRq5OrRq5Orn@2Kr7V,N
-q:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjothJjoFQ+!<2*_!9WDDoB,uOrT4([rT4([roX%Wr8mtZ
-q;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9J[+X8o?'!<0&%!3E7%n#QKhri?)"rN#u!ri?)"p8e5o
-q5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'.Q2g&Tj\!<1[S!8?-,n(IaArn7>PrRq5Orn7>Pp=]KH
-q:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjothJjoFQ+!<2*_!9WDDn)aTMroO1\rT4([roO1\p>u>T
-q;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i7uXT&9gX9J[+X8o?'!<'#!!;!8l!<&u!!<0&"!<&u!!<&u!
-!<&u!!;rnu!;W\r!.h5>XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-NgA_/@g'.Q2g&Tj\!<(XO!;"nE!<(UO!<1[P!<(UO!<(UO
-!<(UO!;tON!;Y=K!.ijlgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>DZk5PFLjothJjoFQ+!<)'[!;#=Q!<)$[!<2*\!<)$[!<)$[
-!<)$[!;tsZ!;YaW!.j:#k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juXS`(sXSi.rXT&9hXSr2'X8i7%!!)u!!!)VlquH_trW)u"rW)nur;cetquH\s
-quD;LS#lYXrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSgACsLgAM$KgA_/AgAV'Ug&M-,!!)uO!!)WEquH`MrW)uPrW)oNr;cfMquH]L
-quD<%S(doBrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bk555Xk5>;Wk5PFMk5G>ajo>DD!!)u[!!)WQquH`YrW)u\rW)oZr;cfYquH]X
-quD<1S*'bNrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXS/^q!.h5&XQ$>]mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g@j5#!.ijTg>^ids8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4[p;!.j9`k2PP's8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXS/^q!.h5&XQ$>]mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g@j5#!.ijTg>^ids8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4[p;!.j9`k2PP's8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXSAmq!<'"o!.h5&XRN=kmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gA'D#!<(XH!.ijTg@3hrs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4n*;!<)'T!.j9`k4%O5s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMX8o@#!;rqs!;rqs!;rqs!:m2k!;`eq!:m2k!;NYq!:m2k!;NYq!;!;j!<'"r
-!:m5k!;rqt!:m5i!;iks!;iht!;W_q!;rqs!;rqs!5,E5mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g&Tk*!;tRL!;tRL!;tRL!:nhD!;bFJ!:nhD!;P:J!:nhD!;P:J!;"qC!<(XK
-!:nkD!;tRM!:nkB!;kLL!;kIM!;Y@J!;tRL!;tRL!5.%cs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:joFQB!;u!X!;u!X!;u!X!:o7P!;bjV!:o7P!;P^V!:o7P!;P^V!;#@O!<)'W
-!:o:P!;u!Y!:o:N!;kpX!;kmY!;YdV!;u!X!;u!X!5.Ios8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSW"rXSr4uXSW"qXSr2#X8r7$q>^MsqZ+%*!!)u!!!*#"!!)u!!!*#"!!)u!
-!!*#"!!)u!!!)YmrrDqt!!)u!!!)YmrrDkr!W];%o;qrlq5aVtX8qmo!!)u!!!*#"!!)u!!!)Vl
-!W];%rN#u!ri?)"oW/#mrN#u!rN#u!q5jSrqQ'YsqQ'YsrN#u!ri?)"rN#u!]r_8%rmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gA:mKgAV*NgA:mJgAV'Qg&V-+q>^NLqZ+%X!!)uO!!*#P!!)uO!!*#P!!)uO
-!!*#P!!)uO!!)ZFrrDrM!!)uO!!)ZFrrDlK!W^pSo@j3Eq:YlMg&Ud!!!)uO!!*#P!!)uO!!)WE
-!W^pSrRq5Orn7>Po\'9FrRq5OrRq5Oq:biKqUtoLqUtoLrRq5Orn7>PrRq5O^"WMdrn@C's8VfH
-s+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5,/Wk5GAZk5,/Vk5G>]joGDCq>^NXqZ+%d!!)u[!!*#\!!)u[!!*#\!!)u[
-!!*#\!!)u[!!)ZRrrDrY!!)u[!!)ZRrrDlW!W_?_oB-&Qq;q_YjoG&9!!)u[!!*#\!!)u[!!)WQ
-!W_?_rT4([roO1\o]?,RrT4([rT4([q<%\WqW7bXqW7bXrT4([roO1\rT4([^#o@prmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i7uX8i7uX8i8!X8i8"X8i8"XT&;!X8i8!X9/I(X8r4#!!'I/!!)u!
-!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)\n!W];%qlBbtrN#u!orJ2pX8r't!W];%oW/)oX8r't
-!W];%oW/#mrN#u!q5aPro;hunX8r4#!!)u!!!)\n!!)u!!!*#"!!)hr!W];%qlBbtq5aPrrN#u!
-ri?)"rN#u!]r_8%rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&M-Ng&M-Ng&M-Og&M-Pg&M-PgA_0Og&M-Og&h?/g&V**!!'I]!!)uO
-!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)]G!W^pSqq;#MrRq5Op"BHIg&Us&!W^pSo\'?Hg&Us&
-!W^pSo\'9FrRq5Oq:YfKo@a6Gg&V**!!)uO!!)]G!!)uO!!*#P!!)iK!W^pSqq;#Mq:YfKrRq5O
-rn7>PrRq5O^"WMdrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[jo>DZjo>DZjo>D[jo>D\jo>D\k5PG[jo>D[joYVGjoGAB!!'Ii!!)u[
-!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)]S!W_?_qrRkYrT4([p#Z;UjoG5>!W_?_o]?2TjoG5>
-!W_?_o]?,RrT4([q;qYWoB$)SjoGAB!!)u[!!)]S!!)u[!!*#\!!)iW!W_?_qrRkYq;qYWrT4([
-roO1\rT4([^#o@prmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!<&u!!<&u!!<&u$!3E7%r2]kurN-#!
-\?#Z1ri?)"rN#u!ri?)"rN#u!q5aPro;holqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8q^j
-!!)ks!!)Vl!s#F(!<&u!!<&u!!:[&i!<0&"!;EPp!;iht!;*>m!;W\r!55K6mf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!<(UO!<(UO!<(UR!8?-,r7V,NrS%8O
-\Cpo_rn7>PrRq5Orn7>PrRq5Oq:YfKo@a0Eqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UTq
-!!)lL!!)WE!s%'/!<(UO!<(UO!:\\B!<1[P!;G1I!;kIM!;+tF!;Y=K!57+ds8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!<)$[!<)$[!<)$^!9WDDr8mtZrT=+[
-\E3bkroO1\rT4([roO1\rT4([q;qYWoB$#QqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFl4
-!!)lX!!)WQ!s%KG!<)$[!<)$[!:]+N!<2*\!;GUU!;kmY!;,CR!;YaW!57Ops8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!;NVt!3E7%rN#u!r2]kurN-#!\Z>c2
-rN#u!rN#u!ri?)"rN#u!qQ'YsnuMfkqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8qak!!)hr
-!!)Vl!s#F(!<&u!!<0)"!:d,j!<&u"!3H/"qlBbtqlBeuXSr4qX8i7rX8i75XT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!;P7M!8?-,rRq5Or7V,NrS%8O\_7#`
-rRq5OrRq5Orn7>PrRq5OqUtoLo%F'Dqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UWr!!)iK
-!!)WE!s%'/!<(UO!<1^P!:ebC!<(UP!8@DPqq;#Mqq;&NgAV*Jg&M-Kg&M,cgAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!;P[Y!9WDDrT4([r8mtZrT=+[\`Nkl
-rT4([rT4([roO1\rT4([qW7bXo&]oPqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFo5!!)iW
-!!)WQ!s%KG!<)$[!<2-\!:f1O!<)$\!9X7\qrRkYqrRnZk5GAVjo>DWjo>Cok5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X8i8"X8i8"X8i8"X8i8"X8i7uXSi.sXSi.tX8i7uX8i7-X8i7uX8i8!
-X8i8"X8i8!X8i7tX8i7uXSW"qX8i7tX8i8!X8i8"XSW"qX8i7tX8i8"X8i7kX8i7tX8i8"X8i7j
-X8i7qX8i7mX8i8"X8i7uXSr2#X8qgm!!)qurrE&"!!)qu!!)ntrrE&"!!)nt!!)hr!!'X4s6fm:
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-Pg&M-Pg&M-Pg&M-Pg&M-NgAM$LgAM$Mg&M-Ng&M,[g&M-Ng&M-O
-g&M-Pg&M-Og&M-Mg&M-NgA:mJg&M-Mg&M-Og&M-PgA:mJg&M-Mg&M-Pg&M-Dg&M-Mg&M-Pg&M-C
-g&M-Jg&M-Fg&M-Pg&M-NgAV'Qg&U]t!!)rNrrE&P!!)rN!!)oMrrE&P!!)oM!!)iK!!'Xbs8W)P
-s+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\jo>D\jo>D\jo>D\jo>DZk5>;Xk5>;Yjo>DZjo>Cgjo>DZjo>D[
-jo>D\jo>D[jo>DYjo>DZk5,/Vjo>DYjo>D[jo>D\k5,/Vjo>DYjo>D\jo>DPjo>DYjo>D\jo>DO
-jo>DVjo>DRjo>D\jo>DZk5G>]joFu7!!)rZrrE&\!!)rZ!!)oYrrE&\!!)oY!!)iW!!'Xns8W)K
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXS`(sXS`(tXSi.nX8i8!X9/I(X8r4#!!)qu!!'F.!!)nt!!)u!!!*#"!!)u!
-!!)qu!!)Mi!!)nt!!)u!!!)Vl!!)nt!!*#"!!)Sk!!)nt!!*#"!!)Sk!!)eq!!)Vl!!*#"!!)eq
-!!)Vl!!)nt!!)u!!!)qu!!)nt!!)u!!!)qu!!)hr!!'U3s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSgACsLgACsMgAM$Gg&M-Og&h?/g&V**!!)rN!!'F\!!)oM!!)uO!!*#P!!)uO
-!!)rN!!)NB!!)oM!!)uO!!)WE!!)oM!!*#P!!)TD!!)oM!!*#P!!)TD!!)fJ!!)WE!!*#P!!)fJ
-!!)WE!!)oM!!)uO!!)rN!!)oM!!)uO!!)rN!!)iK!!'Uas8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bk555Xk555Yk5>;Sjo>D[joYVGjoGAB!!)rZ!!'Fh!!)oY!!)u[!!*#\!!)u[
-!!)rZ!!)NN!!)oY!!)u[!!)WQ!!)oY!!*#\!!)TP!!)oY!!*#\!!)TP!!)fV!!)WQ!!*#\!!)fV
-!!)WQ!!)oY!!)u[!!)rZ!!)oY!!)u[!!)rZ!!)iW!!'Ums8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r7$!!)u!!!)u!!!)u!!!)u!!s#F(!;rnu!4Js/!;`bs
-!<&u!!<0&"!<&u!!<&u!!:Quh!;iht!<&u!!;!8l!;ikp!;!8l!;ikp!;*>m!;EPp!;!;h!;W\r
-!;*>m!;`bs!<&u!!;rnu!;iht!<&u!!<&u!!;W\r!4f32mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V-+!!)uO!!)uO!!)uO!!)uO!s%'/!;tON!4LS]!;bCL
-!<(UO!<1[P!<(UO!<(UO!:SVA!;kIM!<(UO!;"nE!;kLI!;"nE!;kLI!;+tF!;G1I!;"qA!;Y=K
-!;+tF!;bCL!<(UO!;tON!;kIM!<(UO!<(UO!;Y=K!4gh`s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGDC!!)u[!!)u[!!)u[!!)u[!s%KG!;tsZ!4M"i!;bgX
-!<)$[!<2*\!<)$[!<)$[!:T%M!;kmY!<)$[!;#=Q!;kpU!;#=Q!;kpU!;,CR!;GUU!;#@M!;YaW
-!;,CR!;bgX!<)$[!;tsZ!;kmY!<)$[!<)$[!;YaW!4h7ls8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r4#!!*#"rrE&"!!)u!!!)u!!s#F(!<&u!!;rqu!55H6
-!<&u!!<0&"!<&u!!<0&"!<&u!!<0&"!<&u!!;!8l!;iht!<&u!!;!8l!;EPp!:m2k!;EPp!;ikt
-!;rnu!<&u!!;iht!;`es!;NVq!;W\r!;ikt!;rnu!<&u!!<&u!!<0&"!;rnu!;`bs!<0&"!<0&"
-!<&u!!<0&"!<&u!!55K6mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V**!!*#PrrE&P!!)uO!!)uO!s%'/!<(UO!;tRN!57(d
-!<(UO!<1[P!<(UO!<1[P!<(UO!<1[P!<(UO!;"nE!;kIM!<(UO!;"nE!;G1I!:nhD!;G1I!;kLM
-!;tON!<(UO!;kIM!;bFL!;P7J!;Y=K!;kLM!;tON!<(UO!<(UO!<1[P!;tON!;bCL!<1[P!<1[P
-!<(UO!<1[P!<(UO!57+ds8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGAB!!*#\rrE&\!!)u[!!)u[!s%KG!<)$[!;u!Z!57Lp
-!<)$[!<2*\!<)$[!<2*\!<)$[!<2*\!<)$[!;#=Q!;kmY!<)$[!;#=Q!;GUU!:o7P!;GUU!;kpY
-!;tsZ!<)$[!;kmY!;bjX!;P[V!;YaW!;kpY!;tsZ!<)$[!<)$[!<2*\!;tsZ!;bgX!<2*\!<2*\
-!<)$[!<2*\!<)$[!57Ops8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSi.tXSi,!XSMqqX98O)X8o@$!<'"q!!'+t!;ikt!55K2!<'"t!;rqs!<'"r
-!;3Gk!;rqs!;*Aj!;`er!;3Gk!;`er!;rqu!;rqq!;iht!;`es!;W_q!<'"u!;`es!;rqq!;rqt
-!<'"s!;iks!<'"r!<0(s!55K6mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%O5g4=h/gAM$MgAM!OgA1gJg&qE0g&Tk+!<(XJ!!(aM!;kLM!57+`!<(XM!;tRL!<(XK
-!;5(D!;tRL!;,"C!;bFK!;5(D!;bFK!;tRN!;tRJ!;kIM!;bFL!;Y@J!<(XN!;bFL!;tRJ!;tRM
-!<(XL!;kLL!<(XK!<1^L!57+ds8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp%X3eVf@Jk5>;Yk5>8[k5#)Vjob\HjoFQC!<)'V!!)0Y!;kpY!57Ol!<)'Y!;u!X!<)'W
-!;5LP!;u!X!;,FO!;bjW!;5LP!;bjW!;u!Z!;u!V!;kmY!;bjX!;YdV!<)'Z!;bjX!;u!V!;u!Y
-!<)'X!;kpX!<)'W!<2-X!57Ops8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSr2#X8r7$r;churW)u"rW)u"q>gPsq>^MsrW)u"rW)u"q>gMrrVuu#!.h5&
-XIZHmmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRgAV'Qg&V-+r;ciNrW)uPrW)uPq>gQLq>^NLrW)uPrW)uPq>gNKrVuuQ!.ijT
-g7?sts8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ak5G>]joGDCr;ciZrW)u\rW)u\q>gQXq>^NXrW)u\rW)u\q>gNWrVuu]!.j9`
-k+1Z7s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8"XT&;#X8i8!X8i8"XT&;"X8i8"X9J[+X8o?'!<0&"!<&u%!3E7%!<0&"
-!<0&+!3E7%XK2E'X8r7$rr@VOJZPEDs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-PgA_0Qg&M-Og&M-PgA_0Pg&M-Pg'.Q2g&Tj\!<1[P!<(US!8?-,!<1[P
-!<1[Y!8?-,g=cP\g&V-+rr@W(J_H[Ks8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D\k5PG]jo>D[jo>D\k5PG\jo>D\jothJjoFQ+!<2*\!<)$_!9WDD!<2*\
-!<2*e!9WDDk2l[+joGDCrr@W4J``Ncs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!W];%qlC&'XK2E'!3E7%ri?;(XK2E'X8r7$!!)u!#QUs-!3?1%X8r7$
-#lq'.!3E7%XK2F#X8i7uXT&9OXF[IKXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!W^pSqq;;Ug=cP\!8?-,rn7PVg=cP\g&V-+!!)uO#QWT4!87G,g&V-+
-#lr]5!8?-,g=cQ*g&M-NgA_/(g4@tRgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!W_?_qrS.ak2l[+!9WDDroOCbk2l[+joGDC!!)u[#QX#L!9O:DjoGDC
-#ls,M!9WDDk2l[Bjo>DZk5PF4k(2Zjk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3?1%X8r.!!!)nt!s#F(!<&u&!3?1%X8r.!!!)qu!!)bp
-rr@VOJZPZKs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!87G,g&V$(!!)oM!s%'/!<(UT!87G,g&V$(!!)rN!!)cI
-rr@W(J_HpRs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9O:DjoG;@!!)oY!s%KG!<)$`!9O:DjoG;@!!)rZ!!)cU
-rr@W4J``cjs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)ntr;cet"TYX*!3?1tX8i7tXSi-MXF[IC
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oMr;cfM"T[91!87GMg&M-MgAM#&g4@tJ
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oYr;cfY"T[]I!9O:Yjo>DYk5>:2k(2Zb
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)nt!s#F(!<&u&!3E7%X8r.!!!)bp!!%SO
-JZPEDs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oM!s%'/!<(UT!8?-,g&V$(!!)cI!!%T(
-J_H[Ks8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oY!s%KG!<)$`!9WDDjoG;@!!)cU!!%T4
-J``Ncs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt!s#F(!<0)"!;iht!;iht!<&u$!3E7%riH,"qlBbtr2]kurN#u!
-JZOF(SZMkZrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V!'!!)oM!s%'/!<1^P!;kIM!;kIM!<(UR!8?-,rn@APqq;#Mr7V,NrRq5O
-J_G\/S_F,Drn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG8?!!)oY!s%KG!<2-\!;kmY!;kmY!<)$^!9WDDroX4\qrRkYr8mtZrT4([
-J`_OGS`]tPrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!*#"rrDqt!!)nt!!)u!!s#F(!<0)"!;iht!;rqu
-!<0&"!;rqu!.h5&XJDrtmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!*#PrrDrM!!)oM!!)uO!s%'/!<1^P!;kIM!;tRN
-!<1[P!;tRN!.ijTg8*I&s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!*#\rrDrY!!)oY!!)u[!s%KG!<2-\!;kmY!;u!Z
-!<2*\!;u!Z!.j9`k+q/>s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSi.tXSi.uXSr5!X8i8!XS`(tXSMnsXSr5!X8i8!XS`(tX8r=&rW)hsrr@VO
-JZPZKs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hRgAM$MgAM$NgAV*Og&M-OgACsMgA1dLgAV*Og&M-OgACsMg&V3-rW)iLrr@W(
-J_HpRs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@ak5>;Yk5>;Zk5GA[jo>D[k555Yk5#&Xk5GA[jo>D[k555YjoGJErW)iXrr@W4
-J``cjs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSr4qX8i7aX8i7`XSi.+X8i7PX8i6OXI$$gmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hRgAV*Jg&M-:g&M-9gAM#Yg&M-)g&M,(g6^Ons8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@ak5GAVjo>DFjo>DEk5>:ejo>D5jo>C4k*P61s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7`X8i7aX8i7)X8i7bX8i7hX8i6OXI-*hmf(c:KE(uFec1:%rs%#L
-s5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-9g&M-:g&M,Wg&M-;g&M-Ag&M,(g6gUos8LaPJcGcDgAca(rs%2N
-s5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>DEjo>DFjo>Ccjo>DGjo>DMjo>C4k*Y<2s8LRKKE(uFec1:%rs%#L
-s5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7FX8i6eX8i7hX8i6OXI-*hmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M,tg&M,>g&M-Ag&M,(g6gUos8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>D+jo>CJjo>DMjo>C4k*Y<2s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7tXSi.tXT&;#XT&;!XSr4sXSr2$X8i7oXSW"sXT&;#XT&;!XSi.u
-XT&8(X8i7%!!)bprr<A,!!')#!3?/#XSr4sXSr4tXS`(sXSr4sXSi.kXS`(tXT&8(X8i7%!!)u!
-!!%SOR&p>Urmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hRg&M-Jg&M-MgAM$MgA_0QgA_0OgAV*LgAV'Rg&M-HgA:mLgA_0QgA_0OgAM$N
-gA_-Vg&M-,!!)cIrr<AZ!!(^Q!87DQgAV*LgAV*MgACsLgAV*LgAM$DgACsMgA_-Vg&M-,!!)uO
-!!%T(R+hT?rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@ajo>DVjo>DYk5>;Yk5PG]k5PG[k5GAXk5G>^jo>DTk5,/Xk5PG]k5PG[k5>;Z
-k5PDbjo>DD!!)cUrr<Af!!)-]!9O7]k5GAXk5GAYk555Xk5GAXk5>;Pk555Yk5PDbjo>DD!!)u[
-!!%T4R-+GKrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jtX8i7qX8i7uX8i8!X8i8!X9AU*!3E7%r2]kur2]kuriH,"o;holqQ'r&X8o?'
-!3E7%rN#u!riH,""KVS'X8qsqrr<>+!!')#XK2C%ri?)"rN#u!ri?)"ri?)"rN#u!qlBbtr2]ku
-rN#u!oW/#mqQ0\s"KVS'X8r4#!!%SOR&p>Urmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hRg&M-Jg&M-Ng&M-Og&M-Og'%K1!8?-,r7V,Nr7V,Nrn@APo@a0EqUu2Tg&Tj\
-!8?-,rRq5Orn@AP"PNhUg&Uj#rr<>Y!!(^Qg=cN,rn7>PrRq5Orn7>Prn7>PrRq5Oqq;#Mr7V,N
-rRq5Oo\'9FqV(rL"PNhUg&V**!!%T(R+hT?rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@ajo>DVjo>DZjo>D[jo>D[jokbI!9WDDr8mtZr8mtZroX4\oB$#QqW8%`joFQ+
-!9WDDrT4([roX4\"Qf[ajoG,;rr<>e!!)-]k2lXDroO1\rT4([roO1\roO1\rT4([qrRkYr8mtZ
-rT4([o]?,RqW@eX"Qf[ajoGAB!!%T4R-+GKrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jtX8i7rX8i7uX8i7tX8i8"XT&:qX8i8!X8i7uX8i7lX8i7sXT&:uX8i7tX9em.
-X8o?'!3E7%p8eQ#XK2E'X8o?'!<&u!!<0&"!;ro#!3E7%p8e5opT+>poW/#mqQ'l$XK2E'X8r1"
-!!%SORB6GVrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hRg&M-Kg&M-Ng&M-Mg&M-PgA_0Jg&M-Og&M-Ng&M-Eg&M-LgA_0Ng&M-Mg'Ic5
-g&Tj\!8?-,p=]fQg=cP\g&Tj\!<(UO!<1[P!;tOQ!8?-,p=]KHpY#TIo\'9FqUu,Rg=cP\g&V')
-!!%T(RG.]@rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@ajo>DWjo>DZjo>DYjo>D\k5PGVjo>D[jo>DZjo>DQjo>DXk5PGZjo>DYjp;%M
-joFQ+!9WDDp>uY]k2l[+joFQ+!<)$[!<2*\!;ts]!9WDDp>u>TpZ;GUo]?,RqW7t^k2l[+joG>A
-!!%T4RHFPLrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jtX8i7qX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7lX8i7sX8i7tX8i7tX9em.
-X8o?'!3E7%p8eQ#XK2E'X8o?'!<&u!!<0(r!<0(u!;`bs!;ikq!;*>m!;`c$!3E7%XK2F#X8i6O
-XI-*hmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Eg&M-Lg&M-Mg&M-Mg'Ic5
-g&Tj\!8?-,p=]fQg=cP\g&Tj\!<(UO!<1^K!<1^N!;bCL!;kLJ!;+tF!;bCR!8?-,g=cQ*g&M,(
-g6gUos8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DQjo>DXjo>DYjo>DYjp;%M
-joFQ+!9WDDp>uY]k2l[+joFQ+!<)$[!<2-W!<2-Z!;bgX!;kpV!;,CR!;bg^!9WDDk2l[Bjo>C4
-k*Y<2s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7lX8i7sX8i7tX8i7tX9em.
-X8o?'!3E7%p8eQ#XK2E'X8o?'!<&u!!<0&"!;*>m!;iht!;rnu!<&u!!;*>m!;`c$!3E7%XK2F#
-X8i6OXI-*hmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Eg&M-Lg&M-Mg&M-Mg'Ic5
-g&Tj\!8?-,p=]fQg=cP\g&Tj\!<(UO!<1[P!;+tF!;kIM!;tON!<(UO!;+tF!;bCR!8?-,g=cQ*
-g&M,(g6gUos8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DQjo>DXjo>DYjo>DYjp;%M
-joFQ+!9WDDp>uY]k2l[+joFQ+!<)$[!<2*\!;,CR!;kmY!;tsZ!<)$[!;,CR!;bg^!9WDDk2l[B
-jo>C4k*Y<2s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7uX8i8!X8i8!X8i7pX8i7uX8i8"XT&:lX8i7sX8i7sX8i8!X8i8"
-X9J[+X8o?'!<'#!!;ro)!3E7%XK2E'X8r4#!!)u!!!)u!!s#F(!<&u!!;iht!;rnu!<0)"!;*>m
-!<0&"!<0&(!3E7%XK2F#X8i7rXT&9OXJ2frmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-Ng&M-Og&M-Og&M-Ig&M-Ng&M-PgA_0Eg&M-Lg&M-Lg&M-Og&M-P
-g'.Q2g&Tj\!<(XO!;tOW!8?-,g=cP\g&V**!!)uO!!)uO!s%'/!<(UO!;kIM!;tON!<1^P!;+tF
-!<1[P!<1[V!8?-,g=cQ*g&M-KgA_/(g7m=$s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>DZjo>D[jo>D[jo>DUjo>DZjo>D\k5PGQjo>DXjo>DXjo>D[jo>D\
-jothJjoFQ+!<)'[!;tsc!9WDDk2l[+joGAB!!)u[!!)u[!s%KG!<)$[!;kmY!;tsZ!<2-\!;,CR
-!<2*\!<2*b!9WDDk2l[Bjo>DWk5PF4k+_#<s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7tXSi.tXSi.rXS`(sXSr2#X8qppquH\sr;c_rr;churW!,'!!')#
-!<0)"!<'"u!!B;&!3H(us/c2"rN,qtriH"tr2ferrN,tu!iuA%oW8#lriH)!"fq\(X8i8"X8i7r
-XT&9OXJ2frmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-MgAM$MgAM$KgACsLgAV'Qg&Ug"quH]Lr;c`Kr;ciNrW!,U!!(^Q
-!<1^P!<(XN!!CpT!8@>Ns4[GPrS%2Mrn@8Mr7_&KrS%5N!nmVSo\09Ern@>O"kiqVg&M-Pg&M-K
-gA_/(g7m=$s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>DYk5>;Yk5>;Wk555Xk5G>]joG):quH]Xr;c`Wr;ciZrW!,a!!)-]
-!<2-\!<)'Z!!D?`!9X1Zs5s:\rT=%YroX+Yr9!nWrT=(Z!p0I_o]H,QroX1["m,dbjo>D\jo>DW
-k5PF4k+_#<s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7UX8i7IXT&:!X8i7sXT&9OXJ)`qmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-.g&M-"gA_/Og&M-LgA_/(g7d7#s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@ajo>DVjo>D:jo>D.k5PF[jo>DXk5PF4k+Ur;s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jtXSr4qX8i7WX8i7HX8i7!X8i7rX8i6OXIuZpmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hRgAV*Jg&M-0g&M-!g&M,Og&M-Kg&M,(g7[1"s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@ak5GAVjo>D<jo>D-jo>C[jo>DWjo>C4k+Ll:s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jIXSi.tXS;deXS;dHXFdPRmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=h'gAM$Mg@tZ>g@tZ!g4J&Ys8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@6k5>;Yk4eqJk4eq-k(;aqs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jiX8i7aX8i7%XT&:VX8i6OXF[JNXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hGg&M-:g&M,SgA_0/g&M,(g4@uUgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Vjo>DFjo>C_k5PG;jo>C4k(2[mk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7`X8i7bX8i7=X8i7hXSr4sXSr4rX8i6OXF[JOXT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johC3g4=hHg&M-9g&M-;g&M,kg&M-AgAV*LgAV*Kg&M,(g4@uVgAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>DEjo>DGjo>D"jo>DMk5GAXk5GAWjo>C4k(2[nk5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7GX8i7=X8i7fX8i7rX8i7sX8i6OXF[JOXT._fec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!johC3g4=hHg&M,ug&M,kg&M-?g&M-Kg&M-Lg&M,(g4@uVgAh3PgAca(s7Y1HJcG`Sg7eQ/
-k.1PC~>
-!<E0!johL1eVf@Wjo>D,jo>D"jo>DKjo>DWjo>DXjo>C4k(2[nk5YJ\ec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!johL1eS8jjX8i7tXSi.tXT&;#XT&;!XSr4sXSr2$X8i7oXS`(rXSi.lXT&8)X8i7%!!',"
-!<9/"!;3Gk!<0&#!3H/"qlKbsqQ'Ysq5aPrqQ'YsJZOF(rN-%ermh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johC3g4=hHg&M-MgAM$MgA_0QgA_0OgAV*LgAV'Rg&M-HgACsKgAM$EgA_-Wg&M-,!!(aP
-!<:dP!;5(D!<1[Q!8@DPqqD#LqUtoLq:YfKqUtoLJ_G\/rS%;Orn@C's8VfHs+14M#25dNk2s5T
-J,~>
-!<E0!johL1eVf@Wjo>DYk5>;Yk5PG]k5PG[k5GAXk5G>^jo>DTk555Wk5>;Qk5PDcjo>DD!!)0\
-!<;3\!;5LP!<2*]!9X7\qr[kXqW7bXq;qYWqW7bXJ`_OGrT=.[rmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johL1eS8jjX8i7uX8i8!X8i8!X9AU*!3E7%r2]kur2]kuriH,"oW/#mqQ'YsrN#u!orS/n
-#HRn*X8o?'!<&u!!;3Dn!<&u!!<0)"!<0&"!<&u!!<0&"!;iht!;W\r!;`bs!.h5&XSo7#mf(c:
-KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hHg&M-Ng&M-Og&M-Og'%K1!8?-,r7V,Nr7V,Nrn@APo\'9FqUtoLrRq5Op"KEG
-#MK.Xg&Tj\!<(UO!;5%G!<(UO!<1^P!<1[P!<(UO!<1[P!;kIM!;Y=K!;bCL!.ijTgATb*s8LaP
-JcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Wjo>DZjo>D[jo>D[jokbI!9WDDr8mtZr8mtZroX4\o]?,RqW7bXrT4([p#c8S
-#Nc!djoFQ+!<)$[!;5IS!<)$[!<2-\!<2*\!<)$[!<2*\!;kmY!;YaW!;bgX!.j9`k5FHBs8LRK
-KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jkX8i7uX8i7tX8i8"XT&:qX8i8!X8i7uX8i7mX8i7tX8i7tX8i7oX9em.X8o?'
-!3E7%rN#u!orJ,nq5aPrrN#u!ri?)"r2]kur2]kuq5aPrq5aPrJZOF(riH.frmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johC3g4=hIg&M-Ng&M-Mg&M-PgA_0Jg&M-Og&M-Ng&M-Fg&M-Mg&M-Mg&M-Hg'Ic5g&Tj\
-!8?-,rRq5Op"BBGq:YfKrRq5Orn7>Pr7V,Nr7V,Nq:YfKq:YfKJ_G\/rn@DPrn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!johL1eVf@Xjo>DZjo>DYjo>D\k5PGVjo>D[jo>DZjo>DRjo>DYjo>DYjo>DTjp;%MjoFQ+
-!9WDDrT4([p#Z5Sq;qYWrT4([roO1\r8mtZr8mtZq;qYWq;qYWJ`_OGroX7\rmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johL1eS8jjX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7mX8i7tX8i7tX8i7oX9J[+X8o?'
-!<0&%!3E7%o;qljrN#u!rN#u!riGqrr2]kuq5aPrqQ'YsJZOF(rN-%ermh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hHg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Fg&M-Mg&M-Mg&M-Hg'.Q2g&Tj\
-!<1[S!8?-,o@j-CrRq5OrRq5Orn@2Kr7V,Nq:YfKqUtoLJ_G\/rS%;Orn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@Wjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DRjo>DYjo>DYjo>DTjothJjoFQ+
-!<2*_!9WDDoB,uOrT4([rT4([roX%Wr8mtZq;qYWqW7bXJ`_OGrT=.[rmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8jjX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7mX8i7tX8i7tX8i7oX9J[+X8o?'
-!<0&%!3E7%n#QKhri?)"rN#u!ri?)"p8e5oq5aPrqQ'YsJZOF(rN-%ermh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hHg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Fg&M-Mg&M-Mg&M-Hg'.Q2g&Tj\
-!<1[S!8?-,n(IaArn7>PrRq5Orn7>Pp=]KHq:YfKqUtoLJ_G\/rS%;Orn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@Wjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DRjo>DYjo>DYjo>DTjothJjoFQ+
-!<2*_!9WDDn)aTMroO1\rT4([roO1\p>u>Tq;qYWqW7bXJ`_OGrT=.[rmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8jjX8i7uX8i8!X8i8!X8i7pX8i7uX8i8"XT&:mX8i8"X8i8"X8i8!X8i7uXT&:u
-X9J[+X8o?'!<'#!!;!8l!<&u!!<0&"!<&u!!<&u!!<&u!!;rnu!;W\r!;`bs!;W_r!.h5,XT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hHg&M-Ng&M-Og&M-Og&M-Ig&M-Ng&M-PgA_0Fg&M-Pg&M-Pg&M-Og&M-NgA_0N
-g'.Q2g&Tj\!<(XO!;"nE!<(UO!<1[P!<(UO!<(UO!<(UO!;tON!;Y=K!;bCL!;Y@K!.ijZgAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>DZjo>D[jo>D[jo>DUjo>DZjo>D\k5PGRjo>D\jo>D\jo>D[jo>DZk5PGZ
-jothJjoFQ+!<)'[!;#=Q!<)$[!<2*\!<)$[!<)$[!<)$[!;tsZ!;YaW!;bgX!;YdW!.j9fk5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7tXSi.tXSi.rXS`(sXSr2#X8qjnrW)ktr;c_rrrE#!rW!,'!!')#!<&u!
-!;!;i!<0)!!<9/"!<'"t!<'"s!<'"s!;rnu!;W_r!.h5,XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hHg&M-MgAM$MgAM$KgACsLgAV'Qg&U`urW)lMr;c`KrrE#OrW!,U!!(^Q!<(UO
-!;"qB!<1^O!<:dP!<(XM!<(XL!<(XL!;tON!;Y@K!.ijZgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>DYk5>;Yk5>;Wk555Xk5G>]joG#8rW)lYr;c`WrrE#[rW!,a!!)-]!<)$[
-!;#@N!<2-[!<;3\!<)'Y!<)'X!<)'X!;tsZ!;YdW!.j9fk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7UX8i7[XT&:iX8i7<X8i7sXT&9OXG3hVmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hHg&M-.g&M-4gA_0Bg&M,jg&M-LgA_/(g4n>]s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@Wjo>D:jo>D@k5PGNjo>D!jo>DXk5PF4k(`$us8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jiX8i7WX8i7ZX8i7hX8i7=X8i7rX8i6OXG*bUmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hGg&M-0g&M-3g&M-Ag&M,kg&M-Kg&M,(g4e8\s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@Vjo>D<jo>D?jo>DMjo>D"jo>DWjo>C4k(Vsts8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jIXSi.tXS;eNXSi.tXS;dHXF[IsXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=h'gAM$Mg@t['gAM$Mg@tZ!g4@u%gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@6k5>;Yk4er3k5>;Yk4eq-k(2[=k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jiX8i7aX8i6OXJ)]q!8adW!;NYq!:m2k!9^H`!<'"r!;rnu!;W\r!:d,j!;W_q
-!:d/jmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hGg&M-:g&M,(g7d4#!8cE0!;P:J!:nhD!9`)9!<(XK!;tON!;Y=K!:ebC!;Y@J
-!:eeCs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Vjo>DFjo>C4k+Uo;!8ci<!;P^V!:o7P!9`ME!<)'W!;tsZ!;YaW!:f1O!;YdV
-!:f4Os8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jjX8i7`X8i7GX8i7`X8i7`X9/I(X8r7$rW)u"rW(u[!!'p<!!)bp!!(lW!!)bp
-!!)Sk!!)5a!W];%rN#u!rN#u!rN-#!qQ0\sqQ'c!XK2F!X8i7qX8i7jXT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johC3g4=hHg&M-9g&M,ug&M-9g&M-9g&h?/g&V-+rW)uPrW)!4!!'pj!!)cI!!(m0!!)cI
-!!)TD!!)6:!W^pSrRq5OrRq5OrS%8OqV(rLqUu#Og=cQ(g&M-Jg&M-CgAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>DEjo>D,jo>DEjo>DEjoYVGjoGDCrW)u\rW)!@!!'q!!!)cU!!(m<!!)cU
-!!)TP!!)6F!W_?_rT4([rT4([rT=+[qW@eXqW7k[k2l[@jo>DVjo>DOk5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7,X8i7`X8i7`X9/I(X8r4#rrE&"!!)#[!!'p<!!(*A!!(ZQ!W];%poFGq
-ri?/$X8r.!!W];%qQ'c!XK2F!X8i7qX8i7jXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hHg&M,Zg&M-9g&M-9g&h?/g&V**rrE&P!!)$4!!'pj!!(*o!!([*!W^pSpt>]J
-rn7DRg&V$(!W^pSqUu#Og=cQ(g&M-Jg&M-CgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>Cfjo>DEjo>DEjoYVGjoGABrrE&\!!)$@!!'q!!!(+&!!([6!W_?_puVPV
-roO7^joG;@!W_?_qW7k[k2l[@jo>DVjo>DOk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7tXSi.tXT&;#XT&;!XSr4sXSr2$X8i7mXSr2#X8r7$r;churr<&#rW)nu
-quHVqrW)r!rr<&#rW)nuquHYrquHAj!s#F(!<&u&!3?1%X8r1"rW)r!rW)r!rW)\oquH\srrE)#
-rrE#!r;churr<&#rW)ktquH\sr;c_rrW!&%!3E:"!;rqt!;ikr!<0)"!!',"!;!;k!;iks!!0/$
-oW8#lqlK\qoW/,pXK2EtX8i7tX8i7rX8i7sX9/I(X8r.!!!)eq!!)Pjs6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johC3g4=hHg&M-MgAM$MgA_0QgA_0OgAV*LgAV'Rg&M-FgAV'Qg&V-+r;ciNrr<&QrW)oN
-quHWJrW)rOrr<&QrW)oNquHZKquHBC!s%'/!<(UT!87G,g&V')rW)rOrW)rOrW)]HquH]LrrE)Q
-rrE#Or;ciNrr<&QrW)lMquH]Lr;c`KrW!&S!8?0)!;tRM!;kLK!<1^P!!(aP!;"qD!;kLL!!1dR
-o\09EqqCrJo\'BIg=cQ&g&M-Mg&M-Kg&M-Lg&h?/g&V$(!!)fJ!!)QCs8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!johL1eVf@Wjo>DYk5>;Yk5PG]k5PG[k5GAXk5G>^jo>DRk5G>]joGDCr;ciZrr<&]rW)oZ
-quHWVrW)r[rr<&]rW)oZquHZWquHBO!s%KG!<)$`!9O:DjoG>ArW)r[rW)r[rW)]TquH]XrrE)]
-rrE#[r;ciZrr<&]rW)lYquH]Xr;c`WrW!&_!9WGA!;u!Y!;kpW!<2-\!!)0\!;#@P!;kpX!!23^
-o]H,Qqr[eVo]?5Uk2l[>jo>DYjo>DWjo>DXjoYVGjoG;@!!)fV!!)QOs8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johL1eS8jjX8i7uX8i8!X8i8!X9AU*!3E7%r2]kur2]kuriH,"oW/#mriH,"s/Z2#rN#u!
-riH,"ri?)"rN#u!q5aPrri?)"riH,"ri?)"rN#u!qQ'YsrN#u!oW/,pXK2F#X9AU*!3E7%rN#u!
-ri?)"ri?)"r2]kuorJ,nq5ai%X8o?'!3E7%rN#u!riH,"ri?)"ri?)"rN#u!ri?)"rN#u!rN#u!
-riH,"ri?)"pT+>pr2]kurN#u!riH,"ri?)"nuMfkr2]kuriH,"nuMfkr2]kurN#u!oW/,pXK2Et
-X8i7tX8i7rX8i7sX9/I(X8r.!!!)eq!!)Pjs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hHg&M-Ng&M-Og&M-Og'%K1!8?-,r7V,Nr7V,Nrn@APo\'9Frn@APs4RGQrRq5O
-rn@APrn7>PrRq5Oq:YfKrn7>Prn@APrn7>PrRq5OqUtoLrRq5Oo\'BIg=cQ*g'%K1!8?-,rRq5O
-rn7>Prn7>Pr7V,Np"BBGq:Z)Sg&Tj\!8?-,rRq5Orn@APrn7>Prn7>PrRq5Orn7>PrRq5OrRq5O
-rn@APrn7>PpY#TIr7V,NrRq5Orn@APrn7>Po%F'Dr7V,Nrn@APo%F'Dr7V,NrRq5Oo\'BIg=cQ&
-g&M-Mg&M-Kg&M-Lg&h?/g&V$(!!)fJ!!)QCs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@Wjo>DZjo>D[jo>D[jokbI!9WDDr8mtZr8mtZroX4\o]?,RroX4\s5j:]rT4([
-roX4\roO1\rT4([q;qYWroO1\roX4\roO1\rT4([qW7bXrT4([o]?5Uk2l[BjokbI!9WDDrT4([
-roO1\roO1\r8mtZp#Z5Sq;qq_joFQ+!9WDDrT4([roX4\roO1\roO1\rT4([roO1\rT4([rT4([
-roX4\roO1\pZ;GUr8mtZrT4([roX4\roO1\o&]oPr8mtZroX4\o&]oPr8mtZrT4([o]?5Uk2l[>
-jo>DYjo>DWjo>DXjoYVGjoG;@!!)fV!!)QOs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jkX8i7uX8i7tX8i8"XT&:qX8i8!X8i7uX8i7nX8i7uX9&C'!;ii"!3E7%rN#u!
-rN#u!qQ'Ysr2]u#XK2F#X8i8!X8i7sX8i7`X9AU*X8o=%ri?)"r2^2)XK2E'X8o?'!;3Dn!;W_r
-!;<Jo!<0&"!<&u!!<0&"!;*>m!<0&"!;rnu!<0&"!;EPp!<&u!!;ii"!3E7%rN#u!nuMfkrN#u!
-r2]kunuMfkr2]kun>lTiri?)"q5aPrqlBbtq5aPrn#QKhq5aPrnZ;cYrmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hIg&M-Ng&M-Mg&M-PgA_0Jg&M-Og&M-Ng&M-Gg&M-Ng&_9.!;kIP!8?-,rRq5O
-rRq5OqUtoLr7V5Qg=cQ*g&M-Og&M-Lg&M-9g'%K1g&Th,rn7>Pr7VGWg=cP\g&Tj\!;5%G!;Y@K
-!;>+H!<1[P!<(UO!<1[P!;+tF!<1[P!;tON!<1[P!;G1I!<(UO!;kIP!8?-,rRq5Oo%F'DrRq5O
-r7V,No%F'Dr7V,NnCdjBrn7>Pq:YfKqq;#Mq:YfKn(IaAq:YfKn_4$Crn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@Xjo>DZjo>DYjo>D\k5PGVjo>D[jo>DZjo>DSjo>DZjoPPF!;km\!9WDDrT4([
-rT4([qW7bXr8n(]k2l[Bjo>D[jo>DXjo>DEjokbIjoFNDroO1\r8n:ck2l[+joFQ+!;5IS!;YdW
-!;>OT!<2*\!<)$[!<2*\!;,CR!<2*\!;tsZ!<2*\!;GUU!<)$[!;km\!9WDDrT4([o&]oPrT4([
-r8mtZo&]oPr8mtZnE']NroO1\q;qYWqrRkYq;qYWn)aTMq;qYWn`KlOrmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8jjX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7nX8i7sX8i7tX9/I(X8r4#!!)u!
-!!)ksq>gPs!!)u!!!)u!!!)hrr;c/b"TYX*!3?2"XSMqsX9J[+X8o?'!;3Dn!;W\r!;W_o!<0&"
-!<&u!!<'"t!;rqr!<0&"!;NVq!;EPp!<&u!!;ii"!3E7%rN#u!nuMfkrN#u!r2]kunuMfkqlK_r
-oW/#mri?)"qQ'YsqQ'Ysq5aPrn>lTipoFGqnZ;cYrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hHg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Gg&M-Lg&M-Mg&h?/g&V**!!)uO
-!!)lLq>gQL!!)uO!!)uO!!)iKr;c0;"T[91!87GPgA1gLg'.Q2g&Tj\!;5%G!;Y=K!;Y@H!<1[P
-!<(UO!<(XM!;tRK!<1[P!;P7J!;G1I!<(UO!;kIP!8?-,rRq5Oo%F'DrRq5Or7V,No%F'DqqCuK
-o\'9Frn7>PqUtoLqUtoLq:YfKnCdjBpt>]Jn_4$Crn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@Wjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DSjo>DXjo>DYjoYVGjoGAB!!)u[
-!!)lXq>gQX!!)u[!!)u[!!)iWr;c0G"T[]I!9O:\k5#)XjothJjoFQ+!;5IS!;YaW!;YdT!<2*\
-!<)$[!<)'Y!;u!W!<2*\!;P[V!;GUU!<)$[!;km\!9WDDrT4([o&]oPrT4([r8mtZo&]oPqr[hW
-o]?,RroO1\qW7bXqW7bXq;qYWnE']NpuVPVn`KlOrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jjX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7nX8i7sX8i7tX9/I(X8r4#!!)u!
-!!)ks!!)hr!!)u!!!)u!!!)\n!!)Ae!!*#"rrE&"!!)eq"9>M'X8qmo!!)hr!!)ks!!)u!!!*#"
-!!)u!!!)hr!!*#"!!)u!!!*#"!!)eq!!)bp!!)u!!!)nt!s#F(!<&u!!:m2k!<&u!!;rnu!:m2k
-!;EPp!;3Gj!;iht!;`bs!;W\r!:[&i!;NVq!:d/jmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hHg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Gg&M-Lg&M-Mg&h?/g&V**!!)uO
-!!)lL!!)iK!!)uO!!)uO!!)]G!!)B>!!*#PrrE&P!!)fJ"9@-Ug&Ud!!!)iK!!)lL!!)uO!!*#P
-!!)uO!!)iK!!*#P!!)uO!!*#P!!)fJ!!)cI!!)uO!!)oM!s%'/!<(UO!:nhD!<(UO!;tON!:nhD
-!;G1I!;5(C!;kIM!;bCL!;Y=K!:\\B!;P7J!:eeCs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Wjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DSjo>DXjo>DYjoYVGjoGAB!!)u[
-!!)lX!!)iW!!)u[!!)u[!!)]S!!)BJ!!*#\rrE&\!!)fV"9@QajoG&9!!)iW!!)lX!!)u[!!*#\
-!!)u[!!)iW!!*#\!!)u[!!*#\!!)fV!!)cU!!)u[!!)oY!s%KG!<)$[!:o7P!<)$[!;tsZ!:o7P
-!;GUU!;5LO!;kmY!;bgX!;YaW!:]+N!;P[V!:f4Os8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jjX8i7uX8i8!X8i8!X8i7pX8i7uX8i8"XT&:mX8i8!X9/I(X8r4#!!*#"!!)u!
-!!)u!!!*#"!!)u!!!)u!!s#F(!<&u!!<&u!!<0&"!<0&"!<&u!!;rqu!;!8l!<0)"!<&u!!<&u!
-!<0)"!!95%!;*>m!<0&"!<&u!!;`bs!<0)"!<0&"!<&u!!<0&"!<&u!!<0&"!<0)"!<&u!!<&u!
-!<0&"!<0&"!;iht!;rnu!<&u!!<0&"!<&u!!:m2k!;rnu!<0)"!:m2k!;rnu!<&u!!:d,j!;`bs
-!;`bs!;W\r!:[&i!;NVq!:d/jmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hHg&M-Ng&M-Og&M-Og&M-Ig&M-Ng&M-PgA_0Fg&M-Og&h?/g&V**!!*#P!!)uO
-!!)uO!!*#P!!)uO!!)uO!s%'/!<(UO!<(UO!<1[P!<1[P!<(UO!;tRN!;"nE!<1^P!<(UO!<(UO
-!<1^P!!:jS!;+tF!<1[P!<(UO!;bCL!<1^P!<1[P!<(UO!<1[P!<(UO!<1[P!<1^P!<(UO!<(UO
-!<1[P!<1[P!;kIM!;tON!<(UO!<1[P!<(UO!:nhD!;tON!<1^P!:nhD!;tON!<(UO!:ebC!;bCL
-!;bCL!;Y=K!:\\B!;P7J!:eeCs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Wjo>DZjo>D[jo>D[jo>DUjo>DZjo>D\k5PGRjo>D[joYVGjoGAB!!*#\!!)u[
-!!)u[!!*#\!!)u[!!)u[!s%KG!<)$[!<)$[!<2*\!<2*\!<)$[!;u!Z!;#=Q!<2-\!<)$[!<)$[
-!<2-\!!;9_!;,CR!<2*\!<)$[!;bgX!<2-\!<2*\!<)$[!<2*\!<)$[!<2*\!<2-\!<)$[!<)$[
-!<2*\!<2*\!;kmY!;tsZ!<)$[!<2*\!<)$[!:o7P!;tsZ!<2-\!:o7P!;tsZ!<)$[!:f1O!;bgX
-!;bgX!;YaW!:]+N!;P[V!:f4Os8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jjX8i7tXSi.tXSi.rXS`(sXSr2#X8qjnr;cetr;churW)u"rW)nurW)hsr;cl!
-rW)u"rW)nurW)nuquHVqrrD\mrW)r!!!)qur;cetrr<,%!!)VlrW)nur;c_rrW!&%!!',"!<9/"
-!<9.u!;rqt!!95%!<'"t!;rqt!;rqr!<'"t!<0)!!<9/"!;3Gk!<'"u!!95%!;3Gk!<0(t!:d/i
-!;iht!;rqr!<'"s!:m2k!;NVq!:d/jmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hHg&M-MgAM$MgAM$KgACsLgAV'Qg&U`ur;cfMr;ciNrW)uPrW)oNrW)iLr;clO
-rW)uPrW)oNrW)oNquHWJrrD]FrW)rO!!)rNr;cfMrr<,S!!)WErW)oNr;c`KrW!&S!!(aP!<:dP
-!<:dN!;tRM!!:jS!<(XM!;tRM!;tRK!<(XM!<1^O!<:dP!;5(D!<(XN!!:jS!;5(D!<1^M!:eeB
-!;kIM!;tRK!<(XL!:nhD!;P7J!:eeCs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Wjo>DYk5>;Yk5>;Wk555Xk5G>]joG#8r;cfYr;ciZrW)u\rW)oZrW)iXr;cl[
-rW)u\rW)oZrW)oZquHWVrrD]RrW)r[!!)rZr;cfYrr<,_!!)WQrW)oZr;c`WrW!&_!!)0\!<;3\
-!<;3Z!;u!Y!!;9_!<)'Y!;u!Y!;u!W!<)'Y!<2-[!<;3\!;5LP!<)'Z!!;9_!;5LP!<2-Y!:f4N
-!;kmY!;u!W!<)'X!:o7P!;P[V!:f4Os8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jjX8i7UX8i7%XT&9OXF[JOX8i7qX8i7jXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hHg&M-.g&M,SgA_/(g4@uVg&M-Jg&M-CgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>D:jo>C_k5PF4k(2[njo>DVjo>DOk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jiX8i7WX8i7$X8i6OXF[JOX8i7rXSr4iXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hGg&M-0g&M,Rg&M,(g4@uVg&M-KgAV*BgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Vjo>D<jo>C^jo>C4k(2[njo>DWk5GANk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jIXSi.tXS;dHXF[I=XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=h'gAM$Mg@tZ!g4@tDgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@6k5>;Yk4eq-k(2Z\k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uDKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcBJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uDKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH3RZrs=8Vs4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJHE^gs7k=JJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcEUes7tCKJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcEUes8(ILJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc<Ods81OMJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc<Ods8:UNJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc3Ics8C[OJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc3Ics8LaPJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*Cbs8UgQJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:as8ITI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJbm7`Jc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMmXaeWmaU\(ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+s+13$s4%)JgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:s+13$s4%)Jec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!jo_F0eS9['JaS*We*d4cs+Bh@#1]OLk2s>WJ,~>
-!<E0!jo_=2g4=hTJcC<$e,TF$s+0\>#25dNk2s5TJ,~>
-!<E0!jo_F0eVf"YJcC<$e,TEts+Bh@#1]OLk2s>WJ,~>
-!<E0!joD3.eUc8%e]lVEKCAgEeYN6-k.LbF~>
-!<E0!joD*+g4@t/g<J=OJa`UCg7eQ/k.1PC~>
-!<E0!joD3.eUc8%e]lVEKCAgEeYN6-k.LbF~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joM:.JV/N+JV2=%ldZ07s5rIW!.Y~>
-!<E0!joM10JUrB'JUu1!le2N9s5rIT!.Y~>
-!<E0!joM:.JV/N+JV2=%ldZ07s5rIW!.Y~>
-!<E0!joM:.JV/N+JV2@&!<;B8"f21\k.LbF~>
-!<E0!joM10JUrB'JUu4"!<;B="ektYk.1PC~>
-!<E0!joM:.JV/N+JV2@&!<;B8"f21\k.LbF~>
-!<E0!jo_F0K7id/!WTias+13$s7H<m^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_=2JV!F0!WU#fs+13$s7H<m_Z0Z._Z0Z%g'+2Mk2s5TJ,~>
-!<E0!jo_F0K7id/!WTias+13$s7H<m^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+14CrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<E0!jo_=2JV!L2s8N+N_L_`<s+14CrrI\frVuT.s8VE="ektYk.1PC~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+14CrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<Bh3S-%5nKD3(Ys8R]Q^&S+`eUc8%ebI\pK)iU^s7j;-s6J2=S@tG_!!%N~>
-!<B_0R0))nJbR%\s8RWO_Z0Xeg4@t/gA'D%JH3Ras7jJ2s6JABRC\fS!!%N~>
-!<Bh3S-%5nKD3(Ys8R]Q^&S+`eUc8%ebI\pK)iU^s7j;-s6J2=S@tG_!!%N~>
-!!)uB".[noKDE4Zrrpr*K>%<bJ^o>%J^sPGs+:Hfs8UX"rVu`-s8VE8"e<iN]po(Q~>
-!!)u?".@koJbd1]rrq,-J\qHeJ_G\/J_KnQs+(<is8Ug,rVu`2s8VE="e!NE\sWPK~>
-!!)uB".[noKDE4Zrrpr*K>%<bJ^o>%J^sPGs+:Hfs8UX"rVu`-s8VE8"e<iN]po(Q~>
-!<CCD]`XeTK7j'7rVulIs+:Bds8RZ#J^o>%psoCs!knX6rRLlHr4W.1ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!^8rVulNs+(6gs8RZ(J_G\/ptGb!!lG!;rS%5Mr5/L6le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j'7rVulIs+:Bds8RZ#J^o>%psoCs!knX6rRLlHr4W.1ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j-9rVufGs+:Bds8RZ#J^o>%psoCs!knX6qpkZFrk8@3ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!d:rVufLs+(6gs8RZ(J_G\/ptGb!!lG!;qqD#Krke^8le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j-9rVufGs+:Bds8RZ#J^o>%psoCs!knX6qpkZFrk8@3ldZ0/c+Uf\!.Y~>
-!<CCD]`jqVK7gkNrVu`Es+:Bds8RZ#J^o>%psoCs!knX6q:5HD!knX6ldZ0/c+Uf\!.Y~>
-!<C:A\cnMUJUt\TrVu`Js+(6gs8RZ(J_G\/ptGb!!lG!;q:bfI!lG!;le2N1b.>0P!.Y~>
-!<CCD]`jqVK7gkNrVu`Es+:Bds8RZ#J^o>%psoCs!knX6q:5HD!knX6ldZ0/c+Uf\!.Y~>
-!<CCD]`FYRqh+[os+:Bds8RZ#J^o>%psoCs!knX6pso=qs8VE8"e<iN]po(Q~>
-!<C:A\cJ5QqgnOrs+(6gs8RZ(J_G\/ptGb!!lG!;ptG[ts8VE="e!NE\sWPK~>
-!<CCD]`FYRqh+[os+:Bds8RZ#J^o>%psoCs!knX6pso=qs8VE8"e<iN]po(Q~>
-!<CCD]`jqVK7gkNrIasss+:Bds8RZ#J^o>%psoCs!knX6q:5Fr!knX6ldZ0/c+Uf\!.Y~>
-!<C:A\cnMUJUt\TrIOh!s+(6gs8RZ(J_G\/ptGb!!lG!;q:bdu!lG!;le2N1b.>0P!.Y~>
-!<CCD]`jqVK7gkNrIasss+:Bds8RZ#J^o>%psoCs!knX6q:5Fr!knX6ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j-9rIb$us+:Bds8RZ#J^o>%psoCs!knX6qpkXtrk8@3ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!d:rIOn#s+(6gs8RZ(J_G\/ptGb!!lG!;qqD""rke^8le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j-9rIb$us+:Bds8RZ#J^o>%psoCs!knX6qpkXtrk8@3ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j'7rIb+"s+:Bds8RZ#J^o>%psoCs!knX6rRLk!r4W.1ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!^8rIOt%s+(6gs8RZ(J_G\/ptGb!!lG!;rS%4$r5/L6le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j'7rIb+"s+:Bds8RZ#J^o>%psoCs!knX6rRLk!r4W.1ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j!5rIY:(K7gl;s+/^OeUc9Gec17)^&S,_ebt-s^&S,ueHMJf]tKp9J,~>
-!<C:A\c\ASJV!X6rIG.+JUt]<s+/mTg4@uQgAc^,_Z0YigAQU!_Z0Z%g'*ne]"4:0J,~>
-!<CCD]`XeTK7j!5rIY:(K7gl;s+/^OeUc9Gec17)^&S,_ebt-s^&S,ueHMJf]tKp9J,~>
-!<CCD]`XeTK7ip3r.>'as8RZ#J^o>%psoCs!knX6rIamYs8VE8"e<iN]po(Q~>
-!<C:A\c\ASJV!R4r.+pds8RZ(J_G\/ptGb!!lG!;rIOa\s8VE="e!NE\sWPK~>
-!<CCD]`XeTK7ip3r.>'as8RZ#J^o>%psoCs!knX6rIamYs8VE8"e<iN]po(Q~>
-!<CCD]`XeTK7ij1rdt9cs8RY&JV/N+p4EL]s8R_(p:^M+ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!L2rdb-fs8RY$JUrB'p43@`s8RY$p;6k0le2N1b.>0P!.Y~>
-!<CCD]`XeTK7ij1rdt9cs8RY&JV/N+p4EL]s8R_(p:^M+ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7id/!e\2dJV/N+JV3WJ!knVdoY(;)ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!F0!eJ5gJUrB'JV!KF!lFtgoYUY.le2N1b.>0P!.Y~>
-!<CCD]`XeTK7id/!e\2dJV/N+JV3WJ!knVdoY(;)ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7eaTJcC<$df8X`"e<iN]po(Q~>
-!<C:A\c\ASJUrCPJcC<$df8Xe"e!NE\sWPK~>
-!<CCD]`XeTK7eaTJcC<$df8X`"e<iN]po(Q~>
-!<CCD]`O_SK7X&Rs+13ts6J2=SB\a\S,e'~>
-!<C:A\cS;RJV!iPs+13ts6JABREE+PR/ha~>
-!<CCD]`O_SK7X&Rs+13ts6J2=SB\a\S,e'~>
-!<CCD]`=RReUc8%e[a36SB\a\S,e'~>
-!<C:A\cA.Lg4@t/g:>o@REE+PR/ha~>
-!<CCD]`=RReUc8%e[a36SB\a\S,e'~>
-!<CCC^%%VDUk,=mUtMOD^%.Znc2PBWS,e'~>
-!<C:@]()2>Tn/ngU"Q+>](26hb5SsQR/ha~>
-!<CCC^%%VDUk,=mUtMOD^%.Znc2PBWS,e'~>
-!]^8*rOqgI!53s`JcC<$g&LTerk/B'!7cT~>
-!^m%2rOVUC!4ma]JcC<$g&LTbrji0!!8;r~>
-!cn@drOqgI!53s`JcC<$g&LTerk/B'!7cT~>
-!\j]"n%A^kJ`_OGJ`bYJ!6suG!h98@J,~>
-!^m%2n%&LeJ`_OGJ`bYJ!6XcA!gs&BJ,~>
-!bq_[n%A^kJ`_OGJ`bYJ!6suG!h98@J,~>
-s#C,\S=K,_!1\W&J`_OGg#`:Zn\+sm!W^d$J,~>
-s$QngR@3TV!1AE#J`_OGg#`:Wn[eag!W^s.J,~>
-s)S5AS=K,_!1\W&J`_OGg#`:Zn\+sm!W^d$J,~>
-r\=EQn=5'CJ\?WJfY-gFrrE&KJ,~>
-r^?bdn<nj=J\$EDfXgU@rrE&PJ,~>
-rcA)>n=5'CJ\?WJfY-gFrrE&KJ,~>
-r](!63Iq0]!.b-Z!<:RNs4,YM~>
-r'Z)9JH16$[fHH^!W^s.J,~>
-r,[DhJH16$[fHHY!W^d$J,~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/sim_trans_mgr_actors.gif b/lib/et/doc/src/sim_trans_mgr_actors.gif
deleted file mode 100644
index b954a45bba..0000000000
--- a/lib/et/doc/src/sim_trans_mgr_actors.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_mgr_actors.png b/lib/et/doc/src/sim_trans_mgr_actors.png
new file mode 100644
index 0000000000..e42e82adad
--- /dev/null
+++ b/lib/et/doc/src/sim_trans_mgr_actors.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_mgr_actors.ps b/lib/et/doc/src/sim_trans_mgr_actors.ps
deleted file mode 100644
index 9bfa4ab544..0000000000
--- a/lib/et/doc/src/sim_trans_mgr_actors.ps
+++ /dev/null
@@ -1,1705 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/sim_trans_mgr_actors.ps
-%%CreationDate: Mon Oct 14 17:07:53 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 443 371
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 356.135581 translate
-428.031496 -356.135581 scale
-% Image geometry
-512 426 8
-% Transformation matrix
-[ 512 0 0 426 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 512 string def
-/gstr 512 string def
-/bstr 512 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 92674 ASCII Bytes
-colorimage
-r.BP#JH16$MZE\TJ,~>
-r.0D!JH16$MZE\TJ,~>
-r.BP#JH16$MZE\TJ,~>
-rk8=3nc&U&JcC<$JcF@%!56GQquD6~>
-rke[8nc&U'JcC<$JcF@%!5?MRquD6~>
-rk8=3nc&U&JcC<$JcF@%!56GQquD6~>
-s1JI6s8VWG!53s6J^o>%f@9l7a56ja!W`9#J,~>
-s2"g;s8VWC!5=$8J_#D'f@Br9a4gR]!W`9#J,~>
-s1JI6s8VWG!53s6J^o>%f@9l7a56ja!W`9#J,~>
-!keU6n(n&XJ^o>%J^rB&!56A.!lY0>J,~>
-!l=s;n(IcUJ_#D'J_&H(!5?G+!l=s;J,~>
-!keU6n(n&XJ^o>%J^rB&!56A.!lY0>J,~>
-!keU6n(n&X\((JtJ^o>%U=B7W`SL[8!<7Q~>
-!l=s;n(IcU\(1T&dXfu#et^dr^;\e-_>sUd~>
-!keU6n(n&X\((JtJ^o>%U=B7W`SL[8!<7Q~>
-!<E/fh>k7Kec1lieHNpfe\-<VrfmH5!J>`neH)JZJ^oY.!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/fg&SkHf)LlgedTEhf"Q]`R?<W_eq&CHecDJYJ_#_0!5@XMpR1^.s-`i>s-`f=!NlEQ~>
-!<E/fh>k7Kec1lieHNpfe\-<VrfmH5!J>`neH)JZJ^oY.!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&n^[Z(hUN4WHaM=]Hc=O"Ph"<:He$Zc]tMqs`P(Wg!jm<nJ^o\/
-!57RPpRLs6rLEoErLEiC!NZ9O~>
-!<E/tf)M08f)M0:ec<GVdK.4nn^@H"hU3"QJ[X!dIE'QpOj_[/J^Vu`[_:)i_RAgZ!k*NkJ^TJ)
-!5@XIpR1a+rL*]:rL*W8!NlEQ~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&n^[Z(hUN4WHaM=]Hc=O"Ph"<:He$Zc]tMqs`P(Wg!jm<nJ^o\/
-!57RPpRLs6rLEoErLEiC!NZ9O~>
-!<E/uhYiuChYiuDh>k7]eH(;LbgclTPh"<:Hi)=sK6u/!K6t;^!J>abeH(nmJ^o\/!57RPpRLs6
-pRM3=!NZ9O~>
-!<E/uf);$8f);$9ec<GVdf4mBdKPJmdaE\tqpPLqs3gpu^!cq3ld>g!M1O*5dK%#Ef(YU+f(YU2
-ecDoRJ,~>
-!<E/uhYiuChYiuDh>k7]eH(;LbgclTPh"<:Hi)=sK6u/!K6t;^!J>abeH(nmJ^o\/!57RPpRLs6
-pRM3=!NZ9O~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`V\15S9qs"eZ=DRK6u/!`J](q[+27)`RUK*`RUKS
-e]!GnK='1ZMi4ZprRD%aHbIt"rd+pqK6u/!K6u.Erd4[a%#]Ib[+3]bMl_ieK7!LGs,.8uK6su4
-K6suUe]!dOHiMXrMZKo;qUH(pP^@b8`RWM?MgKf/c(t>c"i[R$H],!)ec1O9XGbWJMgKf'^"'fC
-]n+^meH!;GhY3Q5hYE]>h>s\XJ,~>
-!<E/uf)1s9f)1s8ec<G]dK[RNI>+uTU&KH?_Y_b/R=2Zpd\VZGJUu7t_NB8#ZI5b$_U=j#_U=jG
-d__,pKsK.TNK'corR(h[ICdjprd>'pJUu7tJUu7CrdFg`%$>slZI70\NMVW_JV!^Hs,@DpKn6D8
-Kn6PXd__.FIK.aqN<,l8qU,knOb%q?^=(H4M1'f/b+\f_"i@F!I>P-+df5:8V2`p?Ob%q7[aMU4
-\q/:gdK%#Ef(YU*f(ka3ecDoRJ,~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`V\15S9qs"eZ=DRK6u/!`J](q[+27)`RUK*`RUKS
-e]!GnK='1ZMi4ZprRD%aHbIt"rd+pqK6u/!K6u.Erd4[a%#]Ib[+3]bMl_ieK7!LGs,.8uK6su4
-K6suUe]!dOHiMXrMZKo;qUH(pP^@b8`RWM?MgKf/c(t>c"i[R$H],!)ec1O9XGbWJMgKf'^"'fC
-]n+^meH!;GhY3Q5hYE]>h>s\XJ,~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifV
-P^CBoK6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO(P@'mS9oU@S9on5
-c%CYfc%CAfc%CA$V#&=b]r\oSH]-.EH],8<UrC<"HbH5%PeE<.XNf"BH]+]EMgMhE[(X`'H^oZ3
-N6M@9kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/tdeB1.dK%#Zc3h^FKt<Ot`l<RX_YVP*[XFRhcAACCJUu+hJVC\#IE&jHWm6<HWm61(b(58X
-Q$pZtJUNBOrQZU\IE'RPJUPD\JUu+lJUu+dJUPDTJVC\#IE'Q`I>OfGM2D,T(P.!oTm_?KTm_X?
-b(58`c@p\lc@LD#V>AId^952YI>Q7GI>P8<WlE&0IDW"4Q+iN3Wm8n@I>OfGM1)hH[_C&,IA)5;
-N6VF;kL'?uq9f82o[<W)qpGMJ!.Y~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifV
-P^CBoK6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO(P@'mS9oU@S9on5
-c%CYfc%CAfc%CA$V#&=b]r\oSH]-.EH],8<UrC<"HbH5%PeE<.XNf"BH]+]EMgMhE[(X`'H^oZ3
-N6M@9kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEprt(:Hd06N`Qa$^c)c8^c)c8nc$P\oH\7QrHd/X=SB\-^
-XNcBEqoo/+HiD8,K6tkfK6tkfK6tkfK6tkEH^r?^H`YJEHhP]!K6tS^H[E`VH[F#=H^r@*K6tkf
-K7!=:#K=B/K?]$q`VdsiK6tjqHc=7KH\9SfK7!UB",hMr^&?1VH^'*+N6M@9kLBR&q:,J8o[Wi/
-qpb_K!.Y~>
-!<E/sdeT=/dK%#Zc3^Y%TusNdY0MTLps/nj,Kd`K_Tm^`cE;Shb-$/qc@(ttI>+*+IEJ^@TusNd
-Y0MTHb5BNcQ$rYWs+13qs+13qs+13qs+(R'Y'm"dY'mIuJUP]8c5(tZb0GQdb0GQhcE_khcH_,l
-cH^uhb4j0d_S1STc@p\`r6G=n'$c>^`m2SPM9aCtIEKj\M1(r3rQYFlQ%@5>c2bTAdK#^2dK#^-
-defI0dK-KNJ,~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEprt(:Hd06N`Qa$^c)c8^c)c8nc$P\oH\7QrHd/X=SB\-^
-XNcBEqoo/+HiD8,K6tkfK6tkfK6tkfK6tkEH^r?^H`YJEHhP]!K6tS^H[E`VH[F#=H^r@*K6tkf
-K7!=:#K=B/K?]$q`VdsiK6tjqHc=7KH\9SfK7!UB",hMr^&?1VH^'*+N6M@9kLBR&q:,J8o[Wi/
-qpb_K!.Y~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!C<$ClIES;YY:K6tk=r-JgIc&74UPa$g%Mp8'qHNU(gK7!L?
-!L.s1bn#GRc-:lfc-:lfc-:lfc(t8a"/O1oHhP]!K6tkfK6tkfK6tk=H_ep2K6tkfK7!C<#ebkC
-MgL*$H[GY7"G;'GH[Gb:s*Odj!J>aubmD@RH[C[ac-:U"J^'.u!58<\!582u!58*V!1`l8!1``4
-q4.B5!NZ9O~>
-!<E/rdefI0dK%#Zc2a^=I06=kJV!UA$CuUJSW1q?JUu+Cr-\sLcB3[\OdUp'NR"BuI06=kJV!^D
-!L8*4cMrIqcMrIqcMrIqcMrFrcDCGe"/X:oJbIChJcF$qJcF$qJIBc"IA+s3Kmh7lJV!UA#eG_@
-NI?N+I=;"<s+(6sJUROCs*apms+10p$,VsUI>ttdc@(t/cA^$K^AQCZ](q`o](XPPRJG82RJ##(
-RJbJ6XoNt~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!C<$ClIES;YY:K6tk=r-JgIc&74UPa$g%Mp8'qHNU(gK7!L?
-!L.s1bn#GRc-:lfc-:lfc-:lfc(t8a"/O1oHhP]!K6tkfK6tkfK6tk=H_ep2K6tkfK7!C<#ebkC
-MgL*$H[GY7"G;'GH[Gb:s*Odj!J>aubmD@RH[C[ac-:U"J^'.u!58<\!582u!58*V!1`l8!1``4
-q4.B5!NZ9O~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!C<%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?
-(8Q;rc-:lfc-:lfc-:lfc-:lfc)c8^r657pHhP]!K6tkfK6tkfK6tkEH^r@*H[F#^K7!C<$&a/T
-c%CYnK6t<0bmf;Pc%CA^c,G$^c-:lfr65JcUjIa=`I",+c&BmI^&6FTSG(J5SGC\8SG(M-SGgt=
-X8mb~>
-!<E/qdf#U1dK%#Zc2t.sU&<49Jb[M!\p]QhWm8n@J^1EHU&<1DTm_osWdTl#cE;Shr6G=nqp#tN
-IE'RXJUu+lJUu+lJUu+lJUu+LIA-Sas+0mhs+13qs+13qs+(R'Y'l_`b(4udc@LQAc3]J]b0G]p
-c@p\\r6G=n$dOTW`m2SPM9aCtJc*du`h@g7cGk:+J^05"!5ABZpR1a'!1EZ2!1EQ/pR2!.!NlEQ~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!C<%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?
-(8Q;rc-:lfc-:lfc-:lfc-:lfc)c8^r657pHhP]!K6tkfK6tkfK6tkEH^r@*H[F#^K7!C<$&a/T
-c%CYnK6t<0bmf;Pc%CA^c,G$^c-:lfr65JcUjIa=`I",+c&BmI^&6FTSG(J5SGC\8SG(M-SGgt=
-X8mb~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51
-c%CB?boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWn.K6tkfK6tkfK6tk^H[DQH
-H[F#^K7!C<*/f0FXF#<-XF#T$]r]2tK6su$H^)4.H`YK:K7!UB$)FrA[!R_U[!TK;c&BmI^&6FT
-SG(J5SGC\8SG(M3SH%.<SGgt=X8mb~>
-!<E/pcMs1*c2bTVapZ4CIAOBTZHA#P[`8-c,DCPo`lcGTJ]budIAOBTZHBV(IC?_8IC@;<Kmff+
-Y-Q3$Jc!S1\p^a(b(5,db(5,db(5,db)(PT_M*E7[]ZpYJV!gCs,$Wqs+13ms+13ms+(R#_L6j+
-M1'fpb(5-=arH7dWiCJq^8cU8Y-t@Ib)(PTV1"W?Q$oLOb(5-CapFcI^9W0Db-$0$J]`qo!5ABV
-pQbHt!1!B*!1!9'rK[E.rK[?,!NlEQ~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51
-c%CB?boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWn.K6tkfK6tkfK6tk^H[DQH
-H[F#^K7!C<*/f0FXF#<-XF#T$]r]2tK6su$H^)4.H`YK:K7!UB$)FrA[!R_U[!TK;c&BmI^&6FT
-SG(J5SGC\8SG(M3SH%.<SGgt=X8mb~>
-!<E/feH!;[bmMFSH[CCHc*W+M^%onSUjJ@*bn5STc-=4lH[CCHc-:T^c-:T^rlk_fP^@b0XNcBE
-qT]%us32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBErlkIrHi)&&K6tkfK6tkfK6tkfXFl/4K6tkf
-K7!C<(USgAS>:M%c)chMH],kf["E_=XFkkPXT$HFK7!UB#aBsgH^)LoMi3/2Mp278r7(e\q4%Gu
-p=8o-p!s)4rRLq<r7(hL!.Y~>
-!<E/fc2bTUapQ"NJUN6Tb-HSL](sJMTm`(&b5[%mar/']JUN6Tb/SjXb0#-\`lcH@Q%=@;Y0)<H
-qTAhts2t@ms2t@ms2t@ms2kbUJUtDLQ%=@;Y0)<HrlY7lqo\qis2t@ms2t@ms2kYNJVCC`J]c,d
-Jb[A([Y9.#Tm`?OWel.PM8%-<JUtD/KmeZTrlY7lrlPM3JUN*7^<2FpJ]`nn!5ABV!4M]g!4MUH
-pQbEss-<Q.s-<N-!NlEQ~>
-!<E/feH!;[bmMFSH[CCHc*W+M^%onSUjJ@*bn5STc-=4lH[CCHc-:T^c-:T^rlk_fP^@b0XNcBE
-qT]%us32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBErlkIrHi)&&K6tkfK6tkfK6tkfXFl/4K6tkf
-K7!C<(USgAS>:M%c)chMH],kf["E_=XFkkPXT$HFK7!UB#aBsgH^)LoMi3/2Mp278r7(e\q4%Gu
-p=8o-p!s)4rRLq<r7(hL!.Y~>
-!<E/feH!;Qc2)be^"(@/`Ik89blN0Dqp"ta!5714!j%$nJ^'+t!56>$!NZ9O~>
-!<E/fc2bTKb5-Md]%+q)_L\Q.ao]S2L&9$hI/pk6ao\So_L]jfaoK/oc2k'JJ,~>
-!<E/feH!;Qc2)be^"(@/`Ik89blN0Dqp"ta!5714!j%$nJ^'+t!56>$!NZ9O~>
-!<E/fblGGi`<!ZJdDZ<sPbbC=H^rC#!MmD[`JVV7]u8.rX8mb~>
-!<E/faoK/g`W<fIdDcC!OfGF@IA+s+!MR5Y`eqb9^;S.pXoNt~>
-!<E/fblGGi`<!ZJdDZ<sPbbC=H^rC#!MmD[`JVV7]u8.rX8mb~>
-!<E/fblGG7`<Er>K6r6HJ]32ZeAVF$`6A=a!.Y~>
-!<E/faoK/5`Wa)=JUN6GJ]<8\eA_L&`6&+`!.Y~>
-!<E/fblGG7`<Er>K6r6HJ]32ZeAVF$`6A=a!.Y~>
-!<E/fblGG.`IZ!Z`Ri'/]u8.rX8mb~>
-!<E/faoK/,`du-\`n/31^;S.pXoNt~>
-!<E/fblGG.`IZ!Z`Ri'/]u8.rX8mb~>
-!!%S&JV/N+K7a.(J,~>
-!!%S$JUrB'K7O"&J,~>
-!!%S&JV/N+K7a.(J,~>
-!<E0!joD3.s+13$s,I$^V#TT>]`<Q~>
-!<E0!joD*+s+13$s,I$^U&X9;\c@6~>
-!<E0!joD3.s+13$s,I$^V#TT>]`<Q~>
-!<E0!joD3.s+13$s,R*`K;AP0k.LbF~>
-!<E0!joD*+s+13$s,R*`JYE,+k.1PC~>
-!<E0!joD3.s+13$s,R*`K;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:AM?!<(XM!7T[#!;Y@K!!:jS!:eeC!9W#2!!_-W!8?-,!9W#8!<1^P
-!;Y@K!.ijTg?@8jJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:AM?!<(XO!7KU$!<:dQ!;bFL!!:jS!:eeC!9W#8!;bFL!<:dQ!9W#8
-!<1^P!;Y@K!.ijTg?@8jJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9=ec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<:dQ!!M!U!8?0*!<:dQ!<:dQ!<:dQ!<:dO!<:dQ
-!!:jS!;,"F!;kLK!<:dQ!!M!U!8?0*!<1^N!<:dO!<:dO!<:dQ!!:jS!;,"F!<(XO!!CpT!8@AO
-s4[DOs4[JQ!nmVSo\0<Frn@APs4[DOs4[JQ"kiqVg&M,(g4@uGgAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9=ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(N
-k2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Es4[JQ*81Amg&M-,g&M-,!!(a,!!(a,!!(^Q
-!8?-,!8@>No\0<Fr7_/Ns4[JQ+PHeqg&M-,!!(a,!!(^Q!8?-,!8?-,!8?-,!8?-,!8@>No\0<F
-rS%8O&)%!`g=cN,g=cN,g=cN,gACsCgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTg@*bqJH_bI
-k2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(N
-k2s>WJ,~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%n(%Gj"f21\k.LbF~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA_0QgA_-mg&M-,!!(a,!!(a,!!(^Q!87DQg=cN,
-g=cN,gAV*CgA_0NgA_0QgA_-`g&M-,!!(^Q!8?-,!87DQqqD&Ms4[JQs4[JQ!8@DPo%O!A'&!<c
-g&M-,g&M-,g&M-,g&M-,rW)NCq>_)\!!(a,!!(^Q!87DQg=cN,J_G\/n(Rem"ektYk.1PC~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%n(%Gj"f21\k.LbF~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^s5>s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo%F?Lg=cP\g&M-,qZ-ZMrr<;X!!(^Q!8?0(!!:jS!:eeC
-!;tRN!<:dQ!!_-W!87DQgA:jOg&M-MgA_0QgA_0QgA_-Sg&M-CgA_0OgA_-Yg&M-,g&M-,gA:jO
-g&M-CgA_0PgA_-QgA:jVg&M-,!!(a,!!%T(J_KSHs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^s5>s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[OeaM&gK*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQmb7U>s4[JQ!nmVSqqD&M$/,@Zg&M-,g&M-NgA_0CgA_0N
-gA_0QgA_-Yg&M-,!!(^Q!;tRN!;kLM!<:dQ!<:dQ!!:jS!:eeC!<(XO!".E[!8?-,!8?-,!;tRN
-!:eeC!<1^P!!:jS!;tRN!!_-W!8?-,!.ijTg@*bqJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[OeaM&gK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(Nk2s>W
-J,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,n_4!Crn@AP#20%Wg=cN,rn@APs4[JQrn@APs4[JQ
-!nmVSnCmmBs4[DOs4[JQ(tnrig&M-,!!(a,!!(^Q!8?-,!8?-,!8@DPs4[JQ!nmVSn_4!CrS%8O
-#MK.Xg=cN,gAV*PgA_-Sg&M-CgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTg@*bqJH_bIk2s5T
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(Nk2s>W
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%ma_>i"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:\_B!<1^P!<:dO!<(XO!<:dQ!<(XM!<:dQ!:SY?!<:dO
-!<:dQ!!M!U!8?0*!<1^N!<(XO!<:dO!<:dQ!:eeC!<(XO!!:jS!<1^P!<:dO!<:dQ!:eeC!<1^P
-!<:dO!<:dQ!!V'V!87DQJ_G\/mb7\l"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%ma_>i"f21\k.LbF~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+,fRK7SZ9K*A(Nk2s>WJ,~>
-!<E0!joV7Vs+,`PJUrB5JH_bIk2s5TJ,~>
-!<E0!joV@Ys+,fRK7SZ9K*A(Nk2s>WJ,~>
-!<E0!joM:XJV/N+JV/u8"f21\k.LbF~>
-!<E0!joM1UJUrB'JUri4"ektYk.1PC~>
-!<E0!joM:XJV/N+JV/u8"f21\k.LbF~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD*+g>Uc`!;>.H!;P:J!!:jS!;kLM!9`)9!.ijTg@<l#U&X9;\c@6~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD*+g>Ucc!<:dQ!;G4I!;5(G!;kLM!9`)9!.ijTg@<l#U&X9;\c@6~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD+Hg@kRBgA:l+gA_0PgA_0QgAM$OgAM$OgAM$OgA_-Sg&M-MgA_0NgAM$OgA_0PgA_0Q
-gAM$OgA_/(g4@uJg'+2Mk2s5TJ,~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+Hg@tUIJbe%"!/0)+!<1^P!#XDi!8?-,!8?-,!8?-,!8?-,!87DQg&M-MgA_0OgA_0Q
-gA_-Sg&M-PgA_-Zg&M-,g&M-,!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%n^Rf=s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_-Tg&M-,r;ciNr;clOquHcNr;`_KrrE&Prr<D[!!(a,!!(a,
-!!)oMrr<5V!!(^Q!;kLM!<(XO!<:dQ!<:dQ!"IW^!8?-,!8?-,!87DQJ_G\/n_+/?s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%n^Rf=s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0OgA1gLgA_-Wg&M-,g&M-OgA_-Wg&M-,g&M,NgA_0PgA_-QgA:mM
-gA_0PgACpSg&M-,!!)oMrrE#OqZ-ZMrr<2U!!(a,qZ$]O!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gACpNgAV*PgA_0QgA_-Wg&M-,g&M-PgA_0QgA_0QgA_/NgA_0PgA_-S
-g&M-MgA_0QgA_0QgA_-Vg&M-,!!)oMrrE#OrrDoLrW)rOrrDuNrr@W(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA:jMgA:mLg&M-PgA:lJgA_0QgA_0QgA_0QgA_0QgA_-Q
-gAV*PgA_-Vg&M-,!!)oMrrE#OrrE)QrrE&PrW)rOrrE)Qrr<,S!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0NgA_0MgA_0PgA_/JgACsLgAM$MgA_0QgAV'PgAM!Q
-g&M-MgA:jMgAM$Lg&M-NgAM$OgA_/(g4@uJg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%e("Vt
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0QgA_-Zg&M-,g&M-,!!)uOrrE)Qrr@W(J_G\/e(Ou!
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%e("Vt
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e^DtOV#TT>]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0OgAM$NgAM$OgACsNgAM#&g4@t/g="[YU&X9;\c@6~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e^DtOV#TT>]`<Q~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tTg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!e_em\V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0OgAM$NgAM#&g>CTfU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!e_em\V#TT>]`<Q~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tpgAM$NgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\Y
-eHMcKk2s>WJ,~>
-!<E0!joD+Hg@kRBgA_0PgA_-Sg&M-NgA_0FgA:m1gA(`"g8is-!<1^P!<:dQ!!_-W!8?-,!.ik^
-g'+2Mk2s5TJ,~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\Y
-eHMcKk2s>WJ,~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#e_ns]
-V#TT>]`<Q~>
-!<E0!joD+Hg@tUIJbe%"!<1^P!;Y@K!;,"F!8Q<.!.ik&gA_0PgA_0QgA_-Wg&M-,g&M,(g>LZg
-U&X9;\c@6~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#e_ns]
-V#TT>]`<Q~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!hphn+s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#Orr</T!!(aO!<:aR!8@DP
-!8@DPp"KEGrS%2MJ_I?^rrE#Or;ciNr;_E&hqA7-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!hphn+s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XJ!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA1d\g&M-,!!(a,!!(^Q!8?-,!;kLJ!!(aP!<:dQ!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/J_L+W"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<(XO!<1^P!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<(XO!<1^P!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/J_L+W"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XO!<1^P!<:dQ!".E[
-!8?-,!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^rr6"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#OrrE#Or;clOrrE)QrrE)Q
-rrDcHrrE#Or;bI'JUtXgJ_K;@"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^rr6"f21\k.LbF~>
-!<E0!joD4Kec5[EK7VPQeU`@iK)kq&e`YHdV#TT>]`<Q~>
-!<E0!joD+HgAh3JJUuMTg4=glJH5_$g?7/nU&X9;\c@6~>
-!<E0!joD4Kec5[EK7VPQeU`@iK)kq&e`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#B!Be`YHdV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_VtNGg?7/nU&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#B!Be`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&e`YHdV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_W:^uJcGb$g?7/nU&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&e`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^rr6"f21\k.LbF~>
-!<E0!joD+Hg@kRBgA_0PgA_-Sg&M-NgA_0FgA_0PgA_0KgA_/^gAc_T_W/N5s7P(HJcGDss+14M
-J_K;@"ektYk.1PC~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^rr6"f21\k.LbF~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-kLBa3s5rIW!.Y~>
-!<E0!joD+Hg@tUIJbe%"!<1^P!;Y@K!;,"F!<1^P!;Y@K!4U\^JUt\u_Z0Z/g&Zd)p"KFss8RZ(
-kLp*5s5rIT!.Y~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-kLBa3s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&e`YHdV#TT>
-]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE&Prr<_d!!(^Q!8?-,!8?-,
-!87DQg&M-PgAM$OgA_0QgA_0QgA_-Vg&M-,!!(a,s+,a<j21irp"BFts7P+GJcGb$g?7/nU&X9;
-\c@6~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&e`YHdV#TT>
-]`<Q~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#kLBa3
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<1^P!!(aP!".E[!87DQ
-g&M-,gAV'eg&M-,!!(a,!!(^Q!8?-,!8?-,!8@DP!nmVSgY2[YJ\pHas8V_B!<;YAs8RZ(kLp*5
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#kLBa3
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^rr6"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA1d\g&M-,!!(a,!!(^Q!8?-,!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,a<j2(frjFR@2J_K;@"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^rr6"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<kLBa3s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,b$_uG;AkLp*5s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<kLBa3s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^rr6"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<1^P!%ln)!8?-,!87DQg&M-,
-g&M-,g&M-,!!(a,!!(a,!!(^Q!87DQg=cN,g=cN,gY)XYJcEUeJ_K;@"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^rr6"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;bFL!$Bnp!8?-,!8?-,!87DQ
-g=cN,g&M-,g&M-,!!(a,!!*#PrrE)QrrE&PrrE)Qrr@W(J_G\/"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;cZIquHcNrrE)Qrr<,S!!*#Pr;clO
-rrE)Qr;cfMrrE)QrrE&PrrE)Qrr@W(J_G\/"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tTg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^mbKDX1&V#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<TlJc".)U&X9;\c@6~>
-!<E0!joD3.eUc8%eY^mbKDX1&V#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^mcK)krKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<TmJH5`Ig'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^mcK)krKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jbm4`Jbm7`s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD*+g4@t/g8<U(Jc!:bs+1$`s8VuM"ektYk.1PC~>
-!<E0!joD3.eUc8%eY^msKDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD3.eUc8%eY^msKDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(Jc!:cs+,au_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msKDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(Jc*Cbs8RZI_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc*CbrrUo*Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc3Ics8UgQJc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc3Ics8LaPJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc<Ods8C[OJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc<Ods8:UNJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcEUes81OMJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcEUes8(ILJcEUes81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD3.e`>9\s7OqBs8CLJs0^AWs,,A,s7=e@s0'uQK*&ads7t4FKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD*+g>puf!;5(G!<(XO!4CM\!/fM1!;"qE!3b,VJHE^gs7tCKJcEUes81LRU&X9;\c@6~>
-!<E0!joD3.e`>9\!;4nB!<(IJ!4C>W!/f>,!;"b@!3arQK*&ads7t4FKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD4Lec5[Lec#LJeboFOec5["s8UXKs8UXLs8UXLrrCUIrrCUKs-hI<s7FhAs8:CIs0^AW
-s,#8+s74\?s0'uQK*&ads7k.EK*&ads81=MV#TT>]`<Q~>
-!<E0!joD+IgAe#LgARiJgAIcOg81Y"V5;oFV>o9LV>o9LV#]6IV#]6KV4-*<!;+tF!;tON!4CM\
-!/]D0!:nhD!3b,VJHE^gs7k=JJHE^gs81LRU&X9;\c@6~>
-!<E0!joD4Lec,XLeboIJebfCOeGoU"!!(RK!<:UL!<:UL!!(RI!!(RK!1MF<!;+eA!;t@I!4C>W
-!/]5+!:nY?!3arQK*&ads7k.EK*&ads81=MV#TT>]`<Q~>
-!<E0!joD4KeIMW0ec41Ms4,["e^a]Ms8LOVs4,["e^a]Mec42"rm_5Qe^a]Mec2r*s8NATs4,["
-s4./LpsoBDs4.,KrRLrJr7(fIr7(fI[ak?Vs4%/Mec,RMec5[KeH>j%s8W&Jrr;iFs8N,Ms8CLJ
-rrgmPec42!s1Hk^s8CLJs8CLJs8LONs4./LqUPWG!S.5Kec5XPec42"ec,Tlec1:%s7M!G^&S-0
-eHMcKk2s>WJ,~>
-!<E0!joD+Hg('t5g83NWV:sY"g=iCWV>f0VV:sY"g=iCWg83N"rn7RQg=iCWg82+/rr<>Y!8?-,
-!87DQptG]Is4[GPrS%8Or7V,Nr7V,N[bCZ[s4RJRgAV'Rg&M-Pg&h?/!!)uOrW)fKrr<)R!<(XO
-!!M!Ug&Tk+!5."c!<(XO!<(XO!<1[S!87DQqV(rL!SRPPgA_-Ug&Th,gAV)qgAca(s7LpE_Z0Z5
-g'+2Mk2s5TJ,~>
-!<E0!joD4KeIDT0eH".M!7fU"e^XZM!<1LV!7fU"e^XZMeH","rm_2Qe^XZMeGuo*rr<>T!7fU"
-!7_&Lpso?Ds4.)KrRLoJr7(cIr7(cI[ak<Vs4%,Mec#OMeGoUKeH5g%!!)uJrW)fFrr<)M!<(IJ
-!!LgPeH"/!!5-h^!<(IJ!<(IJ!<1LN!7_&LqUPTG!S%2Kec,UPeH","ec#Qlec1:%s7M!G^&S-0
-eHMcKk2s>WJ,~>
-!<E0!joD4KeIDQ/ec41Ms8UXLe^a^"rRLrJ'@m-5ec41Ms4./"s4./"ec5["s0C/^s4./"s4,["
-e^a]qeH#XIeHu9+ec41Ms4,["rRCoJr7(fI[FG9Wr7(fIqpb]Hrm_5Qe^a]Mec5Bo$NJZVec41M
-s4,["rm_#K\^^][rm_MYe^a]Mec41Ms4,["ec5Hq$NJZVec41Ms4,["rm_#KaOU<C!<;YCs8VuH
-"f21\k.LbF~>
-!<E0!joD+Hg'sn4g83NWV5;nBg=iC"rS%:J'AB;:g83NWV:qd"V:qd"g81Y"V6\e^!87G,!8?-,
-g=cQ&g&M-Ng'Ic5g&Tj\!8?-,rRq5Or7V,N[FtT\r7V,Nqq;#Mrn7PVg=cP\g&Um$$38c[g&Tj\
-!8?-,rn7>P\_7#`rn7h^g=cP\g&Tj\!8?-,g&Us&$38c[g&Tj\!8?-,rn7>PaP-ZF!<;YAs8VuM
-"ektYk.1PC~>
-!<E0!joD4KeI;N/eH".M!!(OLe^XX"rRLoJ'@d*5eH".M!7_)"!7_)"eGoU"!4(,^!7_)"!7fU"
-e^XZqeGoUIeHl6+eH".M!7fU"rRClJr7(cI[FG6Wr7(cIqpbZHrm_2Qe^XZMeH#?o$38TVeH".M
-!7fU"rm^uK\^^Z[rm_JYe^XZMeH".M!7fU"eH#Eq$38TVeH".M!7fU"rm^uKaOU<C!<;YCs8VuH
-"f21\k.LbF~>
-!<E0!joD4KeIMW0ec41Ms4./Le^a]Ms8LO`s4./Le^a]Mec42"ec42"e^a]Ms8TCT$NJZVec41M
-s4,["psoEErm_2Pe^a]Mec,UHeH#XIeH#WWeH#XIeH#XJec,UJeH>j%ec5X!s8VoF$NJZVec41M
-s4,["rm_#K\^^][rm_5Qe^a]Mec5Qts8VlE$NJZVec41Ms4,["rm_#KaOU<Co"G)'qpbkGs5rIW
-!.Y~>
-!<E0!joD+Hg('t5g83NWV:qcBg=iCWV>f0`V:qcBg=iCWg83N"g83N"g=iCWV5:KO$38c[g&Tj\
-!8?-,ptG`Jrn7MUg=cP\gAV*Mg&M-Ng&M,\g&M-Ng&M-OgAV*Og&h?/g&V-+rrDlK$38c[g&Tj\
-!8?-,rn7>P\_7#`rn7PVg=cP\g&V')rrDiJ$38c[g&Tj\!8?-,rn7>PaP-ZFo"tG,qq;4Is5rIT
-!.Y~>
-!<E0!joD4KeIDT0eH".M!7_&Le^XZM!<1L`!7_&Le^XZMeH","eH","e^XZM!!'=T$38TVeH".M
-!7fU"psoBErm_/Pe^XZMec#RHeGoUIeGoTWeGoUIeGoUJec#RJeH5g%eH#U!rrDlF$38TVeH".M
-!7fU"rm^uK\^^Z[rm_2Qe^XZMeH#NtrrDiE$38TVeH".M!7fU"rm^uKaOU<Co"G)'qpbkGs5rIW
-!.Y~>
-!<E0!joD4KeKFnBec41Ms4,["e^a]Mec41Ms4,["e^a]Mec41Ms4./KeH>j%ec2r*$NJZVec41M
-s4,["p=0TOe^a]Mec41Ms4,["rRCoJr7(fI[FGK]e^a]Mec5X!"96p%s8LONs4,["r7(fIqUGrQ
-ec42"e^a]Mec5X!!<9U[!<<&K%fb)0s4,["e^a]Mec42"q:,iPec42"e^a]Mec5X!!<:-js+Bh@
-qpbkGs5rIW!.Y~>
-!<E0!joD+Hg*!6Gg83NWV:sY"g=iCWg83NWV:sY"g=iCWg83NWV:qdFg&n2*g82+/$38c[g&Tj\
-!8?-,p=]oTg=cP\g&Tj\!8?-,rRq5Or7V,N[Ftfbg=cP\g&V-+!s%'/!<1[S!8?-,r7V,NqUu8V
-g&Th,g=cP\g&V-+!!'R`!!*#P%KP5:!8?-,g=cP\g&Th,q:Z/Ug&Th,g=cP\g&V-+!!(*os+0\>
-qq;4Is5rIT!.Y~>
-!<E0!joD4KeK=kBeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7_)KeH5g%eGuo*$38TVeH".M
-!7fU"p=0QOe^XZMeH".M!7fU"rRClJr7(cI[FGH]e^XZMeH#U!!s$m%!<1LN!7fU"r7(cIqUGoQ
-eH","e^XZMeH#U!!!'R[!!*#K%KP&0!7fU"e^XZMeH","q:,fPeH","e^XZMeH#U!!!(*js+Bh@
-qpbkGs5rIW!.Y~>
-!<E0!joD4Jec5[Lec5[LeH,^#rr<#Krr<#K!<<&Ks8W)K$3/QUe^a^"e^a]*eHu9+s4./Le^a^"
-psoBDs4.,K#1`bRe^a^"rmgrH!7h#I[akEXs4.)Js4./L!nI>$rr3)Ns8UXKs7t1Ms4./"s8UX"
-rr<#KrVsR]r;ZfIs8W&Js8W,Ls8N/Ns8VrG#QN?Sec5["ec,UKec#Njec19nrrRiQs81=MV#TT>
-]`<Q~>
-!<E0!joD+GgAe#LgAe#Lg&\&(rh]YKrh]YK!2]\Ks/#_K$)Q@Pg=iC"g=iC/g'Ic5!87DQg=cN,
-ptG]Is4[GP#20%Wg=cN,rn@8M!8@>N[bC`]s4[DOs4[JQ!nmY.rW!&S!!(aP!;Y=R!87G,!!(a,
-rW)uPr;aObquHcNrrE#OrrE)Qrr<,S!!)lL#6<HXg&M-,gAV*PgAM#ogAc`qrrRcOs81LRU&X9;
-\c@6~>
-!<E0!joD4Jec,XLec,XLeH#[#rW)uKrW)uK!!*#KrrE&K#lrKUe^XX"e^XZ*eHl6+!7_&Le^XX"
-pso?Ds4.)K#1W\Re^XX"rmgoH!7guI[akBXs4.&Js4.,L!n@;$rW!&N!!(RK!;Y.M!7_)"!!(R"
-rW)uKr;aO]quHcIrrE#JrrE)Lrr<,N!!)lG#6<9SeGoU"ec#RKeboKjec19nrrRiQs81=MV#TT>
-]`<Q~>
-!<E0!joD3.eb%Als+/_]eH#W2eH#Wfec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD*+g@X)!!.ikbg&M,7g&M,kgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD3.eb%Al!.i\]eGoT2eGoTfec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD3.eb7Pns8CLFs+/`!ebfCCec,T@ebfCCec,Tdec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD*+g@j8#!<(XK!.il&gA:mHgAV)EgA:mHgAV)igAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD3.eb7Pn!<(IF!.i]!eb]@Cec#Q@eb]@Cec#Qdec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uDKE(uKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(JcGcBJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msKE(uDKE(uKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msK)krCKE(uKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(JH5`AJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msK)krCKE(uKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X;eH#X=eH#X7eH#WjeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-@g&M-Bg&M-<g&M,og&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU;eGoU=eGoU7eGoTjeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X;eH#X=eH#X7eH#WjeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-@g&M-Bg&M-<g&M,og&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU;eGoU=eGoU7eGoTjeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec,UKec#OJec5[JeH,^#rr2uKrVuZCs8W,Ls8N5Ps8UX"rVulIs8W)K
-!WU^Ls4>d$s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-FgAV*PgAM$OgA_0Og&V3-rVurPr;cWHrrE)Qrr<2U!!(a,r;ciNrrE&P
-!<CjQ!8#p)!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUAec#RKeboLJec,XJeH#[#rVurKr;cWCrrE)Lrr<2P!!(R"r;ciIrrE&K
-!<C[L!8#a$!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeH#XHeH#XHeH#XJeH#XIeH#XDeHu9+ec41Ms4,["rm_#KrRD#Me^a^!
-eH#X!eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg&M-Mg&M-Mg&M-Og&M-Ng&M-Ig'Ic5g&Tj\!8?-,rn7>PrRq>Rg=cQ+
-g&M-&g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeGoUHeGoUHeGoUJeGoUIeGoUDeHl6+eH".M!7fU"rm^uKrRCuMe^X[!
-eGoU!eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec5[JeH#XJec,UIeH#XIeH#XDeHu9+ec41Ms4,["rm_#KrRLoIrRCoJ
-eC=R!MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgA_0Og&M-OgAV*Ng&M-Ng&M-Ig'Ic5g&Tj\!8?-,rn7>PrS%5NrRq5O
-eCjm&MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec,XJeGoUJec#RIeGoUIeGoUDeHl6+eH".M!7fU"rm^uKrRLlIrRClJ
-eC=O!MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X?eH#XKeHc-)ec5["ec5Tu!<;uI"96p%s8(7Ps4,["e^a]Mec5X!#liH*
-s4./"ec5X!!<:R!!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Dg&M-Pg'7W3g&M-,g&V**!!)rN!s%'/!;bCU!8?-,g=cP\g&V-+#QWT4
-!87G,g&V-+!!(O&!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoU?eGoUKeHZ*)eGoU"eH#Qu!!)rI!s$m%!;b4P!7fU"e^XZMeH#U!#QWE*
-!7_)"eH#U!!!(O!!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBec,UHec5[Lec5XOec41MrVuiHs8VlEs8W&Js8N,Ms8LRKs8LRKs8LRI
-s45^#s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-GgAV*MgA_0QgA_-Tg&Tj\r;cfMrrDiJrrE#Orr<)R!<1^P!<1^P!<1^N
-!7oj(!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBec#RHec,XLec,UOeH".Mr;cfHrrDiErrE#Jrr<)M!<1OK!<1OK!<1OI
-!7o[#!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X%ebfBWeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-*gA:l\g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU%eb]?WeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gAM$Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gAV*Mg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XHeH#XIec5Z`eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Mg&M-NgA_/eg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUHeGoUIec,W`eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XAeH#W`eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Fg&M,eg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUAeGoT`eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XCeH>j%s8W&Js8W,L"om-Qec5[Gec#OIec5[Jec,T_eH#W,eH#WHec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Hg&h?/!!)uOrrE)Q"T[6Vg&M-LgAM$NgA_0OgAV)dg&M,1g&M,MgAc`p
-_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUCeH5g%!!)uJrrE)L"T['QeGoUGeboLIec,XJec#Q_eGoT,eGoTHec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeIV]1ec41Ms4,["ec42"ec5Ep!<;rH!<<&K"96p%s1["`s,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg(+2;g&Tj\!8?-,g&Th,g&Up%!!)oM!!*#P!s%'/[email protected]!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeIMZ1eH".M!7fU"eH","eH#Bp!!)oH!!*#K!s$m%!5?t`!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeHQ!'ec41Mrr<#K"TR$Pec5Ep!<;rH!<<&K"96p%s1["`s,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg'%K1g&Tj\rW)uP"9@-Ug&Up%!!)oM!!*#P!s%'/[email protected]!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeHGs'eH".MrW)uK"9?sPeH#Bp!!)oH!!*#K!s$m%!5?t`!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeIMW0ec41Ms4,["e^a]Ms7b%Gs4,["rm_#Krm_,Ne^a]6eH#W,eH#WH
-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg(",:g&Tj\!8?-,g=cP\!;G1L!8?-,rn7>Prn7GSg=cP@g&M,1g&M,M
-gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeIDT0eH".M!7fU"e^XZM!;G"G!7fU"rm^uKrm_)Ne^XZ6eGoT,eGoTH
-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XCec,RQec5["ec5[KeH5d$s7Y"Cs8UXIs8UXLrrL[M^XW>aMU__,VUb^!
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-HgAV'Vg&M-,g&M-Pg&_9.!;>.H!<:dN!<:dQ!!1dR^Y/YfMV8%1VV;'$
-o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUCec#OQeGoU"eGoUKeH,a$!;=tC!<:UI!<:UL!!1UM^XW;aMU_\,VUb^!
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X1ebfBKeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-6gA:lPg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU1eb]?KeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$eb]?0eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gA:l5g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$eb]?0eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$ebfE0eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gACr5g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$ebfE0eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#X*eH#XJeH#X=ec5[@ec5[2eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-/g&M-Og&M-BgA_0EgA_07g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoT,eGoUAeGoU*eGoUJeGoU=ec,X@ec,X2eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#W,eH#XAeH#X%eH#X<eH#X?eH#X2eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-*g&M-Ag&M-Dg&M-7g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoU%eGoU<eGoU?eGoU2eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBec#OJeH,^#r;QiKs8VrG#liHTec5["s4.,Ks4./LrmguIrmh&Kp=00C
-rRLrJrRLrJrm_,Nec5[5eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-GgAM$Og&V3-qu?fP!!)lL#QWQYg&M-,!8@DPs4[JQrn@;Nrn@APp=]KH
-rS%8OrS%8Orn7GSg&M-:g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeboLJeH#[#qu?fK!!)lG#QWBTeGoU"!7h&Ks4.,LrmgrIrmh#Kp=0-C
-rRLoJrRLoJrm_)NeGoU5eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XIeH#XJeH>j%ec5Kr"TR$Pec5X!!<;rH!<<#J!<<#J"96p%s7b%D
-s8LOYs4,["e^a]Mec41Ms4./4eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Ng&M-Og&h?/g&V!'"9@-Ug&V-+!!)oM!!)uO!!)uO!s%'/!;G1I
-!<1[^!8?-,g=cP\g&Tj\!87G9g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoUIeGoUJeH5g%eH#Hr"9?sPeH#U!!!)oH!!)uJ!!)uJ!s$m%!;G"D
-!<1LY!7fU"e^XZMeH".M!7_)4eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XIeH#XJeH>j%ec5Kr"TR$Pec5X!!<;rH!<<#J!<<#Jrr;]B!<<&K
-#636(s4,["r71iIk1'J3MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Ng&M-Og&h?/g&V!'"9@-Ug&V-+!!)oM!!)uO!!)uOrW)ZG!!*#P
-"p!B2!8?-,r7_/Nk1Te8MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAeGoUIeGoUJeH5g%eH#Hr"9?sPeH#U!!!)oH!!)uJ!!)uJrW)ZB!!*#K
-"p!3(!7fU"r71fIk1'G3MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XAeHZ'(ec41Ms8CIMs4,["q:,QHec5Tu!<;rH!<<#J#liH*s4./"ec5Bo
-!<<&K%fb)0s4,["e^a]Mec42"kLBS4MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Fg'.Q2g&Tj\!<(UR!8?-,q:YlMg&V**!!)oM!!)uO#QWT4!87G,g&Um$
-!!*#P%KP5:!8?-,g=cP\g&Th,kLon9MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAeHQ$(eH".M!<(FM!7fU"q:,NHeH#Qu!!)oH!!)uJ#QWE*!7_)"eH#?o
-!!*#K%KP&0!7fU"e^XZMeH","kLBP4MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X@ec5[Lec#OIec5[EeH5d$s8LRIs8UXIs8LRKs8LRKs7k.Bs8UXLs8CLJ
-s8UXLrrUaNs6.u5s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-EgA_0QgAM$NgA_0Jg&_9.!<1^N!<:dN!<1^P!<1^P!;P:G!<:dQ!<(XO
-!<:dQ!!:jS!9i,:!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoU@ec,XLeboLIec,XEeH,a$!<1OI!<:UI!<1OK!<1OK!;P+B!<:UL!<(IJ
-!<:UL!!:[N!9hr5!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#X5eH#WFeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-:g&M,Kg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU5eGoTFeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X7ec5[JebfC,ebfBoeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-<gA_0OgA:m1gA:ltg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU7ec,XJeb]@,eb]?oeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gAM$Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*%rec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gAV*Mg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XBec5Z`eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-GgA_/eg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUBec,W`eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XAeH#W`eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Fg&M,eg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUAeGoT`eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec5XPec42"ec,RMec5[KeH>j%s8W)KrVulIs8W&Jrr9^_!<7r,!<8qH
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-FgA_-Ug&Th,gAV'Rg&M-Pg&h?/!!*#Pr;ciNrrE#OrW'[d!!%o1!!&nM
-s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAec,UPeH","ec#OMeGoUKeH5g%!!*#Kr;ciIrrE#JrW'[_!!%o,!!&nH
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<;rH!<<&K"96p%s8LOKs8CISs4,["e^a]Mec3A6!<7r,
-!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!)oM!!*#P!s%'/!<1[P!<(UX!8?-,g=cP\g&Sk@!!%o1
-!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!)oH!!*#K!s$m%!<1LK!<(FS!7fU"e^XZMeH!>6!!%o,
-!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<<#Jrr;uJ"96p%s8LOKs8CLIs8LONs4,["^=<5`MU__,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!)uOrW)rO!s%'/!<1[P!<(XN!<1[S!8?-,^=iPeMV8%1
-VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!)uJrW)rJ!s$m%!<1LK!<(II!<1LN!7fU"^=<2`MU_\,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<<&K"96p%s8LONs4,["rm_MYe^a]Ms4,["e^a]Mec3A6
-!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!*#P!s%'/!<1[S!8?-,rn7h^g=cP\!8?-,g=cP\g&Sk@
-!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!*#K!s$m%!<1LN!7fU"rm_JYe^XZM!7fU"e^XZMeH!>6
-!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAec,UKec#OJec5XNec42!rrUaNs8LRKs8LRKs8CLJrrL[M^XW>aMU__,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgAV*PgAM$OgA_-Sg&Tk+!!:jS!<1^P!<1^P!<(XO!!1dR^Y/YfMV8%1
-VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec#RKeboLJec,UNeH"/!!!:[N!<1OK!<1OK!<(IJ!!1UM^XW;aMU_\,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X?eH#W<eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Dg&M,Ag&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU?eGoT<eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBec,T:eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-GgAV)?g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBec#Q:eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$eb]?0eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gA:l5g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$eb]?0eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*%rec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH5d$ebfE0eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gACr5g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$ebfE0eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X@ec,X&eGoUJeGoTjeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-EgA_0+g&M-Og&M,og&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU@ec5[&eH#XJeH#WjeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X?eGoU!eGoTjeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Dg&M-&g&M,og&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU?eH#X!eH#WjeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec#RJec,XDec,XJec,XLec,USeH".M!!(OLrRLoJrmgrIb1-LlMU__,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgAV*OgA_0IgA_0OgA_0QgA_-Xg&Tj\!!(^QrS%8Orn@;Nb1ZgqMV8%1
-VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec,UJec5[Dec5[Jec5[Lec5XSec41Ms8UXLrRLrJrmguIb1-IlMU_\,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XBeHl6+eH".M!7fU"q:-2[e^XZMeH".M!7_)"!7_)"!7_)"!<(FJ!<(FJ
-!6E[js,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,q:ZP`g=cP\g&Tj\!87G,!87G,!87G,!<(UO!<(UO
-!6Ejo!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeHu9+ec41Ms4,["q:-5[e^a]Mec41Ms4./"s4./"s4./"s8CIJs8CIJ
-s2`^j!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeHl6+eH".M!7fU"q:,HFr7);Xe^XZM!7_)"!7_)"!7_)JeGoUJeGoTj
-eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,q:YfKr7VY]g=cP\!87G,!87G,!87GOg&M-Og&M,o
-g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeHu9+ec41Ms4,["q:,KFr7)>Xe^a]Ms4./"s4./"s4./JeH#XJeH#Wj
-eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeHl6+eH".M!7fU"q:-2[e^XZMeH".M!7_)"!7_)"!7_)"!<(FJ!<(FM
-!7fU"bLHUmMU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,q:ZP`g=cP\g&Tj\!87G,!87G,!87G,!<(UO!<(UR
-!8?-,bLuprMV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUBeHu9+ec41Ms4,["q:-5[e^a]Mec41Ms4./"s4./"s4./"s8CIJs8CIM
-s4,["bLHRmMU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XAec,UQeH".M!!)cDrrE#JrrE)L!s$jOec#OPeH","!7guIrmh#Kb1-Ll
-MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgA_-Vg&Tj\!!)cIrrE#OrrE)Q!s%$TgAV'Ug&Th,!8@>Nrn@APb1Zgq
-MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec5XQec41Ms8ViDs8W&Js8W,L"96pOec,RPec42"s4.&Irmh&Kb1-Il
-MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X7eb]?EeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-<gA:lJg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU7ebfBEeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X5ec5[,eH#XHeH#XIec5[#eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-:gA_01g&M-Mg&M-NgA_0(g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU5ec,X,eGoUHeGoUIec,X#eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X4eH#X,eH#XAeH#X#eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-9g&M-1g&M-Fg&M-(g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU4eGoU,eGoUAeGoU#eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeH,^#rr<#Ks8W#I!<<#Js8W)Ks8W#Irr;uJs8VlErVulIs8W&Jrr:R"
-!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&V3-rW)uPrrDuN!!)uOrrE&PrrDuNrW)rOrrDiJr;ciNrrE#OrW(O'
-!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH#[#rW)uKrrDuI!!)uJrrE&KrrDuIrW)rJrrDiEr;ciIrrE#JrW(O"
-!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAeH#XJeH>j%ec5Tu!<<&K"96p%s8CIJs8LOKs8:CLs4,["psfBEqpb]H
-rm_,Ne^a]NeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Og&h?/g&V**!!*#P!s%'/!<(UO!<1[P!;tOQ!8?-,pt>]Jqq;#M
-rn7GSg=cPXg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoUJeH5g%eH#Qu!!*#K!s$m%!<(FJ!<1LK!;t@L!7fU"psf?EqpbZH
-rm_)Ne^XZNeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XJec,UHeH#XKec,UJec,UIec5[Kec,UCeH#XHeH#XKeH>j%ec44N
-!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Fg&M-OgAV*Mg&M-PgAV*OgAV*NgA_0PgAV*Hg&M-Mg&M-Pg&h?/g&T^X
-!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAeGoUJec#RHeGoUKec#RJec#RIec,XKec#RCeGoUHeGoUKeH5g%eH"1N
-!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAeH#XJeH>j%ec5Tu!<<&K#liH*s4./"ec5Ns#636(s4,["psfKHe^a^!
-eH#XKeH>j%ec44N!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Og&h?/g&V**!!*#P#QWT4!87G,g&V$("p!B2!8?-,pt>fMg=cQ+
-g&M-Pg&h?/g&T^X!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAeGoUJeH5g%eH#Qu!!*#K#QWE*!7_)"eH#Ks"p!3(!7fU"psfHHe^X[!
-eGoUKeH5g%eH"1N!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBec#OIec5[KeboIIec5[Kec5XOec41Mrr;rIs8VfCs8W,Lr;ZfIs8N,M
-s4>d$s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-GgAM$NgA_0PgACsNgA_0PgA_-Tg&Tj\rW)oNrrDcHrrE)QquHcNrr<)R
-!8#p)!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeboLIec,XKebfFIec,XKec,UOeH".MrW)oIrrDcCrrE)LquHcIrr<)M
-!8#a$!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#WnebfBceH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,sgA:lhg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoTneb]?ceGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gAM$Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*%rec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gAV*Mg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X@ec5[Eec5[DeH#X=eH#X%eH#XHeH#X@eH#W,eH#WHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-EgA_0JgA_0Ig&M-Bg&M-*g&M-Mg&M-Eg&M,1g&M,MgAc`p_Z0Z5g'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoT,eGoU@ec,XEec,XDeGoU=eGoU%eGoUHeGoU@eGoT,eGoTHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#W,eH#X?eH#XDeH#XDeH#X=eH#X%eH#X9eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&Rt,g&M-Dg&M-Ig&M-Ig&M-Bg&M-*g&M->g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoT,eGoU?eGoUDeGoUDeGoU=eGoU%eGoU9eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#W,eH#XAec,UJec5[IeH#XJec5[Kec#OIec5[Eec#OJeH,^#rr3&Ms8W)K"96pO
-s8CLIs8UXLs8:FIs8LRIs8LRKs8CLJs8UURs4./Le^a\WeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-FgAV*OgA_0Ng&M-OgA_0PgAM$NgA_0JgAM$Og&V3-rW!#R!!*#P!s%$T
-!<(XN!<:dQ!;tRN!<1^N!<1^P!<(XO!<:aW!87DQg=cOag&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAec#RJec,XIeGoUJec,XKeboLIec,XEeboLJeH#[#rW!#M!!*#K!s$jO
-!<(II!<:UL!;tCI!<1OI!<1OK!<(IJ!<:RR!7_&Le^XYWeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeHu9+ec41Ms4,["rRCoJrm_,Ne^a^!eH#XJeH>j%ec5Ep!<;uI!<;rH
-!<<&K#636(s4,["qUGTGrm_,Ne^a^!eH#XHeH#XKeI2E-ec41Ms4,["ec1NW!<8qHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ+g&M-Og&h?/g&Up%!!)rN!!)oM
-!!*#P"p!B2!8?-,qUtoLrn7GSg=cQ+g&M-Mg&M-Pg'[o7g&Tj\!8?-,g&R#a!!&nMs+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeHl6+eH".M!7fU"rRClJrm_)Ne^X[!eGoUJeH5g%eH#Bp!!)rI!!)oH
-!!*#K"p!3(!7fU"qUGQGrm_)Ne^X[!eGoUHeGoUKeI)B-eH".M!7fU"eGtKW!!&nHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeHQ!'ec41Mrr;oH!<<&Krr;rI!<<#Jrr;`C!<;uI!<<#Jrr;uJ"96p%
-s8LRKs8LRJs8LOKs81=Hs81=Hs8LOVs4,["e^a]Mec42"MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Gg'%K1g&Tj\rW)lM!!*#PrW)oN!!)uOrW)]H!!)rN!!)uOrW)rO!s%'/
-!<1^P!<1^O!<1[P!;kIM!;kIM!<1[[!8?-,g=cP\g&Th,MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUBeHGs'eH".MrW)lH!!*#KrW)oI!!)uJrW)]C!!)rI!!)uJrW)rJ!s$m%
-!<1OK!<1OJ!<1LK!;k:H!;k:H!<1LV!7fU"e^XZMeH","MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XBeHu9+ec41Ms4,["rRCoJrm_,Ne^a^!eHl3*ec42"e^a]peHZ'(ec41M
-s8LONs4,["rm_,Ne^a]teHQ!'s4,["rm_,Ne^a^!eH>j%ec5X!!<<&K$iec-s4,["e^a]Ms,,>,
-s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ+g'@]4g&Th,g=cQ%g'.Q2g&Tj\
-!<1[S!8?-,rn7GSg=cQ)g'%K1!8?-,rn7GSg=cQ+g&h?/g&V-+!!*#P$NSo7!8?-,g=cP\!/fJ1
-!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeHl6+eH".M!7fU"rRClJrm_)Ne^X[!eHc0*eH","e^XZpeHQ$(eH".M
-!<1LN!7fU"rm_)Ne^XZteHGs'!7fU"rm_)Ne^X[!eH5g%eH#U!!!*#K$NS`-!7fU"e^XZM!/f;,
-!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XAec5XQec41Ms8W)Kr;ZfIs8W#Is8W)Ks8VfCs8W,LrVuoJs8N/Ns4.,K
-"4dGOec,UJec5XMec5X!s8W#Is8W,Lr;ZfIs8W,Lrr2uKrr7l+!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-FgA_-Vg&Tj\!!*#PquHcNrrDuNrrE&PrrDcHrrE)Qr;clOrr<,S!8@DP
-"53_TgAV*OgA_-Rg&V-+rrDuNrrE)QquHcNrrE)QrVurPrW%i0!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAec,UQeH".M!!*#KquHcIrrDuIrrE&KrrDcCrrE)Lr;clJrr<,N!7h&K
-"4[AOec#RJec,UMeH#U!rrDuIrrE)LquHcIrrE)LrVurKrW%i+!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#WtebfB]eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-$gA:lbg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoTteb]?]eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gAM$Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gAV*Mg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X4ec,X9eGoT^eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-9gA_0>g&M,cg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU4ec5[9eH#W^eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X3eGoU9eGoT^eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-8g&M->g&M,cg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU3eH#X9eH#W^eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec,XLeH5g%!!)uJrW)`DrrE)Lrr<2P!!(R"r;ciIrrE&K!<C[L!6`mm
-s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-FgA_0Qg&h?/!!)uOrW)`IrrE)Qrr<2U!!(a,r;ciNrrE&P!<CjQ!6a'r
-!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUAec5[LeH>j%s8W&Jrr;cDs8W,Ls8N5Ps8UX"rVulIs8W)K!WU^Ls3&pm
-!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeIMZ1eH".M!7fU"e^XZMeH#Eq#lrN+!7fU"e^X[!eGoUJeH5g%eH#U!
-!!(*j!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg(+2;g&Tj\!8?-,g=cP\g&Us&#lr]5!8?-,g=cQ+g&M-Og&h?/g&V-+
-!!(*o!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeIV]1ec41Ms4,["e^a]Mec5Hq$3/Q+s4,["e^a^!eH#XJeH>j%ec5X!
-!<:-j!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBec#RJeHl6+eH".M!7fU"q:,cOe^XZMeH".M!<1LK!<(II!<(FJ!6E[j
-s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-GgAV*Og'Ic5g&Tj\!8?-,q:Z,Tg=cP\g&Tj\!<1[P!<(XN!<(UO!6Ejo
-!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBec,UJeHu9+ec41Ms4,["q:,fOe^a]Mec41Ms8LOKs8CLIs8CIJs2`^j
-!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeIMZ1eH".M!7fU"e^XZMeH#Eq#lrN+!7fU"e^X[!eHc0*eH","e^X[!
-eGoTjeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg(+2;g&Tj\!8?-,g=cP\g&Us&#lr]5!8?-,g=cQ+g'@]4g&Th,g=cQ+
-g&M,og&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeIV]1ec41Ms4,["e^a]Mec5Hq$3/Q+s4,["e^a^!eHl3*ec42"e^a^!
-eH#WjeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec,XLec#OSeGoU"eGoU"!;Y1F!<(IJ!!1UMrmh#Krmh#KrmgrIb1-Ll
-MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgA_0QgAV'Xg&M-,g&M-,!;Y@K!<(XO!!1dRrn@APrn@APrn@;Nb1Zgq
-MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec5[Lec,RSec5["ec5["s7t4Fs8CLJrrL[Mrmh&Krmh&KrmguIb1-Il
-MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X1eb]?KeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-6gA:lPg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU1ebfBKeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc^(_Y!j0JcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc^*_Z0Z2gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%^&S-.ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca(_Z0Z3gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%^&S-.ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca(_Z0Z4gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca'_Z0Z5gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca'_Z0Z6gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca&_Z0Z7gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca&_Z0Z8gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca%_Z0Z9gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca%_Z0W;g4=hQ_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca$_>sW8Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca$_?0agJc!=as81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca#_Z,2a_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca#_>o/`_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHeGt6js81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,Mg&Q]ms81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHeGt6js81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#W/eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,4g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoT/eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZXKBC\fV#TT>]`<Q~>
-!<E0!joD+Pg4=g+JUrBTJ`bYiU&X9;\c@6~>
-!<E0!joD4SeU`@(K7SZXKBC\fV#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZYK)kr6eHMcKk2s>WJ,~>
-!<E0!joD+Pg4=g+JUrBUJH5`4g'+2Mk2s5TJ,~>
-!<E0!joD4SeU`@(K7SZYK)kr6eHMcKk2s>WJ,~>
-!<E0!joD4Sec19n]`J/HJcC<$`W(q2s8V`)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`q_?'\RJcC<$`W(q7s8V`.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19n]`J/HJcC<$`W(q2s8V`)s8V63"f21\k.LbF~>
-!<E0!joD4Sec19p^&S*5K=uj9JcEai!/$9ErVuT)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`s_Z0W:J\m!<JcEai!.g-HrVuT.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19p^&S*5K=uj9JcEai!/$9ErVuT)s8V63"f21\k.LbF~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S+`eUc8mec18]^&.j)^&S,peHMJVS=BQZJ,~>
-!<B_0RJY_<JbR%\s8RWO_Z0Xeg4@u"gAc_`_YaB._Z0Yug'*nUR@+$TJ,~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S+`eUc8mec18]^&.j)^&S,peHMJVS=BQZJ,~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s+/^Oe]HAAK8mSEs8UXJs8'G/s5qi8SB\a\S,e'~>
-!!)u?!1E`<s+1!_rVm&TJUt]<s+/mTg<&(KJW7PHs8UgOs8'V4s5r#=REE+PR/ha~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s+/^Oe]HAAK8mSEs8UXJs8'G/s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S+`eUc8mec18]^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_YsN6gAc^*_Z0Xeg4@u"gAc_`_Z0Z7gAV'L_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S+`eUc8mec18]^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S+`eUc8mec18]^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_YsN4gAc^*_Z0Xeg4@u"gAc_`_Z0Z5gAV'N_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S+`eUc8mec18]^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S+`eUc8mec18]^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_YsN2gAc^*_Z0Xeg4@u"gAc_`_Z0Z3gAV$Q_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S+`eUc8mec18]^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ebb!oec17'^&S+`eUc8mec18]^&S--ebt.#s5qi8SB\a\S,e'~>
-!<C:A\cA/qgA?HrgAc^*_Z0Xeg4@u"gAc_`_Z0Z2gAQU&s5r#=REE+PR/ha~>
-!<CCD]`=T"ebb!oec17'^&S+`eUc8mec18]^&S--ebt.#s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S+`eUc8mec18]^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_Yo&^gAc^*_Z0Xeg4@u"gAc_`_Z0Z3gAQR(_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S+`eUc8mec18]^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S+`eUc8mec18]^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_Yo&`gAc^*_Z0Xeg4@u"gAc_`_Z0Z5gAQU%_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S+`eUc8mec18]^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S+`eUc8mec18]^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_Yo&bgAc^*_Z0Xeg4@u"gAc_`_Z0Z7gAQU#_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S+`eUc8mec18]^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8RZ#J^qlms+?<Es8W,LrIas[s8V63"e<iN]po(Q~>
-!<C:A\cA/qgAca"_Yo#hg4=gls8RZ(J_J6"s+-0Hs8W,QrIOg^s8V68"e!NE\sWPK~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8RZ#J^qlms+?<Es8W,LrIas[s8V63"e<iN]po(Q~>
-!<CCD]`=T"ec19r^&3Ka^&S+`eUc8mec18]^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<C:A\cA/qgAc`u_Yerd_Z0Xeg4@u"gAc_`_Z0Z7Jb[+^s5r#=REE+PR/ha~>
-!<CCD]`=T"ec19r^&3Ka^&S+`eUc8mec18]^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec19p^&EWc^&S+`K7SZqK8mSEs8R`F^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAc`s_Z#)f_Z0XeJUrBmJW7PHs8RZD_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec19p^&EWc^&S+`K7SZqK8mSEs8R`F^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19n]`Ni"s+,fRK>rP']`J.coY(;)k1'X*c+Uf\!.Y~>
-!<C:A\cA/qgAc`q_?,;*s+,`PJ]<8#_?'[foYUY.k1U!,b.>0P!.Y~>
-!<CCD]`=T"ec19n]`Ni"s+,fRK>rP']`J.coY(;)k1'X*c+Uf\!.Y~>
-!<CCD]`=T"ec18Qs+13$s02OceHMJf]tKp9J,~>
-!<C:A\cA/qgAc_Ts+13$s02Ocg'*ne]"4:0J,~>
-!<CCD]`=T"ec18Qs+13$s02OceHMJf]tKp9J,~>
-!<CCD]`=T"eGt5Qs+13$s0)IbeHMJf]tKp9J,~>
-!<C:A\cA/qg&Q\Ts+13$s0)Ibg'*ne]"4:0J,~>
-!<CCD]`=T"eGt5Qs+13$s0)IbeHMJf]tKp9J,~>
-!<CCD]`=RReUc8%eW&)_SB\a\S,e'~>
-!<C:A\cA.Lg4@t/g5XeiREE+PR/ha~>
-!<CCD]`=RReUc8%eW&)_SB\a\S,e'~>
-!<CCC^%%VDUk,=mUogEm^%.Znc2PBWS,e'~>
-!<C:@]()2>Tn/ngTrk!g](26hb5SsQR/ha~>
-!<CCC^%%VDUk,=mUogEm^%.Znc2PBWS,e'~>
-rr<&DrOqgI!53s`JcC<$XoIq9rk/B'!<7Q~>
-rr<&ArOVUC!4ma]JcC<$XoIq6rji0!!<7Q~>
-rr<&DrOqgI!53s`JcC<$XoIq9rk/B'!<7Q~>
-rr<&Dn%A^kJ`_OGJ`a)s!6suG!h98jJ,~>
-rr<&An%&LeJ`_OGJ`a)s!6XcA!gs&gJ,~>
-rr<&Dn%A^kJ`_OGJ`a)s!6suG!h98jJ,~>
-"9AH%S=K,_!1\W&J`_OGXl]W.n\+sm!W`9#J,~>
-"9AH%R@3TV!1AE#J`_OGXl]W+n[eag!W`9#J,~>
-"9AH%S=K,_!1\W&J`_OGXl]W.n\+sm!W`9#J,~>
-"9AK%!!)MYJ\?WJJ\A.unXTUZrr7K~>
-"9AK%!!)MVJ\$EDJ\%qonX9CWrr7K~>
-"9AK%!!)MYJ\?WJJ\A.unXTUZrr7K~>
-"TJH%s8RWMJH16$MZE\TJ,~>
-"TJH%s8RWMJH16$MZE\TJ,~>
-"TJH%s8RWMJH16$MZE\TJ,~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/sim_trans_move_actor.gif b/lib/et/doc/src/sim_trans_move_actor.gif
deleted file mode 100644
index f7185cada2..0000000000
--- a/lib/et/doc/src/sim_trans_move_actor.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_move_actor.png b/lib/et/doc/src/sim_trans_move_actor.png
new file mode 100644
index 0000000000..c642720a8b
--- /dev/null
+++ b/lib/et/doc/src/sim_trans_move_actor.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_move_actor.ps b/lib/et/doc/src/sim_trans_move_actor.ps
deleted file mode 100644
index b459735a82..0000000000
--- a/lib/et/doc/src/sim_trans_move_actor.ps
+++ /dev/null
@@ -1,6403 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: (ImageMagick)
-%%Title: (sim_trans_move_actor.ps)
-%%CreationDate: (Mon Oct 14 16:44:32 2002)
-%%BoundingBox: 0 0 512 426
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 1
-%%Orientation: Portrait
-%%PageOrder: Ascend
-%%Pages: 1
-%%EndComments
-
-%%BeginDefaults
-%%EndDefaults
-
-%%BeginProlog
-%
-% Display a color image. The image is displayed in color on
-% Postscript viewers or printers that support color, otherwise
-% it is displayed as grayscale.
-%
-/DirectClassPacket
-{
- %
- % Get a DirectClass packet.
- %
- % Parameters:
- % red.
- % green.
- % blue.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile color_packet readhexstring pop pop
- compression 0 eq
- {
- /number_pixels 3 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add 3 mul def
- } ifelse
- 0 3 number_pixels 1 sub
- {
- pixels exch color_packet putinterval
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/DirectClassImage
-{
- %
- % Display a DirectClass image.
- %
- systemdict /colorimage known
- {
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { DirectClassPacket } false 3 colorimage
- }
- {
- %
- % No colorimage operator; convert to grayscale.
- %
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { GrayDirectClassPacket } image
- } ifelse
-} bind def
-
-/GrayDirectClassPacket
-{
- %
- % Get a DirectClass packet; convert to grayscale.
- %
- % Parameters:
- % red
- % green
- % blue
- % length: number of pixels minus one of this color (optional).
- %
- currentfile color_packet readhexstring pop pop
- color_packet 0 get 0.299 mul
- color_packet 1 get 0.587 mul add
- color_packet 2 get 0.114 mul add
- cvi
- /gray_packet exch def
- compression 0 eq
- {
- /number_pixels 1 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add def
- } ifelse
- 0 1 number_pixels 1 sub
- {
- pixels exch gray_packet put
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/GrayPseudoClassPacket
-{
- %
- % Get a PseudoClass packet; convert to grayscale.
- %
- % Parameters:
- % index: index into the colormap.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile byte readhexstring pop 0 get
- /offset exch 3 mul def
- /color_packet colormap offset 3 getinterval def
- color_packet 0 get 0.299 mul
- color_packet 1 get 0.587 mul add
- color_packet 2 get 0.114 mul add
- cvi
- /gray_packet exch def
- compression 0 eq
- {
- /number_pixels 1 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add def
- } ifelse
- 0 1 number_pixels 1 sub
- {
- pixels exch gray_packet put
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/PseudoClassPacket
-{
- %
- % Get a PseudoClass packet.
- %
- % Parameters:
- % index: index into the colormap.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile byte readhexstring pop 0 get
- /offset exch 3 mul def
- /color_packet colormap offset 3 getinterval def
- compression 0 eq
- {
- /number_pixels 3 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add 3 mul def
- } ifelse
- 0 3 number_pixels 1 sub
- {
- pixels exch color_packet putinterval
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/PseudoClassImage
-{
- %
- % Display a PseudoClass image.
- %
- % Parameters:
- % class: 0-PseudoClass or 1-Grayscale.
- %
- currentfile buffer readline pop
- token pop /class exch def pop
- class 0 gt
- {
- currentfile buffer readline pop
- token pop /depth exch def pop
- /grays columns 8 add depth sub depth mul 8 idiv string def
- columns rows depth
- [
- columns 0 0
- rows neg 0 rows
- ]
- { currentfile grays readhexstring pop } image
- }
- {
- %
- % Parameters:
- % colors: number of colors in the colormap.
- % colormap: red, green, blue color packets.
- %
- currentfile buffer readline pop
- token pop /colors exch def pop
- /colors colors 3 mul def
- /colormap colors string def
- currentfile colormap readhexstring pop pop
- systemdict /colorimage known
- {
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { PseudoClassPacket } false 3 colorimage
- }
- {
- %
- % No colorimage operator; convert to grayscale.
- %
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { GrayPseudoClassPacket } image
- } ifelse
- } ifelse
-} bind def
-
-/DisplayImage
-{
- %
- % Display a DirectClass or PseudoClass image.
- %
- % Parameters:
- % x & y translation.
- % x & y scale.
- % label pointsize.
- % image label.
- % image columns & rows.
- % class: 0-DirectClass or 1-PseudoClass.
- % compression: 0-none or 1-RunlengthEncoded.
- % hex color packets.
- %
- gsave
- /buffer 512 string def
- /byte 1 string def
- /color_packet 3 string def
- /pixels 768 string def
-
- currentfile buffer readline pop
- token pop /x exch def
- token pop /y exch def pop
- x y translate
- currentfile buffer readline pop
- token pop /x exch def
- token pop /y exch def pop
- currentfile buffer readline pop
- token pop /pointsize exch def pop
- /Times-Roman findfont pointsize scalefont setfont
- x y scale
- currentfile buffer readline pop
- token pop /columns exch def
- token pop /rows exch def pop
- currentfile buffer readline pop
- token pop /class exch def pop
- currentfile buffer readline pop
- token pop /compression exch def pop
- class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
- grestore
- showpage
-} bind def
-%%EndProlog
-%%Page: 1 1
-%%PageBoundingBox: 0 0 512 426
-DisplayImage
-0 0
-512 426
-12.000000
-512 426
-1
-0
-0
-64
-31446a
-394473
-314473
-000000
-ffffff
-bdbebd
-dedade
-d5d6d5
-949194
-ded6de
-9c999c
-d5d2d5
-c5c2c5
-bdb6bd
-838183
-7b817b
-8b918b
-7b7d7b
-838583
-b4b2b4
-a4a1a4
-bdbabd
-aca5ac
-acaaac
-cdcecd
-c5cac5
-949594
-c5c6c5
-bdc2bd
-b4b6b4
-949994
-838983
-a4a5a4
-acaeac
-9ca19c
-cdcacd
-9c9d9c
-8b8d8b
-d5ced5
-9c959c
-cdc6cd
-e6e6e6
-d5dad5
-8b898b
-b4aeb4
-c5bec5
-a4aaa4
-eeeeee
-ffa500
-ff0000
-0000ff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-000102000203030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303010201020101010103030404040404040404040404040404040405040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404050404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040403030101010202030404060606060606060606060606060606
-060507070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070705060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606062f2f030001010304060606060606060606
-060606060606060606050707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070506060606060606060606060606060606060606060606060606060606060606
-06060606060606060606060606060606060606060606060606060606060c030002030406
-060606060606060606060606060606060605070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-0707070707070707070707070707070707070707190b0707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707050606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060c03010304060606060606060606060606060606060606060507070707070707070707
-070707070707070707070707070707070707070707080807070707070707070707070707
-07070707070707070707070707070707070707070707070c1407050f111e080807070e0f
-070707070707070707070707070707070707070707070707070707070707070707070707
-07070707070e0f07070e0f07070707070707070707070707070707070707070707070707
-070707070707071405070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070705060606060606060606060606060606
-06060606060606060606060a0a0a0a0a0a0a0a0a0a0606060606060606060606060a0a06
-0606060a0a06060606062103030409090909090a0a0909090909090a0a09090909050b0b
-0b0b0b0b0b0b0b0b0b0b0b0c0d0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b08080b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0f1d0b2511
-1b2608080b0b0e0f0b0b0c0d0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0e0f0b0b0e0f0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c
-0d0b0b0b0b0b0b0b0b0b0b0b0b0b0b1d112d0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0509090909090909
-090909090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a09090909090909
-090909090a0a0a0a09090a0a0a0a0909090921030304090909090a0a0a0a090909090a0a
-0a0a090909050b0b0b0b0b0b0b0b0b0b0b0b0b0e0f0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b2b1a0b0b0e0f0b0b0b0b0b0b0e0f0b0b0e0f0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0e0f0b0b0e0f0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0e0f0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b1a2b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0509090909090909090909090909090909090909090909090909090a0a0a0a0a0a0a0a0a
-0a09090909090909090909090a0a0a0a0a0a0a0a0a0a0909090921030304090909090a0a
-0a0a0a09090a0a0a0a0a090909050b0b0b0b0b0b0c101112130b141111110c0b0b0b0b0b
-0b0a11150b0b16120b0e0f0b0b0c101112130b17110c0b0a110c0b0a140b0c101112130b
-0b252516250b0b0b0b1511150b0a111111230e0f0b0b0e0f0b141111110c0c101112130b
-0b252516250b0e0f0b0b0b0b0b0b212b11112b230b212b112b210b0b0b0e0f0b0b0e0f0b
-0b0c101112130b0b212b11112b23141111110c212b112b210b0b0b252516250b0d11150b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0509090909090909090909090909090909090909090909090909090a
-0a0a0a0a0a0a0a0a0a0909090909090909090909090a0a0a0a0a0a0a0a09090909092103
-03040b0b0b0b0b0a0a0a0a0a0a0a0a0a0a0b0b0b0b051818181818190e12151a111b1b0f
-111c181818181818181d111e18181f20180e0f18190e12151a111b15111718121117180e
-1d190e12151a111b180e112b201818181822111b181b0f111c180e0f18180e0f181b0f11
-1c1b0e12151a111b180e112b20182b1f181818181820112b131d2e1b17111a051a111718
-180e0f18180e0f18190e12151a111b20112b131d2e1b1b0f111c2e111a051a111718180e
-112b20181b11221818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-18181818181818181818181818181818050b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0a0b0b0b0b0b0b0b0b0a0b0b0b0b0b0b0b0b0b0b0b0b0b0a0a0a0a0a0a
-0b0b0b0b0b0b210303040b0b0b0b0b0b0a0a0a0a0a0a0a0a0b0b0b0b0b05181818181821
-112223211121180e0f1818181818181818180e0f2305110c180e0f182111222321112118
-111a1b11121e1c112321112223211121180e112318181818181a111818180e0f18180e0f
-18180e0f18180e0f1821112223211121180e112318181818181818181812110c18181818
-1f111b181b111f18180e0f18180e0f182111222321112112110c18181818180e0f181f11
-1b181b111f18180e1123181818111a181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818050b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0a0b0b0b0b0b0b0b0b0a0b0b0b0b0b0b0b0b0b0b0b
-0b0b0a0a0a0a0a0a0b0b0b0b0b0b210303040b0b0b0b0b0b0b0a0a0a0a0a0a0b0b0b0b0b
-0b05181818181820111111111120180e0f181818181818181818241121242518180e0f18
-2011111111112018100e21081e1217251820111111111120180e0f1818181818181a1118
-18180e0f18180e0f18180e0f18180e0f1820111111111120180e0f181818181818181818
-18111118181818180f11181818111118180e0f18180e0f18201111111111201111181818
-1818180e0f180f11181818111118180e0f18181818111a18181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-1818181818181818181818181818181818181818181818181818181818181818050b0b0b
-0b0b150a0a0a0a0a0a0a0a150b0b0b0b0b0b0b0b0b0b0b0a0b0b0b0b0b0b0b0b0a0b0b0b
-0b0b0b0b0b0b0b0b0b0a0a0a0a0a0a0a0a0b0b0b0b0b210303040b0b0b0b0b0b0b0b0a0a
-0a0a0b0b0b0b0b0b0b05181818181821112218181818180e0f1818181818181818181511
-250e1718180e0f18211122181818181814112520171125141821112218181818180e0f18
-181818181814111b18180e0f18180e0f18180e0f18180e0f1821112218181818180e0f18
-181818181818181818121105181818181f111b181b111f18180e0f18180e0f1821112218
-18181812110518181818180e0f181f111b181b111f18180e0f1818181b11221818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-18181818050b0b0b0b0b0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0a0b0b0b0b
-0b0b0b0b0a0b0b0b0b0b0b0b0b0b0b0b0a0a0a0a0a0a0a0a0a0a0b0b0b0b210303042626
-2626262626262627272626262626262626052323232323281211201d2113231f111d2823
-232323232323231211111b23230e0f23281211201d2113231d11110d1511111d23281211
-201d2113230e0f23232323232315112c23230e0f23230e0f23230e0f23231f111d0c1211
-201d2113230e0f2323232b1f2323232323171112210d170c17111a151a111623230e0f23
-230e0f23281211201d2113171112210d170c231f111d20111a151a111623230e0f232323
-2c110d232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323052626262626272727272727272727272626262626262626
-262626272626262626262626272626262626262626262626272727272626272727272626
-26262103030426262626262626262626262626262626262626052323232323230c1a0f11
-122123130e0f1523232323232323231411082323230e0f23230c1a0f1112212328111123
-2311112823230c1a0f111221230e0f23232323232323252523230e0f23230e0f23230e0f
-2323130e0f150c1a0f111221230e0f2323230e0f232323232323172b11112b2d23161211
-12172323230e0f23230e0f23230c1a0f11122123172b11112b2d23130e0f151612111217
-2323230e0f23232325252323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-23232323232323232323232323232323232323230526262626260d27272727272727270d
-262626262626262626262627272727272727272727262626262626262626262626272726
-262626272726262626262103030426262626262626262626262626262626262626052323
-232323232323232323232323232311111111111111152323232323232323232323232323
-2323232323232323232323232323232323232323232323232323232323230c0e16232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323170e0c232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323230526262626262626
-262626262626262626262626262626262626262626262626262626262626262626262626
-262626262626262626262626262626262626210303042323232323232323232323232323
-2323232323051b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b05141b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b14051b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-052323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232321030304232323232323
-23232323232323232323232323051b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b05232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232103
-030423232323232323232323232323232323232323051b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b0523232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-2323232323232103030e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e030304292929140404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404140429291503030429292914040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040e14042929150303042929
-291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404
-2929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404292915030304292929140404
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e140429291503
-03042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e14042929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a0303030303
-0303032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a03030303
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a030303032a2a2a2a2a2a2a2a03032a03032a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-03030303030303032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a
-2a2a2a03032a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303
-2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a03032a2a2a2a2a2a2a03032a03032a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a03032a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929
-291404042a2a2a2a2a2a2a03032a2a2a2a03032a03032a2a030303032a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a03032a2a03032a03032a2a030303032a2a03032a2a03032a2a03032a2a
-030303032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a03030303
-2a2a03032a03032a2a030303032a2a2a030303032a2a030303032a2a030303032a2a0303
-2a03032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a03032a03032a030303032a2a0303
-03032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a030303032a
-2a03032a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404
-2929150303042929291404042a2a2a2a2a2a2a03032a2a2a2a03032a03032a03032a2a03
-032a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a03032a03032a03032a2a03032a03032a2a
-03032a2a03032a03032a2a03032a03030303032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a2a2a03032a2a03032a03032a03032a03032a2a03032a03032a2a03032a2a03032a2a03
-032a2a03032a03030303032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a03032a03032a
-2a03032a2a03032a2a03032a03030303032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03
-032a03032a2a03032a03032a0303032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a03030303032a03032a
-03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a03032a03032a03032a
-2a03032a2a03032a03032a03032a2a03032a2a03032a0303032a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a03032a2a2a2a2a03032a2a03032a03032a03032a03032a2a03032a03032a2a2a
-2a2a2a03032a2a03032a2a03032a0303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303
-032a03032a03032a2a03032a2a03032a2a03032a0303032a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a030303030303032a03032a2a03032a03032a03032a2a03032a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a03
-032a2a2a2a03032a03032a0303030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a032a2a03
-2a2a03032a0303030303032a2a03032a03032a03032a2a0303030303032a03032a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a03032a2a03032a03032a03032a03030303
-03032a03032a2a2a2a2a2a03032a2a03032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a03032a2a2a2a03032a03032a2a03032a2a0303030303032a03032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a0303030303032a03032a03032a2a03032a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404292915030304292929140404
-2a2a2a2a2a2a2a03032a2a2a2a03032a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a030303032a2a03032a03032a2a2a2a2a2a03032a03032a03032a2a03032a2a2a
-2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a03032a2a03032a0303
-2a03032a03032a2a2a2a2a03032a2a2a2a2a2a03032a2a03032a2a03032a03032a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a03032a03032a2a03032a2a03032a2a2a2a2a
-03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a2a2a2a03032a
-03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e140429291503
-03042929291404042a2a2a2a2a2a2a03032a2a2a2a03032a03032a03032a2a03032a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a03032a2a2a03032a2a0303
-2a2a2a03032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a030303
-032a2a03032a03032a03032a03032a2a03032a03032a2a03032a2a03032a0303032a2a03
-032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a03032a03032a2a03032a
-0303032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a0303
-2a2a03032a03032a0303032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e14042929150303042929291404042a2a2a2a2a2a2a03032a2a2a2a03032a03032a2a
-030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a030303032a2a
-2a2a03032a2a03032a2a2a2a030303032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a030303032a2a030303032a2a03032a03032a2a030303032a2a2a030303032a2a2a2a
-03032a2a030303032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a0303
-2a03032a2a2a03032a2a030303032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303
-2a2a2a03032a2a030303032a2a03032a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929
-291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404
-2929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404292915030304292929140404
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e140429291503
-03042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e14042929150303042929291404040e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e140429291503030429292914040e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303032a2a2a2a2a2a2a2a2a2a2a0303
-2a2a2a2a2a2a2a2a2a03032a03032a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a03032a2a2a2a
-2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a03032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04040404
-040404040404042a2a2a2a2a2a2a2a0303030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303
-2a2a2a03032a2a030303032a2a030303032a2a030303032a2a03032a03032a2a2a2a2a2a
-03032a2a2a2a2a030303032a2a03032a2a2a03032a2a030303032a2a03032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a040404040404040404040e2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a03032a2a2a03032a03032a2a03032a2a03032a2a03032a2a03032a03032a
-03032a2a2a2a2a2a03032a2a2a2a03032a2a03032a03032a2a2a03032a03032a2a03032a
-03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a
-2a03032a03032a030303032a2a2a030303032a2a03030303032a2a030303032a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a03032a2a03032a2a2a2a
-2a2a03032a03032a03032a2a2a2a2a2a03032a2a2a2a03032a2a03032a2a03032a03032a
-2a03032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a
-2a2a2a03032a2a2a2a030303030303032a2a03032a03032a2a03032a2a2a2a03032a0303
-2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a030303030303
-2a2a03032a2a2a03030303032a03032a03032a2a2a2a2a2a03032a2a2a2a030303030303
-2a2a03032a03032a2a0303030303032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a
-2a0e0e2a2a2a2a2a2a2a2a03030303032a0303032a2a03032a2a03032a03032a2a03032a
-2a2a03032a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03
-032a03032a2a2a2a2a2a03032a2a03032a2a03032a03032a03032a2a2a2a2a2a03032a2a
-2a2a03032a2a2a2a2a2a2a0303032a2a2a03032a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a2a03032a2a2a030303030303
-2a0303030303032a2a2a032a2a2a0303030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a03032a2a03032a2a03032a2a03032a2a03032a0303032a2a03032a03032a03032a2a
-2a2a2a2a03032a2a2a2a03032a2a03032a2a2a0303032a2a2a03032a2a03032a03032a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a2a03032a
-2a2a03032a2a2a2a2a03032a2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a03030303032a2a2a2a030303032a2a2a2a03032a2a0303032a03
-0303032a03032a2a2a2a2a2a0303030303032a030303032a2a2a2a2a032a2a2a2a2a0303
-03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03
-032a2a2a2a03032a2a2a03032a2a03032a03032a2a03032a03032a2a2a2a03032a2a0303
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a
-2a2a2a2a2a2a2a03032a2a2a2a03032a2a2a2a030303032a2a2a030303032a2a03030303
-032a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04040e0e
-0e0e0e0e0e0e0e2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a030303032a2a2a03030303
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a030303032a2a2a03032a2a
-03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03
-032a2a2a03032a2a03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a03032a2a2a03032a2a03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a03032a03032a2a03032a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a03032a03
-032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a04040404040404040404042a2a2a2a2a2a2a2a03032a2a2a
-03032a03032a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a0303030303032a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303030303032a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a
-03032a2a03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a040404040404040404040e2a2a2a2a2a
-2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a03032a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a03032a2a2a03032a2a03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a
-2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a03032a03032a2a030303032a2a
-2a2a2a2a2a03032a2a2a2a03032a03032a030303032a2a032a0303032a0303032a2a2a2a
-2a2a2a2a2a2a2a2a03032a2a2a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a030303032a2a2a030303032a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a03032a030303
-2a03032a2a03032a2a2a2a2a2a03032a2a2a2a030303030303032a2a03032a03032a2a03
-032a2a03032a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a03032a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a030303030303032a03
-032a03032a2a03032a03032a2a03032a2a2a2a2a2a03030303032a0303032a2a03032a2a
-03032a03032a2a03032a2a03032a0303030303032a2a2a2a03032a2a2a03032a2a03032a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03
-032a2a2a03032a03032a03032a2a03032a0303030303032a2a2a2a2a2a03032a2a2a2a03
-032a2a2a03032a2a03032a03032a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a
-2a2a2a2a2a2a2a03032a2a2a03032a03032a03032a2a03032a03032a2a2a2a2a2a2a2a2a
-2a03032a2a2a2a03032a2a2a03032a2a03032a03032a2a03032a2a03032a030303030303
-2a2a2a2a03032a2a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a
-2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a03032a0303032a03032a
-2a03032a2a2a2a2a2a03032a2a2a2a03032a2a2a03032a2a03032a03032a2a03032a2a03
-032a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a03
-032a03032a2a030303032a2a2a2a2a2a2a03032a2a2a2a03032a2a2a2a030303032a2a03
-032a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a030303032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a04040e0e0e0e0e0e0e0e0e2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04040404
-040404040404040404040404040404040404040404040404040404042a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c04040404040404040404040404040404040404040404040404040404040e0404
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a
-2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e04
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a
-2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a
-0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a
-2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a
-2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a
-2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a0404040404040404
-0404042a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a2a2a2a03032a2a2a2a2a2a2a2a
-2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a0e0e0404
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-040404040404040404040e2a2a2a2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a0303
-2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a03032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a
-2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03
-032a2a03032a03032a2a030303032a2a2a2a2a2a2a03032a2a2a03032a03032a03032a2a
-03032a2a03032a03032a03032a2a2a030303032a2a03032a2a03032a2a03032a03032a03
-032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e04
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03
-032a2a2a03032a03032a03032a0303032a03032a2a03032a2a2a2a2a2a03032a2a2a0303
-2a0303032a03032a03032a03032a2a0303032a03032a03032a2a03032a03032a2a03032a
-2a03032a0303032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04040e0e0e0e0e0e
-0e0e0e0e0e0e0e040e0e0e0e0e0e0e0e0e0e0e0e0e0e04042a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a
-2a2a2a2a2a2a2a030303030303032a03032a03032a2a03032a03032a2a03032a2a2a2a2a
-2a03032a2a2a03032a03032a2a03032a030303032a2a2a03032a2a03032a03032a2a0303
-2a2a03032a03032a03032a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-040e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e04042a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a
-2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a03032a2a03032a030303
-0303032a2a2a2a2a2a03032a2a2a03032a03032a2a03032a030303032a2a2a03032a2a03
-032a03032a2a03032a2a03032a03032a03032a2a03032a2a03032a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a0303
-2a2a03032a03032a2a2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a03032a03032a03
-032a2a03032a2a03032a03032a2a03032a2a03032a03032a03032a2a03032a2a03032a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-0404040404040404040404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a
-03032a03032a03032a0303032a03032a2a03032a2a2a2a2a2a2a03032a03032a2a03032a
-2a03032a03032a2a03032a03032a2a03032a03032a2a03032a2a2a03032a2a03032a2a2a
-03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a
-2a2a2a03032a2a2a03032a03032a2a03032a03032a2a030303032a2a2a2a2a2a2a2a0303
-0303032a2a03032a2a03032a03032a2a2a030303032a2a03032a2a030303032a2a2a2a03
-032a2a03032a2a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04040e0e0e0e0e0e
-0e0e0e2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c0e1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c040e1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c040e0e1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c04040e0e1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c04042a0e0e1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c04042a2a0e0e1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c04
-042a2a2a0e0e1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c04042a2a2a2a0e0e1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c04042a2a2a2a2a0e0e1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a2a0e0e1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a
-2a2a0e0e1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31
-312a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-04042a2a2a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a30302a2a303030302a30303030302a30302a30302a3030302a
-2a30302a2a30302a30303030302a3030302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a312a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a0e0e1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a302a2a302a2a302a2a302a302a
-2a2a302a2a302a2a302a2a302a302a2a2a302a2a302a2a302a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a312a
-2a31312a31312a2a2a2a2a2a2a2a2a3131312a2a3131312a2a2a2a31312a2a2a2a2a312a
-2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a31312a312a2a312a31312a2a2a2a31312a2a2a2a3131312a2a2a31312a
-2a2a31312a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a31312a2a2a2a31312a2a2a312a3131
-2a2a2a31312a2a2a312a3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a312a2a312a31312a2a2a2a31312a
-2a2a2a3131312a2a2a31312a2a2a31312a2a2a2a2a2a2a2a2a2a313131312a31312a312a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04040e0e0e0e0e0e0e0e0e0e0e0e1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a302a2a3030
-2a302a2a30302a2a2a2a30302a302a2a302a2a302a302a302a302a2a30302a302a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a312a312a312a2a312a2a312a2a2a2a2a2a2a2a312a2a2a2a2a312a2a312a2a312a
-2a312a2a2a2a312a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a312a2a312a2a312a2a312a2a312a2a312a
-2a2a2a2a2a2a312a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a312a2a2a312a2a312a2a312a
-2a312a2a312a312a2a2a312a2a312a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a312a2a312a
-2a312a2a312a2a312a2a312a2a2a2a2a2a2a312a2a2a2a2a312a2a2a2a2a2a2a2a2a2a31
-2a2a2a312a312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e040e0e0e0e0e0e0e0e0e0e0e0e
-0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-302a2a302a2a302a30302a2a302a302a2a2a302a30302a2a302a2a302a302a302a302a2a
-302a30302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a312a312a312a2a312a2a312a2a2a2a2a2a2a2a2a31312a2a2a
-312a2a312a2a3131312a2a2a2a2a312a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a312a2a312a2a312a2a
-3131312a2a2a2a31312a2a2a2a2a312a2a2a3131312a2a2a2a2a2a2a2a2a2a2a312a2a2a
-312a2a312a2a312a2a2a2a2a31312a2a2a2a3131312a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31
-2a312a312a2a312a2a312a2a3131312a2a2a2a31312a2a2a2a2a312a2a2a3131312a2a2a
-2a2a2a2a2a2a2a312a2a2a312a312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a302a2a302a2a302a2a302a2a302a2a302a2a302a2a302a2a302a2a30
-2a2a302a302a2a2a302a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a312a2a312a2a312a2a2a2a2a2a
-2a2a2a2a2a312a2a312a2a312a2a312a2a312a2a2a2a312a2a2a2a2a312a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a31
-2a2a312a2a312a2a312a2a312a2a2a2a2a312a2a2a2a312a2a312a2a312a2a2a2a2a2a2a
-2a2a2a2a312a2a2a312a2a312a2a312a2a312a2a312a312a2a2a312a2a312a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a312a312a312a2a312a2a312a2a312a2a312a2a2a2a2a312a2a2a2a312a
-2a312a2a312a2a2a2a2a2a2a2a2a2a312a2a31312a312a312a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e04040404040404040404040404040404042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a30302a2a30302a2a302a3030302a2a3030302a
-2a302a2a2a30302a2a2a302a302a2a30302a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a31312a2a31
-312a2a2a2a2a2a2a2a2a3131312a2a3131312a31312a2a31312a2a2a31313131312a3131
-3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a312a312a31313131312a31312a2a31312a2a2a3131312a2a2a31313131312a3131
-2a312a2a2a2a2a2a2a2a31313131312a2a31312a2a2a2a31312a2a31312a31312a2a2a31
-312a2a2a313131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a31313131312a31312a2a31312a2a2a3131
-312a2a2a31313131312a31312a312a2a2a2a2a2a2a2a2a2a31312a312a312a31312a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e04040404040404040404040404040e04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a3131313131312a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3131313131312a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3131313131
-312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a
-2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04
-042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a
-0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a
-2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a
-2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04
-042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a
-0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a
-2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04040e0e0e0e0e0e0e
-0e0e0e0e0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a2a2a2a2a31312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a312a31312a2a2a2a31312a2a312a312a31312a2a2a2a2a2a2a313131312a2a
-2a31312a2a2a2a3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a312a2a312a312a312a312a2a2a2a2a2a
-2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a3131312a2a312a31
-2a312a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a
-312a2a312a2a312a312a2a2a2a2a2a2a2a2a2a312a2a312a2a2a312a2a2a312a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a3131312a31312a2a31312a2a2a312a312a2a2a2a2a2a2a2a2a2a2a31312a2a31313131
-312a2a31312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31
-31313131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a0303030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-0303030303312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a03030303032a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a313131312a2a
-312a31313131312a31312a2a2a2a2a2a2a312a312a31312a312a3131312a2a31312a2a2a
-313131312a2a2a31312a2a2a2a2a2a2a2a2a2a2a312a2a2a2a31312a2a2a2a31312a2a2a
-312a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a312a2a2a2a2a312a2a2a2a312a2a312a2a2a2a2a2a2a312a312a312a2a2a312a2a
-2a2a2a2a312a2a2a2a312a2a2a2a312a2a312a2a2a2a2a2a2a2a2a2a312a2a2a312a2a31
-2a2a312a2a312a2a312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a312a2a2a2a312a2a312a2a2a2a2a2a2a312a31
-2a312a2a2a312a2a2a2a2a2a312a2a2a2a312a2a2a2a3131312a2a2a2a2a2a2a2a2a2a2a
-312a2a2a312a2a312a2a312a2a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a312a2a2a2a312a2a312a2a
-2a2a2a2a2a2a312a312a2a2a2a312a2a2a2a2a2a312a2a2a2a312a2a312a312a2a312a2a
-2a2a2a2a2a2a2a2a312a2a2a312a2a312a2a312a2a312a2a312a312a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a31313131
-2a2a2a31312a2a2a2a2a2a2a2a2a312a312a2a2a313131312a2a31313131312a2a2a3131
-2a2a2a31312a2a2a2a2a2a2a2a2a31313131312a2a31312a2a2a2a31312a2a31312a3131
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a3131313131312a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3131313131312a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a030303032a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a03030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-0303030303030303030303030303030303312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303032a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a
-2a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a31312a312a312a3131312a31312a2a2a31
-2a31312a2a2a313131312a2a2a31312a2a2a2a3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a2a312a2a
-2a2a2a2a312a2a2a312a2a312a2a2a312a2a2a2a312a2a312a2a312a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a
-2a312a2a2a312a2a2a2a3131312a2a2a312a2a312a2a2a312a2a2a2a3131312a2a2a312a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a312a2a312a2a2a312a2a2a312a2a312a2a2a312a2a312a2a2a312a2a312a
-312a2a312a2a312a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a3131312a2a313131312a2a31312a312a3131312a31
-312a2a2a31312a2a2a31312a2a2a2a31312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a3131312a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a0303030303032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-0303030303312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a03030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a32322a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a322a
-2a2a2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a3232322a2a2a32322a2a2a2a2a2a2a2a2a2a32322a2a2a2a32322a2a32
-322a322a2a32322a322a2a2a2a32322a2a2a323232322a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a322a2a322a2a322a2a322a2a2a2a2a2a2a2a322a2a32
-2a2a322a2a322a322a322a322a322a322a322a2a2a2a322a2a2a2a322a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a322a2a322a2a322a2a322a2a2a2a
-2a2a2a2a322a2a2a2a2a322a2a322a322a322a322a322a322a322a2a2a2a322a2a2a2a32
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a322a2a322a2a
-322a2a322a2a2a2a2a2a2a2a322a2a322a2a322a2a322a322a322a322a322a322a322a2a
-2a2a322a2a2a2a322a2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a32322a322a2a32322a2a2a2a2a2a2a2a2a2a32322a2a2a2a32322a2a322a322a32
-32322a322a32322a32323232322a2a2a32322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3232323232322a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a
-2a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a3131312a
-2a31312a2a2a2a2a312a2a2a2a31312a2a2a31312a2a2a2a2a3131312a2a2a31312a2a2a
-2a2a2a2a2a2a313131312a2a2a31312a2a2a2a3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a312a2a2a2a312a2a312a2a2a2a312a2a2a312a2a312a2a2a2a312a2a2a312a2a2a
-2a2a312a2a312a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a3131312a2a2a2a2a312a2a2a3131312a2a2a3131
-312a2a2a2a31312a2a2a3131312a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a2a2a312a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a312a2a312a2a2a2a312a2a2a
-312a2a312a312a2a312a2a2a2a2a2a312a2a312a2a312a2a2a2a2a2a2a2a2a312a2a312a
-2a2a312a2a2a312a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a313131312a2a2a31312a
-2a2a31313131312a2a31312a2a2a31312a312a2a3131312a2a2a2a31312a2a2a2a2a2a2a
-2a2a2a2a31312a2a31313131312a2a31312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a3131313131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a030303032a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a03030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-0303030303030303030303030303030303312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303032a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a31312a2a2a2a2a2a2a2a2a31312a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a31
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a3131312a2a2a31312a2a2a2a2a312a2a2a
-2a31312a2a2a313131312a2a2a31312a2a2a2a2a2a2a2a2a313131312a2a312a3131312a
-31312a2a2a312a31312a2a2a2a3131312a2a31312a2a2a2a2a31312a2a2a313131312a2a
-2a31312a2a2a2a31312a2a312a31312a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a312a2a31
-2a2a2a2a312a2a2a312a2a312a2a2a312a2a2a2a312a2a312a2a2a2a2a2a2a2a2a312a2a
-2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a312a2a2a2a2a2a2a312a2a2a312a2a31
-2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a312a2a312a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a
-2a312a2a3131312a2a2a2a2a312a2a2a3131312a2a2a2a312a2a2a2a3131312a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a312a2a2a2a3131312a2a2a312a2a312a2a2a31312a2a2a3131
-312a2a2a312a2a2a2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a312a2a312a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a312a2a312a2a312a2a312a2a2a2a312a2a2a312a2a312a2a2a312a2a312a
-312a2a312a2a2a2a2a2a2a2a2a312a2a312a2a312a2a2a312a2a312a2a2a312a2a312a2a
-2a2a2a312a312a2a312a2a2a312a2a312a2a2a312a2a312a2a2a312a2a2a312a2a312a2a
-312a2a312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a31312a312a2a31312a2a2a31313131312a2a31312a
-2a2a2a2a31312a2a2a31312a2a2a2a2a2a2a2a2a2a2a31312a2a313131312a2a31312a31
-2a3131312a31312a3131312a2a2a31312a312a2a2a31312a2a2a2a2a31312a2a31313131
-312a2a31312a2a3131312a3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3131313131312a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a030303032a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-0303030303030303030303030303030303312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303032a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a32322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a322a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a32
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a32322a2a322a32322a2a2a2a3232322a2a2a2a2a2a2a2a2a32322a2a32
-322a32322a2a323232322a2a2a32322a2a2a322a3232322a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a322a2a322a2a322a2a322a2a322a2a322a2a2a2a2a2a
-2a2a322a2a322a2a322a2a322a2a2a322a2a2a2a322a2a322a2a2a322a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a3232322a2a2a322a2a322a2a322a
-2a322a2a2a2a2a2a2a2a322a2a322a2a322a2a322a2a2a322a2a2a2a3232322a2a2a2a32
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a322a2a322a2a
-322a2a322a2a322a2a322a2a2a2a2a2a2a2a322a2a322a2a322a2a322a2a2a322a2a322a
-322a2a322a2a2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a32322a2a3232322a32322a2a32322a322a2a2a2a2a2a2a2a32322a2a2a2a32322a
-322a2a2a32322a2a2a32322a2a2a323232322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a32
-32323232322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e04040404040404040404040404040404042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c040404040404040404040404040e04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a0e0e1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a
-2a2a2a0e0e1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c04042a2a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c04042a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c04042a2a2a2a2a0e0e1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c04042a2a2a2a0e0e1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c04
-042a2a2a0e0e1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c04042a2a0e0e1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c04042a0e0e1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c040e0e0e1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c040e0e
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c0e0e1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c0e1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04040404040404040404040404040404042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0404040404040404040404040404
-040404042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c041c040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404041c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04041c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a0e0e1c1c
-1c1c1c1c1c1c1c1c1c1c04040e1c04040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-04040404040e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c040404041c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303150a0a0a0a2a2a
-2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c0404040e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404040404041c1c1c1c1c1c1c1c
-1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a150a0a0303
-03232323230a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c040404042a0e0e1c04042a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a0404
-04041c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c1c1c1c1c040404042a2a2a0e
-0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a040404041c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c1c1c0404
-04042a2a2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a040404041c1c1c04042a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a
-0e0e1c1c040404042a2a2a2a2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a040404041c04042a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515
-150a2a2a2a2a2a2a0e0e0e0e0e0e2a2a2a2a2a2a2a2a2a0e0e1c04042a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a
-2a0e0e0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a23
-15150a0303231515150a2a2a2a2a2a2a0e0e1c1c0e0e0e0e2a2a2a2a2a2a2a0e0e1c0404
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a2a2a0e0e0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c1c1c0e0e0e0e2a2a
-2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a0e0e0e0e1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c
-1c1c1c1c0e0e0e0e2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a0e0e0e0e1c1c1c1c1c04042a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a
-2a2a2a2a0e0e1c1c1c1c1c1c1c1c0e0e0e0e2a0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a0e0e0e0e1c1c1c1c1c1c
-1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a03
-03231515150a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c0e0e0e0e0e1c04042a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04040e0e0e0e
-1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c0e0e
-0e1c04040e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04040e0e1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c0e1c040e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c040e1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a
-0e0e04040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-04040404040404040404040404040404040404040404040404040404040404040404042a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515
-150a2a2a2a2a2a2a0e040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a23
-15150a0303231515150a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a0a2315150a030323151515150a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a1414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-14141414141414141414141414141414141414141414141414141414141414141414150a
-0a0a0a0a0a0a0a0a0a0a0a0a0a0a231515150a0302032315151515232323232323232323
-232323232315040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404232323232323232323232323232323231515150a03040103231515151515
-151515151515151515151515150a29292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-2929292929292929292929292929231515151515151515151515151515151515150a0304
-0101030a0a151515151515151515151515151515150a2929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292315151515151515151515151515
-1515150a0a03040402010103030a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515150a0a0a0a0a
-0a0a0a0a0a0a0a0a0a0a0a03030303040001020001030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303040403
-%%PageTrailer
-%%Trailer
-%%EOF
diff --git a/lib/et/doc/src/sim_trans_write_lock.gif b/lib/et/doc/src/sim_trans_write_lock.gif
deleted file mode 100644
index d62505fe35..0000000000
--- a/lib/et/doc/src/sim_trans_write_lock.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_write_lock.png b/lib/et/doc/src/sim_trans_write_lock.png
new file mode 100644
index 0000000000..1ce15a33c5
--- /dev/null
+++ b/lib/et/doc/src/sim_trans_write_lock.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_write_lock.ps b/lib/et/doc/src/sim_trans_write_lock.ps
deleted file mode 100644
index 80e03852dc..0000000000
--- a/lib/et/doc/src/sim_trans_write_lock.ps
+++ /dev/null
@@ -1,1287 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/sim_trans_write_lock.ps
-%%CreationDate: Mon Oct 14 17:06:30 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 359 199
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 184.755782 translate
-344.431594 -184.755782 scale
-% Image geometry
-412 221 8
-% Transformation matrix
-[ 412 0 0 221 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 412 string def
-/gstr 412 string def
-/bstr 412 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 74154 ASCII Bytes
-colorimage
-!AQV60nB=U!.b.=!<5%\0f_7E~>
-r'Z)9JH16$mf<8RJ,~>
-"DW"!C3+q+JH16$mf<B/!budtJ,~>
-r]0uYnc&S<J[C!8]<hPemJd0^mJd0^nc/Uh!]_tqJ,~>
-r^?bdnc&SGS\BZdT=P"ZmJd0[mJd0[nc/Uhr^;8~>
-rcA)>nc&SuJaS*W]C#Z.mJd0^mJd0^nc/Uhrc<S~>
-s"OQTs8W)KqVM,3!%EJWb_q%)n:Lcks3:GkqVM/4!i5k@qpkQ"r8n'Vs3:GkqVDD<s8N'Z3Ih~>
-s$Qngs8W)LrS%8-ro3q>!&U[?JWZ.Y!]9r&rmLesrS%8-ro3t?!hoY>rmLesrS%8-ro3t?!hoY>
-rmLesrS%8-"lfR^!(95*~>
-s)S5As8W)KqVM,3!+LN9J_n#q!b22SqpkQ"r8n'Vs3:GkqVM/4!i5k@qpkQ""m5jb!-<43~>
-!]^8\rRLc$qW7c,JTJMG!.4]d!.4]d!.4]d!/(8l!/(8l!/(8l!/(8l!/pht@uG\TF,PBdF,PBd
-F-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#m
-F-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-L_ps81@ChYZF9V#U>BqVM,3!Mobmeb\/$joWd-3Ih~>
-"%3.hdf.hrgA]t.ir/!>1kC(kI/nitI/nitI/o!#I/o!#I<UO!I=6s'I=7*+I=76/I=76/I=7B3
-I=7B3I=7B3I=7N7I=7N7I=7N7I=7N7I=7N7I=7Z;I=7Z;I=7Z;I=7Z;I=7Z?I=7Z?I=7Z?I=7Z?
-I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z72#mR'rmq&%rndY6roO6Ts8LIGf)=>%
-hYuO6joM1UrmLesrS%8-ro+%Bc2^7_~>
-!cnAArRLc$qW7ceJ^(mQ!7h(n!7h(n!7h(n!7h(n!7h(n!7h(n!7h(ns4..os4..os4..o>MdoT
-c/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!q
-c/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/-]Ss81@ChYZF9V#U>BqVM,3!Mobmeb\/$joWd-F+=~>
-!\j]Trmgl%qrRtJjsbjrr+Z:SK6,%I!-A-S!-A-S!.4][!.4][!.4][E.`4HC4gSBC4gSBC5[.J
-C5[.JC5[.JC5[.JC6WdSC6WdSC6WdSC6WdSC6WdSC6WdSC6WdSC6WdSC7K?[C7K?[C7K?[C7K?[
-C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[.KB=rqVM,3!q)lar71Z#qrRtJV#UAC
-qVM/4!mL^"J,~>
-!^m%grmq&%rndY6roO:IjtqX7r-8?lNIf5t!.Fil!.Fil!.k,pIYE2qH%gZlH&6rpH&[5tH'*N#
-H'*N#H'Nf'H'Nf'H's5/H's5/H's5/H's5/H(BM3H(BM3H(BM3H(BM3H(fe7H(fe7H(fe7H(fe7
-H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe72#l"Prmq&%rndY6roO@K
-U&WQhrmq&%rndY6roO@KU&WQhrmq&%rndY6s5jC.!(;>~>
-!cnAArmgl%qrRtJk$in\r5JZ[`l.r&rl"l^rl"l^rl"l^rl+o^s2G#_s2Ag)c,IZPc,IZPc,IZP
-c,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZP
-c,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,F/lr71Z#qrRtJV#UACqVM,3!q)lar71Z#
-r8n(*!-<Y~>
-!<E0!eb\/"k5XiMjsd0Bs5)RH%#`)>PlLd.hVN!^pA`c["nqt2CA.]*C&i>SC&i>SC&iV[C&iV[
-C3>/MC2/BBC2/BBC;m8qC2/ZJC2/uSC2/uSC2/uSC2/uSC2/uSC208[C208[C208[C208[C208[
-C208[C208[C20PkC20PkC20PkC20PkC20PkC20PkC20PkC20PkC20PkC20PkC20PkC20PkC2,3t
-rRLc$qr[qH!Moboeb;B/k5XiMV#UDD!o?4/rSIQ?rT41L]`<Q~>
-!<E0!f)=>%hYuO6k5X]IjtrrXs5)RS%$ehTSbiB7hVNBtpA3Ea#PS":FnYZSH2_pdH2_r9I<fsX
-JU)B\Km@f`M0X5dNHoYhNHoZdZ@-k<Q$mdtR=04#R=04#R=04#SUGX'SUGX'SUGX'Tm_'+Tm_'+
-Tn.?/Tn.?/V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3
-V1Ec3!]9c%rmq&%rndY6roX7G!hoJ=rmpp2r^?bJs69ZZqU5Ao"56"*gA]t/6ic6GjoXhZ!.Y~>
-!<E0!eb\/"k5XiMk$k4,s7Y9f%+Xdbec5[;p@cJEs8U`js8W,<s8N,=c2PZ^c2PZ^c2PZ^c2P]^
-c2Yc_c2Yc_c2Yb"e]l)$k0:lae]l(Pe]l(Pe]l(Pe]l(Pe]l(Pe]l(Pe]l(PhTa$YhTa$YhTa$Y
-hTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$Y
-@fQDWqVM,3s6]o`s8CLB62p$HmK'-`rRCu+5sbJ+s$?VG!q*`%J,~>
-!s&AOec+G*63#g?k5RaHmK)H!oO7iRPi6'PK9Yk7!J?X%@KP*)3T"9XKE%0%k5S=Fc-87Xp@^4M
-K9Y/#s7QRM@eTLMraGkBraGkBraGkKraL#7S75rSC1:Y!C1:Y)C1:YZs*J45C1:Y1C1:Y1C1:Y:
-C1:Y:C1:Y:F(/UCF(/UCF(/UCF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UK
-F(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF8fVL.KBCtqVM,3rpBf_s8LOKhY0>9k5OcLV#UGE!8dZ?
-s5*]?s5s@L!PJJ`~>
-!s&APf)FD'5l]^?iWA717/lHPi\^:E!KEZ/D#oWen8/2cSa(%ng<rOLD%VX$R8E&G=\-id88\(o
-4Dg(Kghm)b"?^Ppp,r=k!-S9XI<BOHD0^,<D4-r3D1Q\DD1utHD2ECPD79IqD38sXD3]6\D3]B`
-D3]B`D4,ZdD4,ZdD4,ZdD4PrhD4PrhD4PrhD4u5lD4u5lD4u5lD5DMpD5DMpD5DMpD5DMpD5DMp
-D5DMpD5DMpD5DMpD5DMpD5DMpD5DMpD5DOWD#lKirmq&%rndY6roX4F!MTAhec=G$5lF+Nk5OWH
-U&+c>!8@B:s5*]Bs5s@H!P/8]~>
-!s&AOec+G*63#g?k5RaHmK)HZoXt:Me`"1Bc.2<s!R90[]`RWaKAX?Sc2Z%QpA^%tk2q<0s8R/R
-c.1U_s8N4C^&S+Rrk/<Nrk/<Nrk/<Nrk8?^s1SHOs1N9o`P&t0`P&tIs2D[r`P&t0`P&t8`P&t8
-`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8
-`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`W!OO@fQGXqVM,3rpBf_s8LOKhY0>9k5OcLV#UGE!8dZ?
-s5*]?s5s@L!PJJ`~>
-!W`8NrndT>rT=,Gs%<=Z!Tkj'=p"Et9&a"UpA[bT=p"Et9'TU[3T"!Qk05VQp@^4=;E6a@p@^4E
-pA[b@>6":$0j=;E0j7air`T;2r`T;:r`X_bpA[a+@TlrV@Tlr^@Tlr^@a4%V@TlrfC0Ff!C0Ff!
-C0Ff!C0Ff!C0Ff*C0Ff*C0Ff*C0Ff*C0Ff*C0Ff*C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2
-C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2=t0L%eb\/"k5F]OV#SuqhVRum!9X7J"f21Ke_]0W
-5lg'HmK(!$J,~>
-!W`8Orn@<9ro*q?rBpbQmc$(qB`e#)=lO,spA.q^B`e#)=mB]%84;?L''@V)=n_\S@:_ttC%h6_
-C%hC+h.co_#<Z_op,m&'D>n7!EG]E(F_ti,H1q);I;N\4JT5C<KlLg@M/gu'H$*h8O`bAPQ$$eT
-Q$$eTQ$$eTR<<4XR<`L\R<`L\SU"p`SU"p`SU"p`Tm:?dTm:?dTm:?dTm:?dTm:?dTm:?dTm:?d
-Tm:?dTm:?dTm:?dTm:?dTm:?dTm:?dTm:?d"efWeqUX6rgA]t.ir8*>l3?[MqUX6OgAF566icBK
-l3?[MqUX6OgAF566icBKl2eHrJ,~>
-!W`8NrndT>rT=,Gs%<=Z!Tmk`[/^.+UuJc]rrAkb[/^.+V!>>eKAX$Kp?$Fds8R/A["F"<s8R/I
-s8SnN[/^.2F0tuIF0r<frj2[=rj2[=rj7*es8Sn.]sP/c]sP/c]sP/c^#nai]sP/k]sP/k]sP/k
-]sP/k]sP/k]sP/k]sP/k]sP/k]sP/k]sP/k]sP/s]sP/s]sP/s]sP/s]sP/s]sP/s]sP/s]sP/s
-]sP/s]sP/s]sP/s]sP/s]sP/s]sP/s]sP/sZss'ceb\/"k5F]OV#SuqhVRum!9X7J"f21Ke_]0W
-5lg'HmK(!$J,~>
-!<E/uhY]\>k5RaH9)n;[jsg1*#'8Z$mZ^VVrr2t>qGI]kk5YJLC/USis6cEV;ZGSWKC8c0;RHH'
-s)SY+s6c+L;Vp8_mf/eT[/U(0F*ldDs6bgA;CBH`K2PUKmS`cY;GqSms6c+LV#PL6`W(9_`P#/j
-hZ*#.;GuB.XPWnR"G?_q3Q;!t#\s)5;H!5^0spr[s)SV*s6c+L;Vp93hGX(Iqbdflk5YJLC/USi
-s6cEV;ZHG(0iI`=0iEATs6cCT;OlnLs6as8rr74iSF6FFS5OE3hVPs.;N(Qr;Gr-V;Gr-V;Gr-V
-;GrE^;GrE^;GrE^;GrEf;GrEf;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o
-;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;CV=iqVM,3r9aW^p=90!pHe`F!i5P?rSI?9!9X7J
-!PJJ`~>
-!<E/ugAXA;6il<0r'^SQ!TGs5AHmkFqX1%g^Ae-4L&,[email protected],h"d/6LTk1t;
-s8Rc^hYQZ6AS'l\Om`(>A\S0Ds+LU4qZ#uKqIM&"s-7/,[dI`#qIO5lhYQZ6A[;>iA]k%,A^8/(
-L#2[oTk.fpijRkFAH\:uI7VZ_rs3oDqIO73p,p(gs8Rc]hYQZ6AS'l\[c1llqYOh3Woj0Xl?Qs@
-lMp.Lral-''0Kk"p,loChYQZ:Bk==,qZ#i7^Ae.WM5ok@m]'iLET5utk%0hXI:ZuLF_,-HF_,-L
-F_,-LF_,-LF_,-PH"CQTH"CQTH"CQXH"CQXH"CQXH"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\
-H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"Ai+f)=>%hYuO6k5OZGmK0*Uf)FD%5l3tKlMp8R
-U%[(9gAXA86icBKl2pCb!.Y~>
-!<E/uhY]\>k5RaH9)n;[k$n4p#0$$1p=6P,rr2u;qQpX\pAb0d]sQ>`s7Y"B[/]h'c1_1f[,1f^
-s2>H8s7Y!M[.a4<pA`[MhZ!QT`<>W/s7X_6ZmY#9c*Xk7p9al"['[g?s7Y!MhZ(R%k5WE-k2s%i
-mf3"2[']Q#hY-oT"O6tBKBE15#eg9<[']l5F5Hors2>E7s7Y!M[.a4Mp9al"qm6a]pAb0d]sQ>`
-s7Y"B[/^.>F0tuIF0s3[s7Y!M[+4mMs7XForr75feb9%:e[3</p@dYB[*AWH['\)k['\)k['\)k
-['\)k['\)k['\)k['\)k['\)k['\)k['\As['\As['\As['\B&['\B&['\B&['\B&['\B&['\B&
-['\B&['\B&['\B&['\B&['\B&['\B&['\B&ZsraZqVM,3r9aW^p=90!pHe`F!i5P?rSI?9!9X7J
-!PJJ`~>
-!<E/thYKP;9)e5ZhC8A#$tAquC;p3V@eTh"3D03I25L9/HYSd2SH$Q3^&O<p;YL.I[/]P[@eTh"
-9(q[f`W'+>pAa!Vs6`0^pA\#Nk5TL+F';35;CIJ']h22jUbVT:0k0kEC;p3VHiK!rmf/2;p3TF*
-mV9`@>#P(ohP;n*;BrRK5tYV[s&(TFp+]J=p+^%Ms&)J_mV9`@>#P(ohP;mgjtZg4I\d##HYSd2
-SH$Q3^&O<p;YKf=;YKf=@eT5)`W',;s5&*;PX/LHs&,*]c!%g\S6Ahas5'P+MuTkNHX]lNK47_V
-K47_VMdfR^MdfR^MeZ-fMeZ-fMeZ-fP\O)oP\O)oP\O)oP\O)oP\O)oP\O)oP\O)oP\O)oP\O)o
-+d?_>;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;CV>9hYZI4mK'[email protected]!)!1W!MoGd
-hYTS=k5=WJ]`<Q~>
-!<E0!gAg"05kmbHmK)0$r*9_Fp?le7s(Q?DqHZ?dr*;1_s5JTPPuXOXb%\`mSR#Ops5LKel:c'g
-qHZqkmVTi@BjLH4ijSmP9PsM">sRQPH!tu0;#=NHOoN-l?0\FTp@^U_p?le7s(R2eO]CiLO]Ct'
-=n_9#_Z+=UpAa!L5lP%6])PT'EVB675kan6?2!tSD>*g3;"j<o_Z+=UpAa!L5j%&grEXlTs5JTP
-PuXOXb%\`mSR#Opp,lXSp,[email protected][5XC%hC/RK(QH_Z-HH?2"<XW^)^HY#'sl?!WG,
-?!WG,?!WG0?!WS4?!WS4?!W_8?!W_8?!W_8?!Wk@?!Wk@?!Wk@?!X"D?!X"D?!X"D?!X"D?!X"D
-?!SVEF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^890pAN_EhYuO6k5OZFmK'$TrRq<<hVS7k
-roO8MlK\B:!MT5cgAg"05l="Mk5OZGmK'm!J,~>
-!<E/thYKP;9)e5ZhI?Da%(-'.Ut,L@[/^/aH_gS@2:_`pXIQYUc2ZXbec3UiXT/=gec5'%[/^/a
-KE(Y@ec2GHs8VN;s6c,Ys8S"(pA^qHUm.DHX=2'feXW`7c$TKjF0tu@Ut,L@`W*<@pA_Lqs/_Ib
-p8$7=UoaUrm`g+XX<ZU%K:K=Ks,1sus)Y:As)YRIs,2O0p8$7=UoaUrm`g+PmW8?.Ib"JdXIQYU
-c2ZXbec3UiXT/<AXT/<A^&Rf%ec2Gqs6ctY[#;$cs,48ak*4Erc*XSPs6e-Yc2YbQ`O)_J`O)_J
-`O)_J`O)_J`O)_Jc*XRRc+U3[c+U3[c+U3[c+U3[c+U3[c+U3[c+U3[c+U3[c+U3[c+U3[c+U3[
-+jI^%XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XCCo"hYZI4mK'[email protected]!)!1W!MoGd
-hYTS=k5=WJ]`<Q~>
-!<E/uhZ)a:62aFUmf2t]hC8@p$^C[e3K*oi62(",62O80mf-0>5s[Nns%5:Ts5l=6pA[E5p@^45
-p@^5*s.hZ5s+<W2s$8C5p+]25p+\kqs/]]/62F2$pA[F"s&(lNp+_g3UcFA5K1c0W;ZH0u>5pmQ
-s.hZ5s+<W2s$8A"r^nE[s"Qf3p@^4,p@^45p@^45p@^5*s.hZ5s+<W2s$8A"8hi(!8q6:/;DCI'
-3Tg?63ElIF3D0#=0hV050pM^63K*oimf-0>8kM*0p@^6's%5:Ts5l=6pA[E5;Hj+>;Hc[bHWj$6
-K3Cl>K47GFK47GFK47GFK47GFMdf:NMdf:NMdf:NMdf:NMdf:NP[[6WP[[6WP[[6WP[[6WP[[6W
-P[aYb)3eT&8sEdW8sEdW8sEdW8sEdW8sEdW8sEfa8c^C7r8.>5qsOLX!MoGfh>fk=k5XiL9)e8Y
-p&Uu_r8%G9r':<Tr9aX[]`<Q~>
-!W`8Srnd\7qEtNYmdBZ:hDG.5$_@<t8<s43<VH,K<VooVmf-QX9MeFFs&DHus5m!XpA[fOp@^UO
-p@^V:s/JVTs+sbLs%G]Op,lLOp,l@;s/p?A:f[Bq-scE?:jr@P8G;a>Sc>]\Q2c\Ds2&@DlFq-8
-8=BLX8<s43<VH8[5Y1lW,L6<O<E]%h4B;+K4B_CO4B_CO4IQ5L8<s43<VH8[5Y,$C5lFi8mf-QX
-9MeFFs&DHus5m!Xp@^UOp@^V>s/Jb\s,$1D>sMOm9NCf[4QcZD6tQD\9Nh)c83g<ps2J2U=]pSu
-=]pSu=]p`$=]p`$=]p`$=]pl(=]pl,=]q#0=]q#0=]q#0=]q/4=]q/4=]q/4=]q/4=]q/4=]q/4
-=]q/4s&g5-EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EW0)C2"oYWrndY6roX4FrpKgW#,1bEg>:[O
-ro3q>s69SPrpKgW"/5GBgA]q/iql.DlMg2Qo""gO~>
-!<E/uhZ)a:62aFUmf2t]hI?DY$dJ^jK>mklSH&V1SGT*>pA^%tPa%+"s+>s*s6bf@s8R^us8RGA
-s8R/Zs2BW0s/_ajs+>[us*LRAs)X_(s2D(0PaqTGs8OC'^&O=Ts8R/bs2BW0s/_ajeXZ[5c)gql
-`W*o0`W*$0s8RFmMuKLsk5TLuV#UI9SH&V1V#UI9V#UI9`W*o0`W*$0s8RFmMkk]HrM4r:s,25g
-P`,88K7g9*mYdn@s)Y"9s)ZHb`Il/0XS2[PH^pUaV#UI9pA]btXT.^HV#UIAH^(W3eWd/2UqNk*
-UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:Us69BUs69BUs69BUs69BUs69B
-Us6:HU`%FaUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BrhKR(pAEeEk54THp&Uu_rS@N?qr[qH!)!7Y
-s7QJhpAEbIk57LF9)S)Yp:UHV~>
-!<E0!hYlU:62aFUmf)n\hC8@p!3H+u"IqdOp+cD9s8N*S62jLVrt7%P9)noG9(qs59(qs59(qs5
-XSi)3S3clB0hV050hV050hPoos8UVjq+;"$s+@]80gYO,0s(<Q$_0N5p5@2/k*4^WXSi)$S3clB
-1&OWX`W%Yb9(qs59(qs59(qs59(qs5XSi)$S3clB1&+B@rrFi?r_!4j%P^7As8OfGp@^45p@^5B
-r;V8:s8OfO;G'Pjp@^6@s"QfSs8Ofgp@^4U>"\h63D)nj>"VD>@S07F@S07F@S07F@S07F@S07N
-@S07N@S07N@S07N@S07N@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W
-@S07W@S07W@S05pPY*CurS@OMr'C<S!i58Prq6AgpANhJ62]mEmK-#Kmf)n\V"XcD!9X2Fr_!1X
-s7QK,!.Y~>
-!<E0!hYuL7k57UK8FGpFnc@H$r)j$&r;Qnj9_S0BqH<ju!C0Za=VU`44B5Pas$0`\p,l@Kp,lLO
-p,oMUrtCqsp@^UKp@^UOp@^UOEQ8%Yg3rd"$GQOs]&#PLp@^VOr;R.q9\T&sf"U:7i]OCArrnre
-p@^UKrE0i[s$0^ip@^UOp@^UOp@^UOp@^VOr;Qqk9_S0B<V]etrrGAbr`Kg/s#a:as8P>ep@^UO
-p@^VOr;V8;s8P>m@9H`Mp@^WFs#a;(s8P?0p@^UoBjLbY86K)LD-:"uD-:#$D-:#$D-:#$D-:#(
-D-:#(EEQG0EEQG0EEQG0EEQG0EEQG4EEQG4F]hk8F]hk8F]hk8F]hk8F]hk8F]hk8F]hk8F]hk8
-F]hk8F]hk8F]hk8F]hiMR9;B;gA]q/SbYYTV=*dNncGNUgA]q17,m5*k5OWI8FGpFncGNUgA]q/
-iqZ"Amf2hY\c@6~>
-!<E0!hYlU:62aFUmf)n\hI?DY!7h#I"ML'"s)\%4s8N+@SGo>art9CCV#UIAV#UI9V#UI9V#UI9
-eboF\]p/QsF/8j9F/8j9F/61ns8VN#q4nASs/b)FF.E:1F4L3g$b_emp9`u,m_/%0eboFM]p/Qs
-F8VgJk5TLuV#UI9V#UI9V#UI9V#UI9eboFM]p/QsF82R2rrI22rhTSo%We/9s8RGAs8R/9s8R/j
-r;V8[s8R/9XJDZ!s8R0?s)X^;s8RGQs8R/RXJGmHK;><VXJDZ2[%sM:[%sM:[%sM:[%sM:[%sM:
-[%sM:[%sM:[%sM:[%sM:[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB
-[%sMB[%sMB[%sK"c(nhBrS@OMr'C<S!i58Prq6AgpANhJ62]mEmK-#Kmf)n\V"XcD!9X2Fr_!1X
-s7QK,!.Y~>
-!s&AXhYZI69)n>Xp&X#!r(7$Ts.oTJ"$-)K1&=KDmf-Jh8f$Rh8kNRmjtTL%p+]25p+]25p+_g3
-V#<"]3VN/$9(qs59(qs58kMBAV#TjKqFV0;s4-h$0hV050pM^6r@n^@XT..QPlK:00pM^6r@nC7
-p@^6=8cc$nr_!4a%l$]Mp+]25p+]25p+_g3V#<"M3VN/$pdtVUs'#@n''B3d8n.h_0hV050hV05
-0pM^6r@r`_s&r;m8m5-dp+b_08nr,@jtU'5p+]`C@fN5a8pa`68qUSF8qUSF8qUSF8qUSF8qUSF
-8rI.N8rI.N8rI.N8rI.N8rI.N8sEdW8sEdW8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_
-8sF'_8sF'_8sF'_8d(An8h'K5h>l^962X=Tmeuh[V"XfE!Tl]Hk5F]K9()ZO!MoGgh>l^962X=T
-mf)n\]`<Q~>
-!s&AXhYuO6k5IaM8FGpFncJO=2#L>TRK'Gg49J.Jp,r1O!p]esrDaWqs&E'5s5lFDp@^UKp@^UK
-p@^V:s/u;_'1hij4B;+K4B;+K4B5BX=f)/`;#40#IK.adPsA@Cp,ncCY5LHk8?W!HV3V)7Y!AET
-Y5LHb8G;a>r)Ed's8H$up('8cp@^UKp@^UKp@^V:s/u;_"%`.Z4SVnXlMkGo<>+Ho<E3c5jucZ;
-p,l@Kp,ncCY5LJ2lMkEu<E3a=p@^W6s&F&]s5lFPp@^U[<GDK55ZNAL<E4li<E4li<E4li<E5#q
-<E5#q<E5#q<E5/u<E5/u<E5<$<E5<$<E5<(<E5H,<E5H,<E5H,<E5H,<E5H,<E5H,<E5H,<E5H,
-<E5H,<E5H,<E5H,<E5H,<E00iEE+jdrn[Y7q*b6R!:KjW!qr>Yrn[_97,n4.rosRQ8FHKJ!qr>Y
-rn[Y7q*b6R!:KjW!P/8]~>
-!s&AXhYZI69)n>Xp&X#Zr1!i-s2FqX",$XRF8DC.pA^BUS/1huK:K%CmW4ous)X_1s)X_1s)Z0Z
-`VjikKE(smSH&V1SH&V1S=Gh.`W,XrqO@u$s5s$gH^t-9F2e0urGrC"ec4dN[/]:5Hc?$(rGr'n
-s8R0<S/0ZTK:JJ3s)X_1s)X_1s)X_1s)Z0Z`Vji[KE(smpm_EZs-3JP'))?XS?2bYF.E:1F.E:1
-F2e0urGr&6s-3MQs.o\pG]WTYK<2H[mW53(s)Y!+XT-7dS@#)^S@u"oS@u"oS@u"oS@u"oS@u"o
-S@u"oS@u"oS@u"oSAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"
-SAhS"SAhS"SAhS"SAhS"@eTfX!9X2Fr(6tWrUp8fpAWnLk!At.rU'\Ymeuh[V"XfE!9X2Fr(6tW
-rq6B+!.Y~>
-!W`8Wqr[qHs%<=Zr:U0J.JudG;XXRTH^'.Tk5T0oqar`9s5o5dP[^0_]kYOdM_Ritp+]25p+]2%
-s(Z$2s."G#K1bk20hV050hUU.C/V-cC4lQC1&4Eemf3;Q3D0#=0iIH>S9pKQ8pgU<@UfB;C,o2[
-s."G#K1bk21&OWfF8pSQ9(qs59(qs59(qs59'6.g@da8dH^'.Tp@^459'5:68q*<1k)4SN@\!J3
-C;p420hV050hV050j=#FS:d&YSH%`0H^nhCk5T1ls1NKms,/U(p@^458u2Jr3I=q%8pb#>8qUSF
-8qUSF8qUSF8qUSF8qUSF8rI.N8rI.N8rI.N8rI.N8rI.N8sEdW8sF'_8sF'_8sF'_8sF'_8gT^:
-8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kLQ+hVRDWrB^<Qr:U>jp>4Zgk!B"/r9aPWr:U;i
-p>4Zgk5@UGmeocVp&Vi,J,~>
-!W`8Wro3q>s69\S8FGpFo)JCag,/_-$XrK"SV<>c<Ta=(@Ja%^U&X8;JXL5Cs2&p$s-5]Hp@^UK
-p@^[email protected]&/N7p,l@Kp,l@;s)hbUM04[ThE:U6,jPF09Lr1Wp,ldOqON>*M,f90s)E&Y
-s*7"@meWK.Q&/N7p,r7Q,(9KB:f[5_4B;+K4B;+K4B:PDF`$RCSV<>c<VH,K<E82Dr)J3>s5oGp
-R;&5l_KF$$Prr(?p,l@Kp,lpSqONV6M4st3Ob'?K<Ta=(Y5c@eb5[_l<VH,K<E64%D+&qh<E4`e
-<E4li<E4li<E5#q<E5#q<E5#q<E5/u<E5/u<E5/u<E5<(<E5<(<E5H,<E5H,<E5H,<E5H,<E5H,
-<E1?5EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-!qo%r6_iqc(B8H/2[p'.5]hVR8O7/l?J
-lMp8P8H/2[p'%/\hVR8OrC$\N!(?fWrpg-a\c@6~>
-!W`8Wqr[qHs%<=Zr:U0J@f2`(V"Xi-]u@[TpA^YYqj]Ogs6dS-`N7&YeZ@p5[!S>Cs)X_1s)X_(
-s.$1as2D[j]q#-&F.E:1F.Dt(S>=]KXM+YrHhj0WpAb/FMk'hIF/8O0`P'7(SA"t&S>?2bUk>K:
-s2D[j]q#-&F8VOP[/ZqdSH&V1SH&V1SH&V1SG)uQXS2\5]u@[Ts8R/1SF6+KS:8`_m_-!HXMt4i
-XQKPiH^t-9F.E:1F/8O0`P'7(c2[4F[*>tJpA^Z-s4+L=s0R-Cs8R/1SCRY(K=%GES@u"oS@u"o
-S@u"oS@u"oS@u"oS@u"oS@u"oS@u"oSAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"S0c.U
-S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=F'^hVRDWrB^<Qr:U>jp>4Zgk!B"/r9aPWr:U;i
-p>4Zgk5@UGmeocVp&Vi,J,~>
-!<E/sk54TDp&X#!qaq3)^%VKoMa<9ps(_C&1lL5js5mcVPii#.PVG0jp@^45p@^45Mt[0c>.sY0
-mYaC)p+]25p+]0tpA\mPpAaj*;DIu>,cq$b0gSG*p+]0K^%VKoMa:8@s#ECFs#EA;@_ML8mYaC)
-p+cG:s4&5X9(qs59(qs59(qs58rNECC0J=Es6be2p@^459(qs5r(;ErhZ*W<@R67@s5oP#3D0#=
-0hV050hPogpAaQ=8sJ34s5mcVSG)ttSEBk6S2!#rp@^45F5GG%C0F5%HX]T>K47GFK47GFK47GF
-K47GFK47GFMdf:NMdf:NMdf:NMdf:NMdf:NP[[6WP\Nf_P\Nf_P\Nf_P\Nf_P\U4j)3el.8sF'_
-8sF'_8sF'_8sF'_8sF'_8sF)i8cgI0hYuX=Ud7<D8cYsjp&_&XhYu[:62F4Op&_&XhYlU:62g6O
-9)SA`]`<Q~>
-!<E0!ir8*>lMg5No)A=`g,/\'$YdKOs6>S7NUlpc9`%XCQ/;Q;iakfOk5X_34@E$>p,l1Fp,l02
-o(m??_Y4#pNC`d:4AbbF4A_%.qJj[Ks7XT<5l"5%Y5cL(9MkHV4A]b/pAaE;86Puh6qmIW6qC-g
-_Y4#pNC`d:4SqtTef[L[p@^UFp@^UFp@^UFNUlpcBu9TDlA\@.p,l/Jp@^WH:k"\ds8(_d9UY&C
-lBOJ";"jTF;"jTF:hdf?s6>S?Q/;Q;iakfOo(m@"k5X_;4@E$>p,l/shUXf+APc3SAPc3WAPc3W
-Bi%W_Bi%W_Bi%WcBi%WcBi%WcBi%WgD,=&kD,=&kD,=&oD,=&oD,=&oD,=&oD,=&oD,=&oD?!EM
-Q#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#6Ls!]9?%ro*pOr'^NT!ikh^rq6Demb[s&qaCBRs760_
-!ho&=ro+"A6q%%>!q&TMrpp*_!P/8]~>
-!<E/sk54TDp&X#ZqihG`eb9%:[#;Wks.oLU1pl]Ns6c,0^$bpoZu^kas8R/)s8R/)^%VK%Ut,2=
-p9]bXs)XG)s)XF<pA^rNpAb0LMgP8a,gHA>F-Mphs)XF#eb9%:[#:ISs*K\(s*KZgUt,2=p9]bX
-s)\(%s5kG^PlLc)PlLc)PlLc)PeHejUnlQ7s7WgXs8R/)PlLc)r02Z;mf3=TP`*6Cs7Wg@K9ZE9
-F-Q_)F-NKNpAainMmVpPs6c,0`V0>-`U<d"]lSgjs8R/)XR>4lS>;C6[%rqN[%rqN[%rqN[%rqN
-[%rqN]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qk[m)82i1PeElW
-PeElWPeElWPeElWPeElWPeEmlPQG=^hYuX=Ud7<D8cYsjp&_&XhYu[:62F4Op&_&XhYlU:62g6O
-9)SA`]`<Q~>
-!<E/tk54TDp&b9E.JcX;5rnp!"$oOF1&CnOF%SIk0`jX53W:`53W;YN1&jlG1&jiL5qt)[5rnp!%
-RE]A0hP%m0hP&(0eksSr\4C5qYp_?8kM)u3W;YN1&jiH5rnp!#XM'T0el9m0erZ"!C8aF0`s^60
-erPt(1Q]r8kLfm8kLfm8kLfm8kMB(0gS)cr\4L@8hi("9)gXC8cUmM0`jX53W:`53W;YN1&jlG1
-&acF3W:`85tX-tr\4U\;F*#l8icl*EB-X+=tqaQV"RDH>"VD6>"VD>@S07F@S07F@S07F@S07F@
-S07N@S07N@S07N@S07N@S07N@S07W@S07WC._*_C._*_C._*_C._*_C._*_C._*_C._*_C._*_C
-._*_C._*_C._*_C._*_8h'3*k54TDp&b8imec/Dmec\Zs.o)[k54TDp&Vi,J,~>
-!s&A\ir8*>lMg5No)A=aqURM":]X6Tr]C9R:e3_FrrRIB8GtXP9Me.V49.eK;#`ZX;#`ZX:^'BP
-4A8F6r]CZ]:cpj::cpj::e3]29L/S>!'pD\"aNp@6p*a6;#`ZX:]X6Tr]CHW:f'8::f'8:r_NVh
-5lNkJ85ME2qbS&BnsN<N4?QG:4?QG:4?QG:83B".9L/S>"%Z6N4T81W4SqqT8GtXP9Me.V49.eK
-;#`ZX;#`ZX:^C&h4?Pl":e3kN4F:@:83B"76p*Rs6r8#34?Rnhnm+dp:f)^S:f)jW:f)j[:f*!_
-:f*!_:f*!_:f*-c:f*-c:f*9g:f*9k:f*9k:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo
-:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*ER2"(A&roX4FrpKdVrq6EiU$hp>roX4FrpKdVrq6EiU$hp>
-roX4FrpKdVrq6B(!.Y~>
-!<E/tk54TDp&b9E@eko^HiA'gK8YA'qYpVmMhD"M"+,raKDoolKDpf/F8q0uF8q.%K6)*dMgPGE%
-YK[\F,PrtF,Ps/F)ut\rc8'dqYp_pMi2q'HiAs'F8h'tHiA'lK8YY/F,PrtF8_!sHiA'gK8Xelq
-hl5[p:ZBBF*!7tF*!7tF*!7tK6)*dMgPGE"+uMQF8h*tF8LjqKDoooH]*f7rc8'lrepets,6nur
-egc'rc8O$Mh?@tF*j.9K6)*lKDoq3K8ZOiF*".rp5=QnMi4[,Mi4[,Mi4[,Mi4s4Mi4s4Mi4s4M
-i4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=M
-i59=Mi59=Mi59=Mi59,@da-UqsO@T!ro(aqr[eDqt:*kV!e-BqsO@T!PJJ`~>
-!<E/uk54TDpAb-neLBuRqCqt1bsD1\!'/Rq!b.Z[`^'Ssr]pNVr]tm/8jPa@8jPaH8jPaP8jPaP
-;F*T`;OgW>8jPaa;F*Tq>!YH$>!YH$>!YH$>!YH,>!YH,>!YH,>!YH,>!YH4>!YH4@R3;<@R3;<
-@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R39_Mdet$mel5Emec_X
-rrJq`r9!nEqtC'i!Mo/]k54TDp&b9-!.Y~>
-!W`8[roX4FrpKdVrq?Bg!S0*t:]OMl49/(#:]OMl49/(*:]b@%8B+L+<W>mF>ua]t@9HE'AQ_i+
-Bj"8/D-]t7EEuC;F^_+T5Zpo[JRqYSKk4(WKk4(WM.od_M.od_M.od_NG23cNG23cNG23cO_mok
-O_mokQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>o#*j%%
-2"'A_roX4FrpKdVrq?Bg"/5/Bir8*>lMg5No)A@_q?*GZio9t"rp'LNrpp'^!rBJ.J,~>
-!<E/uk54TDpAb-neRJ$+qJuXhc&;F>!/&g[!h?rV`esh]regc@repf@s,28pP`(HiP`(HiP`(Hq
-P`(HqPf8l6P`(I$S;W<,S;W<,S;W<4S;W<4S;W<4S;W<4S;W<4S;W<4S;W<4S;W<4S;W<=S;W<=
-S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;UkEr9!nEqtC'i
-!Mo/]k54TDpAb-nV!e0CqsO@T!roq6J,~>
-!<E0!k54TDpAY'meL?&8r]pNEa$B\tr]pNVr]u$38jPa@8jPaH8jPaP8jPaP;F*T`;F*T@8jPaa
-;F*Tq>!YH$>!YH$>!YH$>!YH,>!YH,>!YH,>!YH,>!YH,>!YH4@R3;<@R3;<@R3;<@R3;<@R3;<
-@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R39\.IR/sqsO@Trr3"pmeu;Fmec_W
-rrJq`rT="FqtC'i!PJJ`~>
-!<E0!k5OZFmf)eVpAXmhehhqOs%EGa7)qt$;#X.<<DZ@_>u43g@9#upAQ;DtBj",'D-9P+EEu73
-=]nElI:[email protected]@SM.K@SNG2'[NG2'[NG2'[O_IK_O_IK_Q"`oc
-Q"`ocQ"`ocQ"`ocQ"`ocQ"`ocQ"`ocQ"`ocQ"`ocQ"`ocQ"`oc#*imr9Jl1sroX4FrpKdVrq??f
-!ho&AroX4FrpKdVrq??f!ho&AroX4FrpKdVrq?Bg!P/8]~>
-!<E0!k54TDpAY'meRF)^rdt2ta+FAMrdt3/re(6/s+>`aMh?YHMh?YPMh?YPMh?YPMh?Y?Mh?YX
-P_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UqP_4UqP_4UqP_4UqS:cI$S:cI$S:cI$S:cI$
-S:cI$S:cI$S:cI$S:cI$S:cI$S:cI$S:cI$S:cI$S:cI$S:cH'meu;Fmec_WrrJq`rT="FqtC$h
-!Mo/^k54TDpAb-n]`<Q~>
-!W`8_qsO@Tr;QfJ.=k*B9"R[t.IQ?\qsO@Tr;QkpmcN[/mec_Urr](bk2uR/qtC!g!PJJ`~>
-!W`8_rp'LNrpp'^rqcZp!R`fU=f5Df<<G)Ck2u[.rpKdVrq??fs8N1plK77.lMg5No)A@^qZ$Qt
-U$Ce&rp'LNrpp'^rqZ]r\c@6~>
-!W`8_qsO@Tr;QfJ@Y(>+Uq<E)@d`C@qsO@Tr;QkpmcN[/mec_Urr](bk2uR/qtC!g!PJJ`~>
-!!)DN!%EI)JI&jn!%I<"!2T"H!2T"H!!%N~>
-!!)DK!&T64JI&jn!&X)*!28eB!28eB!!%N~>
-!!)DN!+LKbJI&jn!+P>[!2T"H!2T"H!!%N~>
-!<E0!joD3.s+13$s7-*mV#TT>]`<Q~>
-!<E0!joD*+s+13$s7-*mU&X9;\c@6~>
-!<E0!joD3.s+13$s7-*mV#TT>]`<Q~>
-!<E0!joD3.s+13$s760oK;AP0k.LbF~>
-!<E0!joD*+s+13$s760oJYE,+k.1PC~>
-!<E0!joD3.s+13$s760oK;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Uec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(IF!!:jS!:8G>!<1^P!!:jS!;tRN!:/A:!9Mr7!:SY;!!_-W!8?-,!.ijZgAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Uec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Uec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!;bFL!:8G>!<1^P!;Y@K!:8G>!<1^P!9W#8!:SYA!;bFL!<:dQ!.ijZgAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Uec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[hec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*o%O*Drn@APs4[DO
-rn@;Ns4[JQ"53_TgAM$OgA_-Sg&M-DgA_0OgA_-Tg&M-,r;clOr;clOrr</T!!(aO!.ijmgAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[hec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^p7?s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)TDrW)oN
-rrE)Qrr<;X!!(a,!!(aL!<:dQ!!(aP!!:jS!;"qE!<(XO!"[c`!8?-,!8?-,!8?-,!8@8Ls4[JQ
-J_HUIs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^p7?s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eX4neK*A(N
-k2s>WJ,~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA1d\g&M-,!!(a,!!(^Q!8?-,!:\_A!<:dQ!<:dQ
-!;tRN!!(aP!<:dQ!;tRN!<:dQ!;"qB!#!uc!87DQg=cN,g=cN,g=cN,gAV*PgAV)'g6gUoJH_bI
-k2s5TJ,~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eX4neK*A(N
-k2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"RaqFj"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo@j3Ern@AP$JGI[g&M-,g&M-,qZ-*=rVurPqZ-ZMqu?fP
-!!*#PrrDuNrrE)QrrDZErrE#Orr<>Y!!(a,!!(a,qZ$]O!!)rNrW%N'RbIdm"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"RaqFj"f21\k.LbF~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"S(7Ok"f21\
-k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQn(RdArn@AP%,([]g&M-,g&M-,!!)KArrE&Prr<,S!!)rN
-rrE)Qrr<,S!!*#PrrDuNrrE)QrrDZErrE#Orr<D[!!(a,!!(a,!!)rNrrDrMrW%N'S(dmn"ektY
-k.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"S(7Ok"f21\
-k.LbF~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eXP+hK*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)WErrE&P
-rr<Va!!(a,!!(^Q!8?-,!87DQrn@APs4[JQ#20%Wg=cN,o@j3ErS%8O#MK.Xg=cN,gAV*PgA_-S
-g&M-PgA_0QgA_/(g7-grJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eXP+hK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^p4>s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*n_3m@rn@;Nrn@>O
-!8@AOrS%2Ms4[JQs4[JQo@j3ErS%8O!nmVSrn@APs4[DOs4[JQrS%2MJ_HRHs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^p4>s+:KNs5rIW!.Y~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joD*+g4@t/g@<l#U&X9;\c@6~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joD3.eUc8)eaA%oeYN6-k.LbF~>
-!<E0!joD*+g4@t3g?sLrg7eQ/k.1PC~>
-!<E0!joD3.eUc8)eaA%oeYN6-k.LbF~>
-!<E0!joV@/eU_IdC5Qd*eaJ+qs4*qFk2s>WJ,~>
-!<E0!joV71g4=g+JVo$Xg@'Rts4X1Hk2s5TJ,~>
-!<E0!joV@/eU`X0Mi*GleaJ+qs4*qFk2s>WJ,~>
-!<E0!joV@/eU_IdC5Zg,mf(c:KDN7]KDN:]rs%#Ls5rIW!.Y~>
-!<E0!joV71g4=g+JW#'Zs8LaPJbm4`Jbm7`rs%2Ns5rIT!.Y~>
-!<E0!joV@/eU`X0Mi3Jns8LRKKDN7]KDN:]rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec1:!]`J.cqRuq/#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca$_?'[fqSN:4#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:!]`J.cqRuq/#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I5XT._fec1:!]`S4dKDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca$_?0agJc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:!]`S4dKDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec1:"^&S-4KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca%_Z0Z9Jc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:"^&S-4KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMX8o@#!;rqs!.h5AXT._fec1:"^&S*6eUrMP^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g&Tk*!;tRL!.ijogAh3PgAca%_Z0W;g4=hQ_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:joFQB!;u!X!.j:&k5YJ\ec1:"^&S*6eUrMP^&S*:eYN6-k.LbF~>
-!<E0!joqR2eS8j#qZ-Srq>gPsq>gMrrW)hsquHbuquHAjquHYrq>^MsrW)r!rVur"q>^MsquH#`
-!!)u!!!*#"!!)u!!!%SOSZMkZrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/qZ-TKq>gQLq>gNKrW)iLquHcNquHBCquHZKq>^NLrW)rOrVurPq>^NLquH$9
-!!)uO!!*#P!!)uO!!%T(S_F,Drn@C'rPJU7s4[L(r5/L6#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JqZ-TWq>gQXq>gNWrW)iXquHcZquHBOquHZWq>^NXrW)r[rVur\q>^NXquH$E
-!!)u[!!*#\!!)u[!!%T4S`]tPrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!#lq'.!3E7%XK2F"X8i7rX8i7tX8i7iX8i7rX8i8!X9/I(
-X8r1"!!*#"!!)u!!!*#"!!)5a!!)u!!!*#"!!)u!!!%SOSZMkZrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO#lr]5!8?-,g=cQ)g&M-Kg&M-Mg&M-Bg&M-Kg&M-Og&h?/
-g&V')!!*#P!!)uO!!*#P!!)6:!!)uO!!*#P!!)uO!!%T(S_F,Drn@C'rPJU7rn@C'rPJU7#25dN
-k2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[#ls,M!9WDDk2l[Ajo>DWjo>DYjo>DNjo>DWjo>D[joYVG
-joG>A!!*#\!!)u[!!*#\!!)6F!!)u[!!*#\!!)u[!!%T4S`]tPrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!#lq'.!3E7%XK2F#X9&C'!;`bs!;iht!:[&i!;W\r!<&u$
-!3E7%r2]kuri?)"rN#u!ri?)"poOJqm]6Bgri?)"rN#u!JZPEDs6fm:s+C<as8W&Js+C9`s8N;R
-V#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO#lr]5!8?-,g=cQ*g&_9.!;bCL!;kIM!:\\B!;Y=K!<(UR
-!8?-,r7V,Nrn7>PrRq5Orn7>PptG`Jmb.X@rn7>PrRq5OJ_H[Ks8W)Ps+10ds8W&Os+1-cs8N;W
-U&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[#ls,M!9WDDk2l[BjoPPF!;bgX!;kmY!:]+N!;YaW!<)$^
-!9WDDr8mtZroO1\rT4([roO1\pu_SVmcFKLroO1\rT4([J``Ncs8W)Ks+C<as8W&Js+C9`s8N;R
-V#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;`bu!3?1sX8i7tX8i7iX8i7rX9/I(X8r1"!!*#"
-!!)u!!s#F(!;rnu!;NYq!:Quh!<&u!!<&u!!.h5BXT._fec1:$^&S-1ec1:$^&S*:eYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;bCN!87GLg&M-Mg&M-Bg&M-Kg&h?/g&V')!!*#P
-!!)uO!s%'/!;tON!;P:J!:SVA!<(UO!<(UO!.ijpgAh3PgAca'_Z0Z6gAca'_Z0W?g7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;bgZ!9O:Xjo>DYjo>DNjo>DWjoYVGjoG>A!!*#\
-!!)u[!s%KG!;tsZ!;P^V!:T%M!<)$[!<)$[!.j:'k5YJ\ec1:$^&S-1ec1:$^&S*:eYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r1"!!*#"r;c\q!!)nt!!*#"!!)nt!!)nt!!)Mi!!)hrr;cbs!!*#"!!)u!
-r;cbs!!),^!!)qu!!)u!!!%SOSZMkZrmh%$s1SI4qpk_!rk8@3#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#Pr;c]J!!)oM!!*#P!!)oM!!)oM!!)NB!!)iKr;ccL!!*#P!!)uO
-r;ccL!!)-7!!)rN!!)uO!!%T(S_F,Drn@C's2+g9qqD($rke^8#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\r;c]V!!)oY!!*#\!!)oY!!)oY!!)NN!!)iWr;ccX!!*#\!!)u[
-r;ccX!!)-C!!)rZ!!)u[!!%T4S`]tPrmh%$s1SI4qpk_!rk8@3#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;ikq!;iht!;iht!<&u!!;3Dn!<&u!!<0&%!3E7%
-qlBi!X8r1"!s#F(!;rnu!<&u!!:-]d!;iht!<&u!!.h5BXT._fec1:%^&S-/ec1:%^&S*:eYN6-
-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;kLJ!;kIM!;kIM!<(UO!;5%G!<(UO!<1[S!8?-,
-qq;)Og&V')!s%'/!;tON!<(UO!:/>=!;kIM!<(UO!.ijpgAh3PgAca(_Z0Z4gAca(_Z0W?g7eQ/
-k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;kpV!;kmY!;kmY!<)$[!;5IS!<)$[!<2*_!9WDD
-qrRq[joG>A!s%KG!;tsZ!<)$[!:/bI!;kmY!<)$[!.j:'k5YJ\ec1:%^&S-/ec1:%^&S*:eYN6-
-k.LbF~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)u!!W];%r2]kurN#u!ri?)"rN#u!m&U0eqQ'YsrN#u!JZPEDs6fm:s+:Bds8VoFs+C?b
-s8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)uO!W^pSr7V,NrRq5Orn7>PrRq5Om+MF>qUtoLrRq5OJ_H[Ks8W)Ps+(6gs8VoKs+13e
-s8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)u[!W_?_r8mtZrT4([roO1\rT4([m,e9JqW7bXrT4([J``Ncs8W)Ks+:Bds8VoFs+C?b
-s8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)qu!!)nt!!)u!!!*#"!!)u!!!)u!rrDYl!!)u!!!*#"!!)u!!!%SOSZMkZrmh%$!knX6
-psoCs$,-B=eYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)rN!!)oM!!)uO!!*#P!!)uO!!)uOrrDZE!!)uO!!*#P!!)uO!!%T(S_F,Drn@C'!lG!;
-ptGb!$,Z`Bg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)rZ!!)oY!!)u[!!*#\!!)u[!!)u[rrDZQ!!)u[!!*#\!!)u[!!%T4S`]tPrmh%$!knX6
-psoCs$,-B=eYN6-k.LbF~>
-!<E0!joqR2eS8j#qZ-Srq>gMrquHbur;Zi!r;cl!quHbuq#L/jq#LGrq>gGp!!)quq>^Msq#LAp
-rrDYlqZ-Srr;_DMS?2bYrmh%$s8VbE$,-B=eYN6-k.LbF~>
-!<E0!joqI4g4=h/qZ-TKq>gNKquHcNr;ZiOr;clOquHcNq#L0Cq#LHKq>gHI!!)rNq>^NLq#LBI
-rrDZEqZ-TKr;_E&SD+#Crn@C's8VbC$,Z`Bg7eQ/k.1PC~>
-!<E0!joqR2eVf@JqZ-TWq>gNWquHcZr;Zi[r;cl[quHcZq#L0Oq#LHWq>gHU!!)rZq>^NXq#LBU
-rrDZQqZ-TWr;_E2SEBkOrmh%$s8VbE$,-B=eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec17%s7:mCrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc^(s7:gArs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec17%s7:mCrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec19m^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc`p_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19m^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec19krs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc`nrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19krs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec19nrs=>Xs4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc`qrs=8Vs4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19nrs=>Xs4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXN7IC!.h5mXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g;qtJ!.ikFgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k/cZb!.j:Rk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqR2eS8j#quHVqrW)ktqZ-Vsq>^MsquEau!!(0C!!)nt!!)2`rW)5brr@bSs6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/quHWJrW)lMqZ-WLq>^NLquEbN!!(0q!!)oM!!)39rW)6;rr@c,s8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@JquHWVrW)lYqZ-WXq>^NXquEbZ!!(1(!!)oY!!)3ErW)6Grr@c8s8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7pX8i7tX8i8!X8i8"X8i8!X8i8"X8i7!X8i7<X8i7^X8i7bX8i6SXT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Ig&M-Mg&M-Og&M-Pg&M-Og&M-Pg&M,Og&M,jg&M-7g&M-;g&M,,gAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DUjo>DYjo>D[jo>D\jo>D[jo>D\jo>C[jo>D!jo>DCjo>DGjo>C8k5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&"!<&u!!<0&"!;NYq!48j*!<'#!!<9/#!<9/"
-!<9/"!;ESo!<0)!!!]M)!3E7%!<'"u!;rqr!;iks!:d,j!;ikr!;iks!!0/$ri?/$XK;C$MQHjG
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[P!<(UO!<1[P!;P:J!4:JX!<(XO!<:dQ!<:dP
-!<:dP!;G4H!<1^O!!_-W!8?-,!<(XN!;tRK!;kLL!:ebC!;kLK!;kLL!!1dRrn7DRg=lN+MVA+1
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*\!<)$[!<2*\!;P^V!4:nd!<)'[!<;3]!<;3\
-!<;3\!;GXT!<2-[!!_Qc!9WDD!<)'Z!;u!W!;kpX!:f1O!;kpW!;kpX!!23^roO7^k2uXCMWXs=
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&%!3E7%r2]kupoOJqZ`F-,q5ai%X8o?'!3E7%
-rN#u!orJ,nr2]kuri?8'X8o?'!;rnu!;iht!;W\r!<0&"!:m2k!;rnu!<&u!!<&u!!<0)"!<0&%
-!3E7%LogXErmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[S!8?-,r7V,NptG`JZe>BZq:Z)Sg&Tj\!8?-,
-rRq5Op"BBGr7V,Nrn7MUg&Tj\!;tON!;kIM!;Y=K!<1[P!:nhD!;tON!<(UO!<(UO!<1^P!<1[S
-!8?-,Lt_n/rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*_!9WDDr8mtZpu_SVZfV5fq;qq_joFQ+!9WDD
-rT4([p#Z5Sr8mtZroO@ajoFQ+!;tsZ!;kmY!;YaW!<2*\!:o7P!;tsZ!<)$[!<)$[!<2-\!<2*_
-!9WDDM!"a;rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7rX8i8"X8i8!XS`(sXSi.sX8i7!X8i7rXT&:tX8i8!X8i7nX9J[+X8o?'
-!<0)"!;NVq!;iht!;`bs!;rnu!;!8l!<&u!!;ii"!3E7%r2]kuri?/$X8n$Ws6fm:s+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Kg&M-Pg&M-OgACsLgAM$Lg&M,Og&M-KgA_0Mg&M-Og&M-Gg'.Q2g&Tj\
-!<1^P!;P7J!;kIM!;bCL!;tON!;"nE!<(UO!;kIP!8?-,r7V,Nrn7DRg&Qo^s8W)Ps+14Mp=fOt
-s8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DWjo>D\jo>D[k555Xk5>;Xjo>C[jo>DWk5PGYjo>D[jo>DSjothJjoFQ+
-!<2-\!;P[V!;kmY!;bgX!;tsZ!;#=Q!<)$[!;km\!9WDDr8mtZroO7^joC2!s8W)Ks+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8"XS`(sX8i8!X8i8"X9/I(X8r1"!!)u!!!'.&!!)hr!!)hr!s#F(
-!;*>s!3E7%XK2F$X8i7pX8i7tX8i7sXSMqgX8i8!X8i7tX9/I(X8r$srr@eTs6fm:s+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-PgACsLg&M-Og&M-Pg&h?/g&V')!!)uO!!'.T!!)iK!!)iK!s%'/
-!;+tL!8?-,g=cQ+g&M-Ig&M-Mg&M-LgA1g@g&M-Og&M-Mg&h?/g&Up%rr@f-s8W)Ps+14Mp=fOt
-s8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\k555Xjo>D[jo>D\joYVGjoG>A!!)u[!!'.`!!)iW!!)iW!s%KG
-!;,CX!9WDDk2l[Cjo>DUjo>DYjo>DXk5#)Ljo>D[jo>DYjoYVGjoG2=rr@f9s8W)Ks+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!'.&!!)hr!!)hr
-!s#F(!;!8p!3?1%!<&u!!;EPp!;iht!;`bs!:?if!<&u!!;ii"!3E7%poFMsX8n$Ws6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!'.T!!)iK!!)iK
-!s%'/!;"nI!87G,!<(UO!;G1I!;kIM!;bCL!:AJ?!<(UO!;kIP!8?-,pt>cLg&Qo^s8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!'.`!!)iW!!)iW
-!s%KG!;#=U!9O:D!<)$[!;GUU!;kmY!;bgX!:AnK!<)$[!;km\!9WDDpuVVXjoC2!s8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)u!rrBC,!!*#"
-!!)u!!!)eqrrDVkrr<,%!!)u!!!)bp!!)nt!!*#"!!)u!!!)u!!!)Vl!!)qu!!)u!!!)u!!!)u!
-!!*#"!s#F(!/R`Vmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)uOrrBCZ!!*#P
-!!)uO!!)fJrrDWDrr<,S!!)uO!!)cI!!)oM!!*#P!!)uO!!)uO!!)WE!!)rN!!)uO!!)uO!!)uO
-!!*#P!s%'/!/TA/s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)u[rrBCf!!*#\
-!!)u[!!)fVrrDWPrr<,_!!)u[!!)cU!!)oY!!*#\!!)u[!!)u[!!)WQ!!)rZ!!)u[!!)u[!!)u[
-!!*#\!s%KG!/Te;s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#q#CDrr;Zi!r;Zi!qZ-Vsq>^Msq#LAprrB@+rW)nur;cYp!!)Skrr<,%!!*#"
-r;c_rquHYrrW)hsr;cJkquH\sr;c_rr;churrE)#rW%hWs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/q#CEKr;ZiOr;ZiOqZ-WLq>^NLq#LBIrrB@YrW)oNr;cZI!!)TDrr<,S!!*#P
-r;c`KquHZKrW)iLr;cKDquH]Lr;c`Kr;ciNrrE)QrW%i0s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@Jq#CEWr;Zi[r;Zi[qZ-WXq>^NXq#LBUrrB@erW)oZr;cZU!!)TPrr<,_!!*#\
-r;c`WquHZWrW)iXr;cKPquH]Xr;c`Wr;ciZrrE)]rW%i<s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXR3(h!.h5HXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g?mSo!.ik!gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3_:2!.j:-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXR3(h!.h5HXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g?mSo!.ik!gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3_:2!.j:-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXRE7h!<'"o!7\+F!.h67XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g@*bo!<(XH!7]`t!.ikegAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3qI2!<)'T!7^0+!.j:qk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXPU&Y!.h5XXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g>:Q`!.ik1gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k2,8#!.j:=k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSMnsXSW"qXSi.uXSr5!XSr3OX8i7hXSr4sXSr3NXO4-Lmf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!jp%O5g4=h/gA1dLgA:mJgAM$NgAV*OgAV)(g&M-AgAV*LgAV)'g<nXSs8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!jp%X3eVf@Jk5#&Xk5,/Vk5>;Zk5GA[k5G@4jo>DMk5GAXk5G@3k0`>ks8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!)u!!!*#"rrE&"rr@VO!!)Df!!)hr!!%SOdB*B9
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!)uO!!*#PrrE&Prr@W(!!)E?!!)iK!!%T(dG"X#
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!)u[!!*#\rrE&\rr@W4!!)EK!!)iW!!%T4dH:K/
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!s#F(!;ii%!3E7%X8o@$!<'#!!3E:%!!]M)!3?/#XSr5"
-XSr4mXS`(tX8r=&rW)hsrW)er!!)hr!!%SOdB*B9rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!s%'/!;kIS!8?-,g&Tk+!<(XO!3FoS!!_-W!87DQgAV*P
-gAV*FgACsMg&V3-rW)iLrW)fK!!)iK!!%T(dG"X#rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!s%KG!;km_!9WDDjoFQC!<)'[!3G>_!!_Qc!9O7]k5GA\
-k5GARk555YjoGJErW)iXrW)fW!!)iW!!%T4dH:K/rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX9/I(X8r4#!!)u!!s#F(!;ii(!3E7%X8o=%X8r4#rrB+$rr<;*!!')#XK2F#
-X8i7nX8i8!X8i8"XT&;"X8i8!X8i8"X8i7tX8i7rX8i6OXO4-Lmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hSg&h?/g&V**!!)uO!s%'/!;kIV!8?-,g&Th,g&V**rrB+Rrr<;X!!(^Qg=cQ*
-g&M-Gg&M-Og&M-PgA_0Pg&M-Og&M-Pg&M-Mg&M-Kg&M,(g<nXSs8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@bjoYVGjoGAB!!)u[!s%KG!;kmb!9WDDjoFNDjoGABrrB+^rr<;d!!)-]k2l[B
-jo>DSjo>D[jo>D\k5PG\jo>D[jo>D\jo>DYjo>DWjo>C4k0`>ks8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8juXSi.tX8i8"X8i8"X8i7tX9em.X8o?'!3E7%V5st'XK2E'X8o?'!<&u!!;3Dn
-!;W\r!<&u!!<0&"!;rnu!;rnu!;W\r!.h6!XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSgAM$Mg&M-Pg&M-Pg&M-Mg'Ic5g&Tj\!8?-,V:l4Ug=cP\g&Tj\!<(UO!;5%G
-!;Y=K!<(UO!<1[P!;tON!;tON!;Y=K!.ikOgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bk5>;Yjo>D\jo>D\jo>DYjp;%MjoFQ+!9WDDV</'ak2l[+joFQ+!<)$[!;5IS
-!;YaW!<)$[!<2*\!;tsZ!;tsZ!;YaW!.j:[k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX9/I(X8r4#r;cet!!)nt#lq'.!3E7%XK2DuX9J[+X8o?'!<0&%!3E7%o;qlj
-rN#u!rN#u!riGqrr2]kuq5aPrJZR8#s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&h?/g&V**r;cfM!!)oM#lr]5!8?-,g=cP'g'.Q2g&Tj\!<1[S!8?-,o@j-C
-rRq5OrRq5Orn@2Kr7V,Nq:YfKJ_JN*s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjoYVGjoGABr;cfY!!)oY#ls,M!9WDDk2lZ?jothJjoFQ+!<2*_!9WDDoB,uO
-rT4([rT4([roX%Wr8mtZq;qYWJ`bABs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7sX8i8"X8i8"X8i7tX9/I(X8r1"!!&js"ota+!3E7%ri?2%XK2EjX8i8"
-X8i8!X8i8"X8i7oX8i7rX8i6OXO4-Lmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Pg&M-Pg&M-Mg&h?/g&V')!!&kL"p!B2!8?-,rn7GSg=cPqg&M-P
-g&M-Og&M-Pg&M-Hg&M-Kg&M,(g<nXSs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>D\jo>D\jo>DYjoYVGjoG>A!!&kX"p!fJ!9WDDroO:_k2l[4jo>D\
-jo>D[jo>D\jo>DTjo>DWjo>C4k0`>ks8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7sX8i8!X8i8"X8i8!X8i8"X8i7uX8i8!XT&:$X9J[+X8o?'!<'#!!;!8l
-!<&u!!<0&"!<&u!!<&u!!<&u!!;rnu!;W\r!.h6!XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Lg&M-Og&M-Pg&M-Og&M-Pg&M-Ng&M-OgA_/Rg'.Q2g&Tj\!<(XO!;"nE
-!<(UO!<1[P!<(UO!<(UO!<(UO!;tON!;Y=K!.ikOgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DXjo>D[jo>D\jo>D[jo>D\jo>DZjo>D[k5PF^jothJjoFQ+!<)'[!;#=Q
-!<)$[!<2*\!<)$[!<)$[!<)$[!;tsZ!;YaW!.j:[k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSi.tXSr4uX8i8"XSi.uXSr5!XSr5!XT&:%XSr2'X8i7%!!)u!!!)VlquH_t
-rW)u"rW)nur;cetquH\squD;Le#`T;rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gAM$MgAV*Ng&M-PgAM$NgAV*OgAV*OgA_/SgAV'Ug&M-,!!)uO!!)WEquH`M
-rW)uPrW)oNr;cfMquH]LquD<%e(Xj%rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5>;Yk5GAZjo>D\k5>;Zk5GA[k5GA[k5PF_k5G>ajo>DD!!)u[!!)WQquH`Y
-rW)u\rW)oZr;cfYquH]XquD<1e)p]1rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXS/^q!.h5?XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g@j5#!.ijmgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k4[p;!.j:$k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXS/^q!.h5?XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g@j5#!.ijmgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k4[p;!.j:$k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXSAmq!<'"o!.h5MXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+gA'D#!<(XH!.ik&gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k4n*;!<)'T!.j:2k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXP0`U!.h5[XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g=k6\!.ik4gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k1\qt!.j:@k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSMqrXSi-MXQlke!9pTa!:$Zc!.h6:XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1gKgAM#&g?RAl!9r5:!:&;<!.ikhgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#)Wk5>:2k3D(/!9rYF!:&_H!.j:tk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i6OXO+$K!9pQb!.h6:XT._fec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M,(g<eOR!9r2;!.ikhgAh3PgAca(s7Y1HJcG`Sg7eQ/
-k.1PC~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>C4k0W5j!9rVG!.j:tk5YJ\ec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!jq"9<eS8j#X8o?'!3E7%X8r.!!!)u!rrALhrr<A,!!')#!3?/#XSr4sXSr4tXS`(sXSr4s
-XSi.hX8i7tXSi.rXSr2#X8r7$!W]='rW)nurW)nurrE)#rr@VO!j(hXrmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!jq"0>g4=h/g&Tj\!8?-,g&V$(!!)uOrrAMArr<AZ!!(^Q!87DQgAV*LgAV*MgACsLgAV*L
-gAM$Ag&M-MgAM$KgAV'Qg&V-+!W^s.rW)oNrW)oNrrE)Qrr@W(!o!\Srn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!jq"9<eVf@JjoFQ+!9WDDjoG;@!!)u[rrAMMrr<Af!!)-]!9O7]k5GAXk5GAYk555Xk5GAX
-k5>;Mjo>DYk5>;Wk5G>]joGDC!W_BFrW)oZrW)oZrrE)]rr@W4!p9O_rmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i8!XT&9gXT&8+X8i7%!3E7%!<0&"!<&u!!<0&"!<0&"!<&u!
-!;iht!;rnu!<&u!!:m2k!;rnu!<&u!!<&u!!<0)"!<0&%!3E7%r2]kuri?)"rN$/&X8o?'!.h6O
-mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M-OgA_/@gA_-Yg&M-,!8?-,!<1[P!<(UO!<1[P!<1[P!<(UO
-!;kIM!;tON!<(UO!:nhD!;tON!<(UO!<(UO!<1^P!<1[S!8?-,r7V,Nrn7>PrRqDTg&Tj\!.il(
-s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>D[k5PFLk5PDejo>DD!9WDD!<2*\!<)$[!<2*\!<2*\!<)$[
-!;kmY!;tsZ!<)$[!:o7P!;tsZ!<)$[!<)$[!<2-\!<2*_!9WDDr8mtZroO1\rT47`joFQ+!.j;4
-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9em.X8o?'!3E7%rN#u!ri?)"r2]u#XK2EqX8i7pX8i7k
-X8i8!X8i7tX9/I(X8r1"!!*#"!W];%r2]kur2]kuriH,"JZSgOs6fm:s+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'Ic5g&Tj\!8?-,rRq5Orn7>Pr7V5Qg=cQ#g&M-Ig&M-D
-g&M-Og&M-Mg&h?/g&V')!!*#P!W^pSr7V,Nr7V,Nrn@APJ_L(Vs8W)Ps+14Mp=fOts8N;WU&X9;
-\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjp;%MjoFQ+!9WDDrT4([roO1\r8n(]k2l[;jo>DUjo>DP
-jo>D[jo>DYjoYVGjoG>A!!*#\!W_?_r8mtZr8mtZroX4\J`cpns8W)Ks+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9em.X8o?'!3E7%rN#u!riGqrriH%uqQ'YsqlK\qnuMfk
-rN#u!qlBl"XK2EsXT&:tXSMqrX8i6OXSf1"mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'Ic5g&Tj\!8?-,rRq5Orn@2Krn@;NqUtoLqqCrJo%F'D
-rRq5Oqq;,Pg=cQ%gA_0MgA1gKg&M,(gAK\)s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjp;%MjoFQ+!9WDDrT4([roX%WroX.ZqW7bXqr[eVo&]oP
-rT4([qrRt\k2l[=k5PGYk5#)Wjo>C4k5=BAs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9em.X8o?'!3E7%rN#u!ri?)"oW/#mqlBbtr2]kurN#u!
-nuMfkrN#u!qlBl"XK2EsX9&C'!;rnu!;NVq!.h6LXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'Ic5g&Tj\!8?-,rRq5Orn7>Po\'9Fqq;#Mr7V,NrRq5O
-o%F'DrRq5Oqq;,Pg=cQ%g&_9.!;tON!;P7J!.il%gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjp;%MjoFQ+!9WDDrT4([roO1\o]?,RqrRkYr8mtZrT4([
-o&]oPrT4([qrRt\k2l[=joPPF!;tsZ!;P[V!.j;1k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i7uXT&9gX9em.X8o?'!3E7%rN#u!rN#u!rN$)$XK2F#X8i7t
-X8i7uX8i8"XT&:kX8i7uX8i8!X8i8!X8i8!X8i8"X9/I(X8r1"!!)u!!!*#"!!%SOr2fqdrmh%$
-s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-NgA_/@g'Ic5g&Tj\!8?-,rRq5OrRq5OrRq>Rg=cQ*g&M-M
-g&M-Ng&M-PgA_0Dg&M-Ng&M-Og&M-Og&M-Og&M-Pg&h?/g&V')!!)uO!!*#P!!%T(r7_2Nrn@C'
-s8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>DZk5PFLjp;%MjoFQ+!9WDDrT4([rT4([rT41^k2l[Bjo>DY
-jo>DZjo>D\k5PGPjo>DZjo>D[jo>D[jo>D[jo>D\joYVGjoG>A!!)u[!!*#\!!%T4r9"%Zrmh%$
-s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juXS`(sXSi.rXT&9hXSr2%X8i7%quHburW)nur;chuquHYrquH\srW!#$!!)\n
-quH\sr;c_rr;churrE)#rW)nur;chur;_DMriH.frmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSgACsLgAM$KgA_/AgAV'Sg&M-,quHcNrW)oNr;ciNquHZKquH]LrW!#R!!)]G
-quH]Lr;c`Kr;ciNrrE)QrW)oNr;ciNr;_E&rn@DPrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bk555Xk5>;Wk5PFMk5G>_jo>DDquHcZrW)oZr;ciZquHZWquH]XrW!#^!!)]S
-quH]Xr;c`Wr;ciZrrE)]rW)oZr;ciZr;_E2roX7\rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXN[d@!.h5qXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g<A:G!.ikJgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k02u_!.j:Vk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMX8o@#!;rqs!;rqs!;rqs!:m2k!;`eq!:m2k!;NYq!:m2k!;NYq!;!;j!<'"r
-!:m5k!;rqt!:m5i!;iks!;iht!;W_q!;`es!;iht!:m5kmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g&Tk*!;tRL!;tRL!;tRL!:nhD!;bFJ!:nhD!;P:J!:nhD!;P:J!;"qC!<(XK
-!:nkD!;tRM!:nkB!;kLL!;kIM!;Y@J!;bFL!;kIM!:nkDs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:joFQB!;u!X!;u!X!;u!X!:o7P!;bjV!:o7P!;P^V!:o7P!;P^V!;#@O!<)'W
-!:o:P!;u!Y!:o:N!;kpX!;kmY!;YdV!;bjX!;kmY!:o:Ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSW"rXSr4uXSW"qXSr2#X8r7$q>^MsqZ+%*!!)u!!!*#"!!)u!!!*#"!!)u!
-!!*#"!!)u!!!)YmrrDqt!!)u!!!)YmrrDkr!W];%o;qrlq5aVtX8qmo!!)u!!!*#"!!)u!!!)Vl
-!W];%rN#u!ri?)"oW/#mrN#u!rN#u!q5jSrqQ'YspoFMsX8r1"rrDVks6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!jp%O5g4=h/gA:mKgAV*NgA:mJgAV'Qg&V-+q>^NLqZ+%X!!)uO!!*#P!!)uO!!*#P!!)uO
-!!*#P!!)uO!!)ZFrrDrM!!)uO!!)ZFrrDlK!W^pSo@j3Eq:YlMg&Ud!!!)uO!!*#P!!)uO!!)WE
-!W^pSrRq5Orn7>Po\'9FrRq5OrRq5Oq:biKqUtoLpt>cLg&V')rrDWDs8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!jp%X3eVf@Jk5,/Wk5GAZk5,/Vk5G>]joGDCq>^NXqZ+%d!!)u[!!*#\!!)u[!!*#\!!)u[
-!!*#\!!)u[!!)ZRrrDrY!!)u[!!)ZRrrDlW!W_?_oB-&Qq;q_YjoG&9!!)u[!!*#\!!)u[!!)WQ
-!W_?_rT4([roO1\o]?,RrT4([rT4([q<%\WqW7bXpuVVXjoG>ArrDWPs8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i7uX8i7uX8i8!X8i8"X8i8"XT&;!X8i8!X9/I(X8r4#!!'I/!!)u!
-!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)\n!W];%qlBbtrN#u!orJ2pX8r't!W];%oW/)oX8r't
-!W];%oW/#mrN#u!q5aPro;hunX8r4#!!)u!!!)\n!!)u!!!*#"!!)hr!W];%qlBbtpT+DrX8r4#
-!W];%nuVlZrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&M-Ng&M-Ng&M-Og&M-Pg&M-PgA_0Og&M-Og&h?/g&V**!!'I]!!)uO
-!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)]G!W^pSqq;#MrRq5Op"BHIg&Us&!W^pSo\'?Hg&Us&
-!W^pSo\'9FrRq5Oq:YfKo@a6Gg&V**!!)uO!!)]G!!)uO!!*#P!!)iK!W^pSqq;#MpY#ZKg&V**
-!W^pSo%O-Drn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[jo>DZjo>DZjo>D[jo>D\jo>D\k5PG[jo>D[joYVGjoGAB!!'Ii!!)u[
-!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)]S!W_?_qrRkYrT4([p#Z;UjoG5>!W_?_o]?2TjoG5>
-!W_?_o]?,RrT4([q;qYWoB$)SjoGAB!!)u[!!)]S!!)u[!!*#\!!)iW!W_?_qrRkYpZ;MWjoGAB
-!W_?_o&fuPrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!<&u!!<&u!!<&u$!3E7%r2]kurN-#!
-\?#Z1ri?)"rN#u!ri?)"rN#u!q5aPro;holqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8q^j
-!!)ks!!)Vl!s#F(!<&u!!<&u!!:[&i!<0&"!;EPp!;iht!;NVt!3E7%qlBbtnuVlZrmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!<(UO!<(UO!<(UR!8?-,r7V,NrS%8O
-\Cpo_rn7>PrRq5Orn7>PrRq5Oq:YfKo@a0Eqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UTq
-!!)lL!!)WE!s%'/!<(UO!<(UO!:\\B!<1[P!;G1I!;kIM!;P7M!8?-,qq;#Mo%O-Drn@C's8VfH
-s+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!<)$[!<)$[!<)$^!9WDDr8mtZrT=+[
-\E3bkroO1\rT4([roO1\rT4([q;qYWoB$#QqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFl4
-!!)lX!!)WQ!s%KG!<)$[!<)$[!:]+N!<2*\!;GUU!;kmY!;P[Y!9WDDqrRkYo&fuPrmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!;NVt!3E7%rN#u!r2]kurN-#!\Z>c2
-rN#u!rN#u!ri?)"rN#u!qQ'YsnuMfkqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8qak!!)hr
-!!)Vl!s#F(!<&u!!<0)"!:d,j!<&u"!3H/"qlBbtqlBeuXSr4tX9/I(X8r.!!!)Sks6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!;P7M!8?-,rRq5Or7V,NrS%8O\_7#`
-rRq5OrRq5Orn7>PrRq5OqUtoLo%F'Dqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UWr!!)iK
-!!)WE!s%'/!<(UO!<1^P!:ebC!<(UP!8@DPqq;#Mqq;&NgAV*Mg&h?/g&V$(!!)TDs8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!;P[Y!9WDDrT4([r8mtZrT=+[\`Nkl
-rT4([rT4([roO1\rT4([qW7bXo&]oPqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFo5!!)iW
-!!)WQ!s%KG!<)$[!<2-\!:f1O!<)$\!9X7\qrRkYqrRnZk5GAYjoYVGjoG;@!!)TPs8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8"X8i8"X8i8"X8i8"X8i7uXSi.sXSi.tX8i7uX8i7-X8i7uX8i8!
-X8i8"X8i8!X8i7tX8i7uXSW"qX8i7tX8i8!X8i8"XSW"qX8i7tX8i8"X8i7kX8i7tX8i8"X8i7j
-X8i7qX8i7mX8i8"X8i7uXSr2#X8qgm!!)qurrE&"!!)qu!!)ntrrE&"!!*#"!!*#"!!)nt!!)Sk
-s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-Pg&M-Pg&M-Pg&M-Pg&M-NgAM$LgAM$Mg&M-Ng&M,[g&M-Ng&M-O
-g&M-Pg&M-Og&M-Mg&M-NgA:mJg&M-Mg&M-Og&M-PgA:mJg&M-Mg&M-Pg&M-Dg&M-Mg&M-Pg&M-C
-g&M-Jg&M-Fg&M-Pg&M-NgAV'Qg&U]t!!)rNrrE&P!!)rN!!)oMrrE&P!!*#P!!*#P!!)oM!!)TD
-s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\jo>D\jo>D\jo>D\jo>DZk5>;Xk5>;Yjo>DZjo>Cgjo>DZjo>D[
-jo>D\jo>D[jo>DYjo>DZk5,/Vjo>DYjo>D[jo>D\k5,/Vjo>DYjo>D\jo>DPjo>DYjo>D\jo>DO
-jo>DVjo>DRjo>D\jo>DZk5G>]joFu7!!)rZrrE&\!!)rZ!!)oYrrE&\!!*#\!!*#\!!)oY!!)TP
-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXS`(sXS`(tXSi.nX8i8!X9/I(X8r4#!!)qu!!'F.!!)nt!!)u!!!*#"!!)u!
-!!)qu!!)Mi!!)nt!!)u!!!)Vl!!)nt!!*#"!!)Sk!!)nt!!*#"!!)Sk!!)eq!!)Vl!!*#"!!)eq
-!!)Vl!!)nt!!)u!!!)qu!!)nt!!)u!!!*#"!!*#"!!)nt!!)Sks6fm:s+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johC3g4=hSgACsLgACsMgAM$Gg&M-Og&h?/g&V**!!)rN!!'F\!!)oM!!)uO!!*#P!!)uO
-!!)rN!!)NB!!)oM!!)uO!!)WE!!)oM!!*#P!!)TD!!)oM!!*#P!!)TD!!)fJ!!)WE!!*#P!!)fJ
-!!)WE!!)oM!!)uO!!)rN!!)oM!!)uO!!*#P!!*#P!!)oM!!)TDs8W)Ps+14Mp=fOts8N;WU&X9;
-\c@6~>
-!<E0!johL1eVf@bk555Xk555Yk5>;Sjo>D[joYVGjoGAB!!)rZ!!'Fh!!)oY!!)u[!!*#\!!)u[
-!!)rZ!!)NN!!)oY!!)u[!!)WQ!!)oY!!*#\!!)TP!!)oY!!*#\!!)TP!!)fV!!)WQ!!*#\!!)fV
-!!)WQ!!)oY!!)u[!!)rZ!!)oY!!)u[!!*#\!!*#\!!)oY!!)TPs8W)Ks+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r7$!!)u!!!)u!!!)u!!!)u!!s#F(!;rnu!4Js/!;`bs
-!<&u!!<0&"!<&u!!<&u!!:Quh!;iht!<&u!!;!8l!;ikp!;!8l!;ikp!;*>m!;EPp!;!;h!;W\r
-!;*>m!;`bs!<&u!!;rnu!;iht!<&u!!<0(s!;rnu!:m5kmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V-+!!)uO!!)uO!!)uO!!)uO!s%'/!;tON!4LS]!;bCL
-!<(UO!<1[P!<(UO!<(UO!:SVA!;kIM!<(UO!;"nE!;kLI!;"nE!;kLI!;+tF!;G1I!;"qA!;Y=K
-!;+tF!;bCL!<(UO!;tON!;kIM!<(UO!<1^L!;tON!:nkDs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGDC!!)u[!!)u[!!)u[!!)u[!s%KG!;tsZ!4M"i!;bgX
-!<)$[!<2*\!<)$[!<)$[!:T%M!;kmY!<)$[!;#=Q!;kpU!;#=Q!;kpU!;,CR!;GUU!;#@M!;YaW
-!;,CR!;bgX!<)$[!;tsZ!;kmY!<)$[!<2-X!;tsZ!:o:Ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r4#!!*#"rrE&"!!)u!!!)u!!s#F(!<&u!!;rqu!55H6
-!<&u!!<0&"!<&u!!<0&"!<&u!!<0&"!<&u!!;!8l!;iht!<&u!!;!8l!;EPp!:m2k!;EPp!;ikt
-!;rnu!<&u!!;iht!;`es!;NVq!;W\r!;ikt!;rnu!<&u!!<&u!!<0&"!;rnu!;`bs!<0&"!;`bs
-!;iht!:m5kmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V**!!*#PrrE&P!!)uO!!)uO!s%'/!<(UO!;tRN!57(d
-!<(UO!<1[P!<(UO!<1[P!<(UO!<1[P!<(UO!;"nE!;kIM!<(UO!;"nE!;G1I!:nhD!;G1I!;kLM
-!;tON!<(UO!;kIM!;bFL!;P7J!;Y=K!;kLM!;tON!<(UO!<(UO!<1[P!;tON!;bCL!<1[P!;bCL
-!;kIM!:nkDs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGAB!!*#\rrE&\!!)u[!!)u[!s%KG!<)$[!;u!Z!57Lp
-!<)$[!<2*\!<)$[!<2*\!<)$[!<2*\!<)$[!;#=Q!;kmY!<)$[!;#=Q!;GUU!:o7P!;GUU!;kpY
-!;tsZ!<)$[!;kmY!;bjX!;P[V!;YaW!;kpY!;tsZ!<)$[!<)$[!<2*\!;tsZ!;bgX!<2*\!;bgX
-!;kmY!:o:Ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSi.tXSi,!XSMqqX98O)X8o@$!<'"q!!'+t!;ikt!55K2!<'"t!;rqs!<'"r
-!;3Gk!;rqs!;*Aj!;`er!;3Gk!;`er!;rqu!;rqq!;iht!;`es!;W_q!<'"u!;`es!;rqq!;rqt
-!<'"s!;iks!;`er!<0(t!;*Ammf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%O5g4=h/gAM$MgAM!OgA1gJg&qE0g&Tk+!<(XJ!!(aM!;kLM!57+`!<(XM!;tRL!<(XK
-!;5(D!;tRL!;,"C!;bFK!;5(D!;bFK!;tRN!;tRJ!;kIM!;bFL!;Y@J!<(XN!;bFL!;tRJ!;tRM
-!<(XL!;kLL!;bFK!<1^M!;,"Fs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp%X3eVf@Jk5>;Yk5>8[k5#)Vjob\HjoFQC!<)'V!!)0Y!;kpY!57Ol!<)'Y!;u!X!<)'W
-!;5LP!;u!X!;,FO!;bjW!;5LP!;bjW!;u!Z!;u!V!;kmY!;bjX!;YdV!<)'Z!;bjX!;u!V!;u!Y
-!<)'X!;kpX!;bjW!<2-Y!;,FRs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jtXSr2#X8r7$r;churW)u"rW)u"q>gPsq>^MsrW)u"rW)u"q>gMrrVuu#!.h5&
-XOXEPmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRgAV'Qg&V-+r;ciNrW)uPrW)uPq>gQLq>^NLrW)uPrW)uPq>gNKrVuuQ!.ijT
-g==pWs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ak5G>]joGDCr;ciZrW)u\rW)u\q>gQXq>^NXrW)u\rW)u\q>gNWrVuu]!.j9`
-k1/Vos8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8"XT&;#X8i8!X8i8"XT&;"X8i8"X9J[+X8o?'!<0&"!<&u%!3E7%!<0&"
-!<0&+!3E7%XK2E'X8r7$rr@VOJZRD's6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-PgA_0Qg&M-Og&M-PgA_0Pg&M-Pg'.Q2g&Tj\!<1[P!<(US!8?-,!<1[P
-!<1[Y!8?-,g=cP\g&V-+rr@W(J_JZ.s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D\k5PG]jo>D[jo>D\k5PG\jo>D\jothJjoFQ+!<2*\!<)$_!9WDD!<2*\
-!<2*e!9WDDk2l[+joGDCrr@W4J`bMFs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!W];%qlC&'XK2E'!3E7%ri?;(XK2E'X8r7$!!)u!#QUs-!3?1%X8r7$
-#lq'.!3E7%XK2F#X8i7uXT&9OXF[J.XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!W^pSqq;;Ug=cP\!8?-,rn7PVg=cP\g&V-+!!)uO#QWT4!87G,g&V-+
-#lr]5!8?-,g=cQ*g&M-NgA_/(g4@u5gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!W_?_qrS.ak2l[+!9WDDroOCbk2l[+joGDC!!)u[#QX#L!9O:DjoGDC
-#ls,M!9WDDk2l[Bjo>DZk5PF4k(2[Mk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3?1%X8r.!!!)nt!s#F(!<&u&!3?1%X8r.!!!)qu!!)bp
[email protected]:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!87G,g&V$(!!)oM!s%'/!<(UT!87G,g&V$(!!)rN!!)cI
-rr@W(J_Jo5s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9O:DjoG;@!!)oY!s%KG!<)$`!9O:DjoG;@!!)rZ!!)cU
-rr@W4J`bbMs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)ntr;cet"TYX*!3?1tX8i7tXSi-MXF[J&
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oMr;cfM"T[91!87GMg&M-MgAM#&g4@u-
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oYr;cfY"T[]I!9O:Yjo>DYk5>:2k(2[E
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)nt!s#F(!<&u&!3E7%X8r.!!!)bp!!%SO
-JZRD's6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oM!s%'/!<(UT!8?-,g&V$(!!)cI!!%T(
-J_JZ.s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oY!s%KG!<)$`!9WDDjoG;@!!)cU!!%T4
-J`bMFs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt!s#F(!<0)"!;iht!;iht!<&u$!3E7%riH,"qlBbtr2]kurN#u!
-JZOF(eZAf=rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V!'!!)oM!s%'/!<1^P!;kIM!;kIM!<(UR!8?-,rn@APqq;#Mr7V,NrRq5O
-J_G\/e_:''rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG8?!!)oY!s%KG!<2-\!;kmY!;kmY!<)$^!9WDDroX4\qrRkYr8mtZrT4([
-J`_OGe`Qo3rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!*#"rrDqt!!)nt!!)u!!s#F(!<0)"!;iht!;rqu
-!<0&"!;rqu!.h5&XPBoWmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!*#PrrDrM!!)oM!!)uO!s%'/!<1^P!;kIM!;tRN
-!<1[P!;tRN!.ijTg>(E^s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!*#\rrDrY!!)oY!!)u[!s%KG!<2-\!;kmY!;u!Z
-!<2*\!;u!Z!.j9`k1o,!s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSi.tXSi.uXSr5!X8i8!XS`(tXSMnsXSr5!X8i8!XS`(tX8r=&rW)hsrr@VO
-JZRY.s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hRgAM$MgAM$NgAV*Og&M-OgACsMgA1dLgAV*Og&M-OgACsMg&V3-rW)iLrr@W(
-J_Jo5s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@ak5>;Yk5>;Zk5GA[jo>D[k555Yk5#&Xk5GA[jo>D[k555YjoGJErW)iXrr@W4
-J`bbMs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jOX8i7EX8i7*XSi.WX8i7JXT&:DX8i7FXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=h-g&M,sg&M,XgAM$0g&M-#gA_/rg&M,tgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@<jo>D*jo>Cdk5>;<jo>D/k5PG)jo>D+k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juXSr4VX8i7EX8i7tX8i7`XSr4bXT&:hX8i7VX8i7YX8i7jX8i7`XT&:_X8i7G
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSgAV*/g&M,sg&M-Mg&M-9gAV*;gA_0Ag&M-/g&M-2g&M-Cg&M-9gA_08g&M,u
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bk5GA;jo>D*jo>DYjo>DEk5GAGk5PGMjo>D;jo>D>jo>DOjo>DEk5PGDjo>D,
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jsX8i6oX8i7^X8i7bX8i7hX8i7VX8i7YX8i7jX8i7_X8i7_X8i7GXT._fec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hQg&M,Hg&M-7g&M-;g&M-Ag&M-/g&M-2g&M-Cg&M-8g&M-8g&M,ugAh3PgAca(
-s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@`jo>CTjo>DCjo>DGjo>DMjo>D;jo>D>jo>DOjo>DDjo>DDjo>D,k5YJ\ec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jtX9&C'!;iks!!0/$riH)!"fq\(X8i8"XT&;!XSr4tXT&;#XT&:uXSr4mXSr5!
-XSr2(X8i7%X8i8!XSr4tXS`(qXSr4iX8i7tXSi.rXSr2#X8r7$!W]='rW)YnqZ-Srr;cetrrE)#
-rrDVk!!)u!rr<8)!!')#!3H/"s/c2"p8n/lr2fhsrN$#"XSr4bX9&C'XSr4uXSr5!XSr5"XSr4u
-X8i7GXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hRg&_9.!;kLL!!1dRrn@>O"kiqVg&M-PgA_0OgAV*MgA_0QgA_0NgAV*FgAV*O
-gAV'Vg&M-,g&M-OgAV*MgACsJgAV*Bg&M-MgAM$KgAV'Qg&V-+!W^s.rW)ZGqZ-TKr;cfMrrE)Q
-rrDWD!!)uOrr<8W!!(^Q!8@DPs4[GPp=fEEr7_)LrRq8PgAV*;g&_9.gAV*NgAV*OgAV*PgAV*N
-g&M,ugAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@ajoPPF!;kpX!!23^roX1["m,dbjo>D\k5PG[k5GAYk5PG]k5PGZk5GARk5GA[
-k5G>bjo>DDjo>D[k5GAYk555Vk5GANjo>DYk5>;Wk5G>]joGDC!W_BFrW)ZSqZ-TWr;cfYrrE)]
-rrDWP!!)u[rr<8c!!)-]!9X7\s5s:\p?)8Qr9!qXrT4+\k5GAGjoPPFk5GAZk5GA[k5GA\k5GAZ
-jo>D,k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jtX9&C'!;rnu!<0)"!<9,#!<0)"!<0&"!<&u!!;iht!;ii$!3?1%X8r7$!!*#"
-!!)\n!!)qu!!*#""TYV(XK2F"X8i7tX8i7rX8i8"X8i7kX8i7uX8i8!X8i8!X8i8"XT&;"X9/I(
-X8qgm!!)nt!!)u!!!)u!"TYV(XK2EnX8i7uXT&8*X8i7%!3E7%rN#u!oW/#mqQ'YsrN#u!riH,"
-ri?)"l`:0gXK2F"X8i8"X8i8"X8i8!X8i7uX8i7GXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hRg&_9.!;tON!<1^P!<:aQ!<1^P!<1[P!<(UO!;kIM!;kIR!87G,g&V-+!!*#P
-!!)]G!!)rN!!*#P"T[6Vg=cQ)g&M-Mg&M-Kg&M-Pg&M-Dg&M-Ng&M-Og&M-Og&M-PgA_0Pg&h?/
-g&U]t!!)oM!!)uO!!)uO"T[6Vg=cPug&M-NgA_-Xg&M-,!8?-,rRq5Oo\'9FqUtoLrRq5Orn@AP
-rn7>Ple2F@g=cQ)g&M-Pg&M-Pg&M-Og&M-Ng&M,ugAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@ajoPPF!;tsZ!<2-\!<;0]!<2-\!<2*\!<)$[!;kmY!;km^!9O:DjoGDC!!*#\
-!!)]S!!)rZ!!*#\"T[Zbk2l[Ajo>DYjo>DWjo>D\jo>DPjo>DZjo>D[jo>D[jo>D\k5PG\joYVG
-joFu7!!)oY!!)u[!!)u["T[Zbk2l[8jo>DZk5PDdjo>DD!9WDDrT4([o]?,RqW7bXrT4([roX4\
-roO1\lfJ9Lk2l[Ajo>D\jo>D\jo>D[jo>DZjo>D,k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8"X8i8"X8i7uX9&C'!;rnu!<0&"!<&u!!;iht!;ikt!;iht!;rnu!;<Ju
-!3E7%XK2F$XT&:qX8i7tX8i7sX8i7uX8i7lX8i8!X8i7tX9/I(X8r1"!!*#"!W];%nZ2]jr2]ku
-qlBbtriH,"n>lTiqlC)(XK2E'X8o?'!<&u!!;*>m!;3Dn!<0&"!;rnu!:6cg!3?1uX8i7uX9/I(
-X8r4#!!)nt!!(?Hs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Pg&M-Pg&M-Ng&_9.!;tON!<1[P!<(UO!;kIM!;kLM!;kIM!;tON!;>+N
-!8?-,g=cQ+gA_0Jg&M-Mg&M-Lg&M-Ng&M-Eg&M-Og&M-Mg&h?/g&V')!!*#P!W^pSn_*sCr7V,N
-qq;#Mrn@APnCdjBqq;>Vg=cP\g&Tj\!<(UO!;+tF!;5%G!<1[P!;tON!:8D@!87GNg&M-Ng&h?/
-g&V**!!)oM!!(@!s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D\jo>D\jo>DZjoPPF!;tsZ!<2*\!<)$[!;kmY!;kpY!;kmY!;tsZ!;>OZ
-!9WDDk2l[Ck5PGVjo>DYjo>DXjo>DZjo>DQjo>D[jo>DYjoYVGjoG>A!!*#\!W_?_n`BfOr8mtZ
-qrRkYroX4\nE']NqrS1bk2l[+joFQ+!<)$[!;,CR!;5IS!<2*\!;tsZ!:8hL!9O:Zjo>DZjoYVG
-joGAB!!)oY!!(@-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXS`(tX8i7sX8i7uX8i8"X8i8!X8i7tX8i7tX8i7sXSMqjX9J[+X8o?'!<0&"
-!;EPp!;iht!;`en!;!8l!<&u!!;ii"!3E7%poOJqn>lTir2]kuqlBbtri?)"m]6Bgr2^)&XK2E'
-X8r7$!s#F(!;!8l!;W_o!<0&"!;rnu!:6fe!;iko!<0&%!3E7%qlBbtcE.'6rmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSgACsMg&M-Lg&M-Ng&M-Pg&M-Og&M-Mg&M-Mg&M-LgA1gCg'.Q2g&Tj\!<1[P
-!;G1I!;kIM!;bFG!;"nE!<(UO!;kIP!8?-,ptG`JnCdjBr7V,Nqq;#Mrn7>Pmb.X@r7V>Tg=cP\
-g&V-+!s%'/!;"nE!;Y@H!<1[P!;tON!:8G>!;kLH!<1[S!8?-,qq;#McJ&<urn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!johL1eVf@bk555Yjo>DXjo>DZjo>D\jo>D[jo>DYjo>DYjo>DXk5#)OjothJjoFQ+!<2*\
-!;GUU!;kmY!;bjS!;#=Q!<)$[!;km\!9WDDpu_SVnE']Nr8mtZqrRkYroO1\mcFKLr8n1`k2l[+
-joGDC!s%KG!;#=Q!;YdT!<2*\!;tsZ!:8kJ!;kpT!<2*_!9WDDqrRkYcK>0,rmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!s#F(!;`bs!;rnu!<0&"!<&u!!;iht!;iht!;`bs!:Qul!3?1%!<&u!
-!;EPp!;iht!;`bs!:?if!<&u!!;ii"!3E7%poFMsX8qdl!!)qu!!)nt!!*#"!!)Gg!!)qu"ota+
-!3E7%ri?2%XK2EnX8i7sX8i8!X8i8"X8i7uX8i7eX9&C'!;rnu!;NVt!3E7%qlBbtcE.'6rmh%$
-s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!s%'/!;bCL!;tON!<1[P!<(UO!;kIM!;kIM!;bCL!:SVE!87G,!<(UO
-!;G1I!;kIM!;bCL!:AJ?!<(UO!;kIP!8?-,pt>cLg&UZs!!)rN!!)oM!!*#P!!)H@!!)rN"p!B2
-!8?-,rn7GSg=cPug&M-Lg&M-Og&M-Pg&M-Ng&M->g&_9.!;tON!;P7M!8?-,qq;#McJ&<urn@C'
-s8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!s%KG!;bgX!;tsZ!<2*\!<)$[!;kmY!;kmY!;bgX!:T%Q!9O:D!<)$[
-!;GUU!;kmY!;bgX!:AnK!<)$[!;km\!9WDDpuVVXjoFr6!!)rZ!!)oY!!*#\!!)HL!!)rZ"p!fJ
-!9WDDroO:_k2l[8jo>DXjo>D[jo>D\jo>DZjo>DJjoPPF!;tsZ!;P[Y!9WDDqrRkYcK>0,rmh%$
-s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!!s#F(!<0)"!<0&"!<0)"!;iht!;iht!;W\r!<&u!!;3Gn
-!!95%!<&u!!;EPp!;iht!<0&"!<&u!!<&u!!;!8l!;rnu!<&u!!<&u!!<&u!!<0&%!3E7%nuMfk
-qlBbtrN#u!rN#u!m]6Bgr2^)&XK2E'X8r4#rrDVk!!*#"!!*#"!!*#"rrE&"rrE&"!!)qurrDVk
-!s#F(!;rnu!<&u!!<'#!!;`bs!7%\Gmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO!s%'/!<1^P!<1[P!<1^P!;kIM!;kIM!;Y=K!<(UO!;5(G
-!!:jS!<(UO!;G1I!;kIM!<1[P!<(UO!<(UO!;"nE!;tON!<(UO!<(UO!<(UO!<1[S!8?-,o%F'D
-qq;#MrRq5OrRq5Omb.X@r7V>Tg=cP\g&V**rrDWD!!*#P!!*#P!!*#PrrE&PrrE&P!!)rNrrDWD
-!s%'/!;tON!<(UO!<(XO!;bCL!7'<us8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[!s%KG!<2-\!<2*\!<2-\!;kmY!;kmY!;YaW!<)$[!;5LS
-!!;9_!<)$[!;GUU!;kmY!<2*\!<)$[!<)$[!;#=Q!;tsZ!<)$[!<)$[!<)$[!<2*_!9WDDo&]oP
-qrRkYrT4([rT4([mcFKLr8n1`k2l[+joGABrrDWP!!*#\!!*#\!!*#\rrE&\rrE&\!!)rZrrDWP
-!s%KG!;tsZ!<)$[!<)'[!;bgX!7'a,s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#r;Zi!r;chur;cetrVuu#!<'"u!!95%!<0(t!<0(u!;`eq!;*Am!!95%!<0(u
-!;ikq!;rqt!;ikr!;*Aj!<'"t!;ikr!<0)"!<9/"!;<Ml!;rqs!<'"t!:[&i!<'"u!!TG(!3?/#
-rN#u!nZ;]ir2fkt#-7e)X8i7%rW)hsrrDYlrrE)#rW)nur;c_r!!)ks!!(<Gs6fm:s+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/r;ZiOr;ciNr;cfMrVuuQ!<(XN!!:jS!<1^M!<1^N!;bFJ!;,"F!!:jS!<1^N
-!;kLJ!;tRM!;kLK!;,"C!<(XM!;kLK!<1^P!<:dP!;>.E!;tRL!<(XM!:\\B!<(XN!!V'V!87DQ
-rRq5On_3sBr7_,M#20%Wg&M-,rW)iLrrDZErrE)QrW)oNr;c`K!!)lL!!(<us8W)Ps+14Mp=fOt
-s8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@Jr;Zi[r;ciZr;cfYrVuu]!<)'Z!!;9_!<2-Y!<2-Z!;bjV!;,FR!!;9_!<2-Z
-!;kpV!;u!Y!;kpW!;,FO!<)'Y!;kpW!<2-\!<;3\!;>RQ!;u!X!<)'Y!:]+N!<)'Z!!VKb!9O7]
-rT4([n`KfNr9!tY#3Gmcjo>DDrW)iXrrDZQrrE)]rW)oZr;c`W!!)lX!!(=,s8W)Ks+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8j_X8i6OXN.CB!:d,j!7n7O!8adW!;W\r!7%\Gmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=h=g&M,(g;hnI!:ebC!7om(!8cE0!;Y=K!7'<us8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@Ljo>C4k/ZTa!:f1O!7p<4!8ci<!;YaW!7'a,s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8j_X8i6OXN%=A!:m2k!7n4O!8X^V!;`bs!6qVFmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=h=g&M,(g;_hH!:nhD!7oj(!8Z?/!;bCL!6s6ts8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@Ljo>C4k/QN`!:o7P!7p94!8Zc;!;bgX!6s[+s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jaXSi-MXLYG2!<'"o!5Yc8!62,?mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=h?gAM#&g:>r9!<(XH!5[Cf!63ams8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Nk5>:2k.0XQ!<)'T!5[gr!641$s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7CsDrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7CmBrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7CsDrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec17%s7:mCrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc^(s7:gArs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec17%s7:mCrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec19m^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc`p_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19m^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec19krs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc`nrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19krs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec17%^%D=2KE(u%V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc^(_Y!j7JcGc(U&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec17%^%D=2KE(u%V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I5XT._fec17'^&S--ec17.^&S,_V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc^*_Z0Z2gAc^1_Z0YiU&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec17'^&S--ec17.^&S,_V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%^&S-.ec17.^&S,_V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(_Z0Z3gAc^1_Z0YiU&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%^&S-.ec17.^&S,_V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%^&S-/ec1:%^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(_Z0Z4gAca(_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%^&S-/ec1:%^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:$^&S-0ec1:%^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca'_Z0Z5gAca(_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:$^&S-0ec1:%^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:$^&S-1ec1:$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca'_Z0Z6gAca'_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:$^&S-1ec1:$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:#^&S-2ec1:$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca&_Z0Z7gAca'_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:#^&S-2ec1:$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:#^&S-3ec1:#^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca&_Z0Z8gAca&_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:#^&S-3ec1:#^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:"^&S-4ec1:#^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca%_Z0Z9gAca&_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:"^&S-4ec1:#^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:"^&S*6eUrMP^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca%_Z0W;g4=hQ_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:"^&S*6eUrMP^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:!]`A*3KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca$_>sW8Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:!]`A*3KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec1:!]`S4dKDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca$_?0agJc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:!]`S4dKDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec19u^&N`^^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca#_Z,2a_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19u^&N`^^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMmXaebmf(c:KDN7]KDN:]rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+s+13/s8LaPJbm4`Jbm7`rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:s+13/s8LRKKDN7]KDN:]rs%#Ls5rIW!.Y~>
-!<E0!jo_F0eS9['JaSHarmh%$nG`^CV#TT>]`<Q~>
-!<E0!jo_=2g4=hTJcCZ.rn@C'nG`^HU&X9;\c@6~>
-!<E0!jo_F0eVf"YJcCZ.rmh%$nG`^CV#TT>]`<Q~>
-!<E0!joD3.eUc8)eGt6jrs%#Ls5rIW!.Y~>
-!<E0!joD*+g4@t3g&Q]mrs%2Ns5rIT!.Y~>
-!<E0!joD3.eUc8)eGt6jrs%#Ls5rIW!.Y~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joD*+g4@t/g@<l#U&X9;\c@6~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joD*+g4@t/g@<l#U&X9;\c@6~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joM:.JV/N+LkG$D"f21\k.LbF~>
-!<E0!joM10JUrB'Lk4mG"ektYk.1PC~>
-!<E0!joM:.JV/N+LkG$D"f21\k.LbF~>
-!<E0!joM:.JV/N+M1Yg.ldZ07s5rIW!.Y~>
-!<E0!joM10JUrB'M1G[,le2N9s5rIT!.Y~>
-!<E0!joM:.JV/N+M1Yg.ldZ07s5rIW!.Y~>
-!<E0!jo_F0K7id/!WTias+13OrrTn6s7F#)s6J2=V#TT>]`<Q~>
-!<E0!jo_=2JV!F0!WU#fs+13OrrU(;s7F2.s6JABU&X9;\c@6~>
-!<E0!jo_F0K7id/!WTias+13OrrTn6s7F#)s6J2=V#TT>]`<Q~>
-!<E0!jo_F0K7ij1s8N+P]n-37s/l;%K>%6`p:^M+ldZ07s5rIW!.Y~>
-!<E0!jo_=2JV!L2s8N+N_L_`<s/l;%J\qBcp;6k0le2N9s5rIT!.Y~>
-!<E0!jo_F0K7ij1s8N+P]n-37s/l;%K>%6`p:^M+ldZ07s5rIW!.Y~>
-!<?U-5m#ShKD3(Ys8R]Q^&S+`eUc8Tec17%^&.j)^&S,ueHJ6J5sYJNJ,~>
-!<@-<9ENq!JbR%\s8RWO_Z0Xeg4@t^gAc^(_YaB._Z0Z%g'(/i9M>EdJ,~>
-!<BM*PQKBfKD3(Ys8R]Q^&S+`eUc8Tec17%^&.j)^&S,ueHM2EP`u.JJ,~>
-!!)tU"$tIiKDE4Zrrpr*K>%<bJ^o>%Ygrc+"MOj8e^aWuqRuq/ldZ/)Mdg-]!.Y~>
-!!)t_"&.F"Jbd1]rrq,-J\qHeJ_G\/YhK,."N(3=g=lN*qSN:4le2M9Q#Ue;!.Y~>
-!!)u:"-h>gKDE4Zrrpr*K>%<bJ^o>%Ygrc+"MOj8e^aWuqRuq/ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7j'7rVulIs+:Bds8RZ#J^q!Ts+:Bds8W&JrVuf/s8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!^8rVulNs+(6gs8RZ(J_I?^s+(6gs8W&OrVuf4s8VE="\b2$ED-@_~>
-!<C+<ZicQCK7j'7rVulIs+:Bds8RZ#J^q!Ts+:Bds8W&JrVuf/s8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7j-9rVufGs+:Bds8RZ#J^q!Ts+:Bds8VuHrVul1s8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!d:rVufLs+(6gs8RZ(J_I?^s+(6gs8VuMrVul6s8VE="\b2$ED-@_~>
-!<C+<ZicQCK7j-9rVufGs+:Bds8RZ#J^q!Ts+:Bds8VuHrVul1s8VE8"dI!5[$1Q@~>
-!<A&W@Kf'JK7gkNrVu`Es+:Bds8RZ#J^q!Ts+:Bds8VoFrVlr4s8VE8"[S&U@R1!E~>
-!<ADaE<T%iJUt\TrVu`Js+(6gs8RZ(J_I?^s+(6gs8VoKrVlr9s8VE="\b2$ED-@_~>
-!<C+<Ziu]EK7gkNrVu`Es+:Bds8RZ#J^q!Ts+:Bds8VoFrVlr4s8VE8"dI!5[$1Q@~>
-!<A&W@KAdFqh+[os+:Bds8RZ#J^q!Ts+:Bds8VlErIb.MldZ/)Mdg-]!.Y~>
-!<ADaE</beqgnOrs+(6gs8RZ(J_I?^s+(6gs8VlJrIP"Kle2M9Q#Ue;!.Y~>
-!<C+<ZiQEAqh+[os+:Bds8RZ#J^q!Ts+:Bds8VlErIb.MldZ0'`O*":!.Y~>
-!<A&W@Kf'JK7gkNrIasss+:Bds8RZ#J^q!Ts+:Bds8VoFrIY0bs8VE8"[S&U@R1!E~>
-!<ADaE<T%iJUt\TrIOh!s+(6gs8RZ(J_I?^s+(6gs8VoKrIG$es8VE="\b2$ED-@_~>
-!<C+<Ziu]EK7gkNrIasss+:Bds8RZ#J^q!Ts+:Bds8VoFrIY0bs8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7j-9rIb$us+:Bds8RZ#J^q!Ts+:Bds8VuHrIb*_s8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!d:rIOn#s+(6gs8RZ(J_I?^s+(6gs8VuMrIOsbs8VE="\b2$ED-@_~>
-!<C+<ZicQCK7j-9rIb$us+:Bds8RZ#J^q!Ts+:Bds8VuHrIb*_s8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7j'7rIb+"s+:Bds8RZ#J^q!Ts+:Bds8W&JrIb$]s8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!^8rIOt%s+(6gs8RZ(J_I?^s+(6gs8W&OrIOm`s8VE="\b2$ED-@_~>
-!<C+<ZicQCK7j'7rIb+"s+:Bds8RZ#J^q!Ts+:Bds8W&JrIb$]s8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7j!5rIY:(K7gl;s+/^OeZdU(K*8mfs4,ZuKDN:]s6J2=6&T2]5lcE~>
-!<ADaE<AngJV!X6rIG.+JUt]<s+/mTg9B<2JHWjis4Z3*Jbm7`s6JAB9U0U;9E9S~>
-!<C+<ZicQCK7j!5rIY:(K7gl;s+/^OeZdU(K*8mfs4,ZuKDN:]s6J2=Pf:#:PQ64~>
-!<A&W@KSpHK7ip3r.>'as8RZ#J^q!Ts+:Bds8W%Mpq?_-ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!R4r.+pds8RZ(J_I?^s+(6gs8W%Kpqm(2le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7ip3r.>'as8RZ#J^q!Ts+:Bds8W%Mpq?_-ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7ij1rdt9cs8RY&JV1+X"MOj8K7im2s8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!L2rdb-fs8RY$JUstT"N(3=JV!O3s8VE="\b2$ED-@_~>
-!<C+<ZicQCK7ij1rdt9cs8RY&JV1+X"MOj8K7im2s8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7id/!e\2dJV/N+Xb-\gs+BsWs8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!F0!eJ5gJUrB'XapPjs+0gZs8VE="\b2$ED-@_~>
-!<C+<ZicQCK7id/!e\2dJV/N+Xb-\gs+BsWs8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7eaTJcCW-ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJUrCPJcCW-le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7eaTJcCW-ldZ0'`O*":!.Y~>
-!<A&W@KJjGK7X&Rs,$dAeHJ6s@U_V'J,~>
-!<ADaE<8hfJV!iPs,$dAg'(08EH+YPJ,~>
-!<C+<ZiZKBK7X&Rs,$dAeHM2V['Z%tJ,~>
-!<A&W@K8]FeUc8%ea_/n6&T2]5lcE~>
-!<ADaE<&[`g4@t/g@<l#9U0U;9E9S~>
-!<C+<ZiH>AeUc8%ea_/nPf:#:PQ64~>
-!<A&V@dua8Uk,>(U]=lp5lciB@KAapJ,~>
-!<AD`EUc_RTn/o"T`B*'9E:@WE</`5J,~>
-!<C+;[.0B3Uk,>(U]@dmPQ8]%ZiQBkJ,~>
-!\j\5rF5AV!+LNZJcCl4nVdBU!^Qh:J,~>
-!^m$RrGhFo!-*SiJcCl4nWj)n!_`UJJ,~>
-!cn@\rNu18!47=WJcCl4n\tL7!gE]8J,~>
-!]^7=mpZ8_J`_OGOlcY%mpZ>a!7cT~>
-!^m$Rmr8>$J`_OGOlcY/mr8D&!8;r~>
-!cn@\n$E(ZJ`_OGOlcY_n$E.\!7cT~>
-">Mn:5sb$M!'u1uJ``*W!/pAVs$6\de^]0~>
-s$Qng9MFtr!).t+J``*W!1!(os%EIog=h&~>
-s)S5APa(^F!0i&sJ``*W!6+K8s-*Qbe^]0~>
-r]0uYn3MW=J\@2Z!+PIarrE&KJ,~>
-r^?bdn4\DEJ\$uT!-.O&rrE&PJ,~>
-rcA)>n<AL;J\@2Z!4;9\rrE&KJ,~>
-">Mnk3B;WjJH16$mf3C=s8LQ!~>
-r'Z)9JH16$mf3CB!<1]&~>
-"DW!mF)um4JH16$mf3C=!<1N!~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/user_guide.gif b/lib/et/doc/src/user_guide.gif
deleted file mode 100644
index e6275a803d..0000000000
--- a/lib/et/doc/src/user_guide.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/warning.gif b/lib/et/doc/src/warning.gif
deleted file mode 100644
index 96af52360e..0000000000
--- a/lib/et/doc/src/warning.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/examples/Makefile b/lib/et/examples/Makefile
index 553fe55f3b..67a6536fdf 100644
--- a/lib/et/examples/Makefile
+++ b/lib/et/examples/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -38,7 +38,9 @@ RELSYSDIR = $(RELEASE_PATH)/lib/et-$(VSN)
MODULES = \
- et_demo
+ et_demo \
+ et_display_demo \
+ et_trace_demo
ERL_FILES= $(MODULES:=.erl)
diff --git a/lib/et/examples/et_demo.erl b/lib/et/examples/et_demo.erl
index 57e7e77246..e439e6882c 100644
--- a/lib/et/examples/et_demo.erl
+++ b/lib/et/examples/et_demo.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
@@ -23,24 +23,29 @@
-module(et_demo).
-export([
- sim_trans/0,
+ sim_trans/0, sim_trans/1,
+ live_trans/0, live_trans/1,
mgr_actors/1,
- live_trans/0,
- start/0,
- start/1,
+ start/0, start/1,
filters/0,
trace_mnesia/0
]).
+%% Test
+-export([s/0, t/0, t/1, init/0, gen/3]).
+
-include_lib("et/include/et.hrl").
%%----------------------------------------------------------------------
%sim_trans
sim_trans() ->
+ sim_trans([]).
+
+sim_trans(ExtraOptions) ->
Options = [{dict_insert, {filter, mgr_actors}, fun mgr_actors/1}],
- {ok, Viewer} = et_viewer:start_link(Options),
- Collector = et_viewer:get_collector_pid(Viewer),
+ {ok, Viewer} = et_viewer:start_link(Options ++ ExtraOptions),
+ Collector = et_viewer:get_collector_pid(Viewer),
et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer,
"Start outer transaction"),
et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid,
@@ -56,11 +61,13 @@ sim_trans() ->
et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction,
"End of outer transaction"),
et_collector:report_event(Collector, 20, my_shell, end_outer,
- "Transaction returned {atomic, ok}").
+ "Transaction returned {atomic, ok}"),
+ {collector, Collector}.
+
%sim_trans
%mgr_actors
-mgr_actors(E) when record(E, event) ->
+mgr_actors(E) when is_record(E, event) ->
Actor = fun(A) ->
case A of
mnesia_tm -> trans_mgr;
@@ -94,9 +101,13 @@ start(ExtraOptions) ->
%live_trans
live_trans() ->
- et_demo:start([{title, "Mnesia tracer"},
- {hide_actions, true},
- {active_filter, named_process_info_nolink}]),
+ live_trans([]).
+
+live_trans(ExtraOptions) ->
+ Options = [{title, "Mnesia tracer"},
+ {hide_actions, true},
+ {active_filter, named_process_info_nolink}],
+ et_demo:start(Options ++ ExtraOptions),
mnesia:start(),
mnesia:create_table(my_tab, [{ram_copies, [node()]}]),
et_demo:trace_mnesia(),
@@ -146,7 +157,7 @@ filters() ->
%filters
%module_as_actor
-module_as_actor(E) when record(E, event) ->
+module_as_actor(E) when is_record(E, event) ->
case lists:keysearch(mfa, 1, E#event.contents) of
{value, {mfa, {M, F, _A}}} ->
case lists:keysearch(pam_result, 1, E#event.contents) of
@@ -163,7 +174,7 @@ module_as_actor(E) when record(E, event) ->
%%----------------------------------------------------------------------
%plain_process_info
-plain_process_info(E) when record(E, event) ->
+plain_process_info(E) when is_record(E, event) ->
case E#event.label of
send -> true;
send_to_non_existing_process -> true;
@@ -182,7 +193,7 @@ plain_process_info(E) when record(E, event) ->
%plain_process_info
%plain_process_info_nolink
-plain_process_info_nolink(E) when record(E, event) ->
+plain_process_info_nolink(E) when is_record(E, event) ->
(E#event.label /= link) and
(E#event.label /= unlink) and
(E#event.label /= getting_linked) and
@@ -191,7 +202,7 @@ plain_process_info_nolink(E) when record(E, event) ->
%%----------------------------------------------------------------------
-named_process_info(E) when record(E, event) ->
+named_process_info(E) when is_record(E, event) ->
case plain_process_info(E) of
true ->
{true, E#event{to = pid_to_name(E#event.to),
@@ -201,7 +212,7 @@ named_process_info(E) when record(E, event) ->
false
end.
-named_process_info_nolink(E) when record(E, event) ->
+named_process_info_nolink(E) when is_record(E, event) ->
case plain_process_info_nolink(E) of
true ->
{true, E#event{to = pid_to_name(E#event.to),
@@ -211,7 +222,7 @@ named_process_info_nolink(E) when record(E, event) ->
false
end.
-pid_to_name(Pid) when pid(Pid) ->
+pid_to_name(Pid) when is_pid(Pid) ->
case process_info(Pid, registered_name) of
{registered_name, Name} ->
Name;
@@ -225,7 +236,7 @@ pid_to_name(Other) ->
%%----------------------------------------------------------------------
-node_process_info(E) when record(E, event) ->
+node_process_info(E) when is_record(E, event) ->
case plain_process_info(E) of
true ->
{true, E#event{to = pid_to_node(E#event.to),
@@ -234,7 +245,7 @@ node_process_info(E) when record(E, event) ->
false ->
false
end.
-node_process_info_nolink(E) when record(E, event) ->
+node_process_info_nolink(E) when is_record(E, event) ->
case plain_process_info_nolink(E) of
true ->
{true, E#event{to = pid_to_node(E#event.to),
@@ -244,21 +255,21 @@ node_process_info_nolink(E) when record(E, event) ->
false
end.
-pid_to_node(Pid) when pid(Pid) ->
+pid_to_node(Pid) when is_pid(Pid) ->
node(Pid);
-pid_to_node(Name) when atom(Name) ->
+pid_to_node(Name) when is_atom(Name) ->
node();
-pid_to_node({_Name, Node}) when atom(Node) ->
+pid_to_node({_Name, Node}) when is_atom(Node) ->
Node.
%%----------------------------------------------------------------------
-application_as_actor(E) when record(E, event) ->
+application_as_actor(E) when is_record(E, event) ->
{true, E#event{to = pid_to_application(E#event.to),
from = pid_to_application(E#event.from),
label = msg_to_label(E)}}.
-pid_to_application(Pid) when pid(Pid) ->
+pid_to_application(Pid) when is_pid(Pid) ->
case application:get_application(Pid) of
{ok, Name} ->
Name;
@@ -268,7 +279,7 @@ pid_to_application(Pid) when pid(Pid) ->
%%----------------------------------------------------------------------
-msg_to_label(E) when record(E, event) ->
+msg_to_label(E) when is_record(E, event) ->
case lists:keysearch(msg, 1, E#event.contents) of
{value, {msg, Msg}} ->
mnesia_msg_to_label(Msg, E#event.label);
@@ -349,3 +360,35 @@ mnesia_msg_to_label(Msg, Label) ->
_ -> Label
end.
+%%----------------------------------------------------------------------
+
+s() ->
+ spawn(fun() -> t(), timer:sleep(infinity) end).
+
+t() ->
+ t(500).
+
+t(N) ->
+ Collector = init(),
+ gen(Collector, 1, N),
+ Collector.
+
+init() ->
+ EvenFilter =
+ fun(#event{label = Label}) ->
+ case catch (list_to_integer(Label) div 10) rem 2 of
+ 0 ->
+ false;
+ _ ->
+ true
+ end
+ end,
+ OddFilter = fun(E) -> not EvenFilter(E) end,
+ {ok, Viewer} = et_viewer:start_link([{dict_insert, {filter, odd_tens}, EvenFilter},
+ {dict_insert, {filter, even_tens}, OddFilter},
+ {active_filter, odd_tens}]),
+ et_viewer:get_collector_pid(Viewer).
+
+gen(Collector, From, To) ->
+ [et_collector:report_event(Collector, 20, from, to, integer_to_list(I), [I]) || I <- lists:seq(From, To)],
+ ok.
diff --git a/lib/et/examples/et_display_demo.erl b/lib/et/examples/et_display_demo.erl
new file mode 100644
index 0000000000..ebcbc2e816
--- /dev/null
+++ b/lib/et/examples/et_display_demo.erl
@@ -0,0 +1,32 @@
+%%
+%% %CopyrightBegin%
+%% %CopyrightEnd%
+%%
+
+%module
+-module(et_display_demo).
+
+-export([test/0]).
+
+test() ->
+ {ok, Viewer} = et_viewer:start([{title,"Coffee Order"}, {max_actors,10}]),
+ Drink = {drink,iced_chai_latte},
+ Size = {size,grande},
+ Milk = {milk,whole},
+ Flavor = {flavor,vanilla},
+ C = et_viewer:get_collector_pid(Viewer),
+ et_collector:report_event(C,99,customer,barrista1,place_order,[Drink,Size,Milk,Flavor]),
+ et_collector:report_event(C,80,barrista1,register,enter_order,[Drink,Size,Flavor]),
+ et_collector:report_event(C,80,register,barrista1,give_total,"$5"),
+ et_collector:report_event(C,80,barrista1,barrista1,get_cup,[Drink,Size]),
+ et_collector:report_event(C,80,barrista1,barrista2,give_cup,[]),
+ et_collector:report_event(C,90,barrista1,customer,request_money,"$5"),
+ et_collector:report_event(C,90,customer,barrista1,pay_money,"$5"),
+ et_collector:report_event(C,80,barrista2,barrista2,get_chai_mix,[]),
+ et_collector:report_event(C,80,barrista2,barrista2,add_flavor,[Flavor]),
+ et_collector:report_event(C,80,barrista2,barrista2,add_milk,[Milk]),
+ et_collector:report_event(C,80,barrista2,barrista2,add_ice,[]),
+ et_collector:report_event(C,80,barrista2,barrista2,swirl,[]),
+ et_collector:report_event(C,80,barrista2,customer,give_tasty_beverage,[Drink,Size]),
+ ok.
+%module
diff --git a/lib/et/examples/et_trace_demo.erl b/lib/et/examples/et_trace_demo.erl
new file mode 100644
index 0000000000..5c16d4b77c
--- /dev/null
+++ b/lib/et/examples/et_trace_demo.erl
@@ -0,0 +1,38 @@
+%%
+%% %CopyrightBegin%
+%% %CopyrightEnd%
+%%
+
+%module
+-module(et_trace_demo).
+
+-export([test/0]).
+
+test() ->
+ et_viewer:start([
+ {title,"Coffee Order"},
+ {trace_global,true},
+ {trace_pattern,{et,max}},
+ {max_actors,10}
+ ]),
+ %% dbg:p(all,call),
+ %% dbg:tpl(et, trace_me, 5, []),
+ Drink = {drink,iced_chai_latte},
+ Size = {size,grande},
+ Milk = {milk,whole},
+ Flavor = {flavor,vanilla},
+ et:trace_me(99,customer,barrista1,place_order,[Drink,Size,Milk,Flavor]),
+ et:trace_me(80,barrista1,register,enter_order,[Drink,Size,Flavor]),
+ et:trace_me(80,register,barrista1,give_total,"$5"),
+ et:trace_me(80,barrista1,barrista1,get_cup,[Drink,Size]),
+ et:trace_me(80,barrista1,barrista2,give_cup,[]),
+ et:trace_me(90,barrista1,customer,request_money,"$5"),
+ et:trace_me(90,customer,barrista1,pay_money,"$5"),
+ et:trace_me(80,barrista2,barrista2,get_chai_mix,[]),
+ et:trace_me(80,barrista2,barrista2,add_flavor,[Flavor]),
+ et:trace_me(80,barrista2,barrista2,add_milk,[Milk]),
+ et:trace_me(80,barrista2,barrista2,add_ice,[]),
+ et:trace_me(80,barrista2,barrista2,swirl,[]),
+ et:trace_me(80,barrista2,customer,give_tasty_beverage,[Drink,Size]),
+ ok.
+%module
diff --git a/lib/et/src/Makefile b/lib/et/src/Makefile
index c590852625..bb6632ee91 100644
--- a/lib/et/src/Makefile
+++ b/lib/et/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -127,9 +127,16 @@ $(EBIN)/et_selector.$(EMULATOR): et_selector.erl ../include/et.hrl
$(EBIN)/et_contents_viewer.$(EMULATOR): et_contents_viewer.erl ../include/et.hrl et_internal.hrl
+$(EBIN)/et_gs_contents_viewer.$(EMULATOR): et_gs_contents_viewer.erl ../include/et.hrl et_internal.hrl
+$(EBIN)/et_wx_contents_viewer.$(EMULATOR): et_wx_contents_viewer.erl ../include/et.hrl et_internal.hrl
+
$(EBIN)/et_collector.$(EMULATOR): et_collector.erl ../include/et.hrl et_internal.hrl
$(EBIN)/et_viewer.$(EMULATOR): et_viewer.erl ../include/et.hrl et_internal.hrl
+$(EBIN)/et_gs_viewer.$(EMULATOR): et_gs_viewer.erl ../include/et.hrl et_internal.hrl
+
+$(EBIN)/et_wx_viewer.$(EMULATOR): et_wx_viewer.erl ../include/et.hrl et_internal.hrl
+
diff --git a/lib/et/src/et.app.src b/lib/et/src/et.app.src
index 0c7bef7c3d..dc22ce4223 100644
--- a/lib/et/src/et.app.src
+++ b/lib/et/src/et.app.src
@@ -1,20 +1,20 @@
%% This is an -*- erlang -*- file.
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
{application, et,
@@ -25,8 +25,13 @@
et,
et_collector,
et_contents_viewer,
+ et_gs_contents_viewer,
+ et_gs_viewer,
et_selector,
- et_viewer
+ et_viewer,
+ et_viewer,
+ et_wx_contents_viewer,
+ et_wx_viewer
]},
{registered, [et_collector]},
{applications, [stdlib, kernel]},
diff --git a/lib/et/src/et.erl b/lib/et/src/et.erl
index 9c0a7f8f49..e2cd8564c3 100644
--- a/lib/et/src/et.erl
+++ b/lib/et/src/et.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
@@ -84,13 +84,15 @@
-module(et).
-export([
- phone_home/4, report_event/4,
- phone_home/5, report_event/5
+ trace_me/4, phone_home/4, report_event/4,
+ trace_me/5, phone_home/5, report_event/5
]).
%%----------------------------------------------------------------------
%% Reports an event, such as a message
%%
+%% trace_me(DetailLevel, FromTo, Label, Contents) -> hopefully_traced
+%% trace_me(DetailLevel, From, To, Label, Contents) -> hopefully_traced
%% report_event(DetailLevel, FromTo, Label, Contents) -> hopefully_traced
%% report_event(DetailLevel, From, To, Label, Contents) -> hopefully_traced
%% phone_home(DetailLevel, FromTo, Label, Contents) -> hopefully_traced
@@ -123,18 +125,28 @@
%% Other events (termed actions) may be undirected and only have one actor.
%%----------------------------------------------------------------------
+trace_me(DetailLevel, FromTo, Label, Contents)
+ when is_integer(DetailLevel) ->
+ ?MODULE:trace_me(DetailLevel, FromTo, FromTo, Label, Contents).
+
+trace_me(DetailLevel, _From, _To, _Label, _Contents)
+ when is_integer(DetailLevel) ->
+ hopefully_traced.
+
phone_home(DetailLevel, FromTo, Label, Contents) ->
%% N.B External call
- ?MODULE:report_event(DetailLevel, FromTo, FromTo, Label, Contents).
+ ?MODULE:trace_me(DetailLevel, FromTo, FromTo, Label, Contents).
phone_home(DetailLevel, From, To, Label, Contents) ->
%% N.B External call
- ?MODULE:report_event(DetailLevel, From, To, Label, Contents).
+ ?MODULE:trace_me(DetailLevel, From, To, Label, Contents).
report_event(DetailLevel, FromTo, Label, Contents) ->
%% N.B External call
- ?MODULE:report_event(DetailLevel, FromTo, FromTo, Label, Contents).
+ ?MODULE:trace_me(DetailLevel, FromTo, FromTo, Label, Contents).
+
+report_event(DetailLevel, From, To, Label, Contents)
+ when is_integer(DetailLevel) ->
+ %% N.B External call
+ ?MODULE:trace_me(DetailLevel, From, To, Label, Contents).
-report_event(DetailLevel, _From, _To, _Label, _Contents)
- when integer(DetailLevel) ->
- hopefully_traced.
diff --git a/lib/et/src/et_collector.erl b/lib/et/src/et_collector.erl
index ea23c188f7..289537541d 100644
--- a/lib/et/src/et_collector.erl
+++ b/lib/et/src/et_collector.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
@@ -36,6 +36,7 @@
iterate/3,
iterate/5,
+ lookup/2,
start_trace_client/3,
start_trace_port/1,
@@ -45,6 +46,7 @@
get_global_pid/0,
%% get_table_handle/1,
+ get_table_size/1,
change_pattern/2,
make_key/2,
@@ -59,9 +61,12 @@
-export([init/1,terminate/2, code_change/3,
handle_call/3, handle_cast/2, handle_info/2]).
+-include("et_internal.hrl").
-include("../include/et.hrl").
-record(state, {parent_pid,
+ auto_shutdown, % Optionally shutdown when the last subscriber dies
+ event_tab_size,
event_tab,
dict_tab,
event_order,
@@ -102,7 +107,7 @@
%% stored by the collector. By replacing the default collector filter
%% with a customized dito it is possible to allow any trace data as
%% input. The collector filter is a dictionary entry with the
-%% predefined key {filter, collector} and the value is a fun of
+%% predefined key {filter, all} and the value is a fun of
%% arity 1. See et_selector:parse_event/2 for interface details,
%% such as which erlang:trace/1 tuples that are accepted.
%%
@@ -126,7 +131,7 @@
%% option() =
%% {parent_pid, pid()} |
%% {event_order, event_order()} |
-%% {dict_insert, {filter, collector}, collector_fun()} |
+%% {dict_insert, {filter, all}, collector_fun()} |
%% {dict_insert, {filter, event_filter_name()}, event_filter_fun()} |
%% {dict_insert, {subscriber, pid()}, dict_val()} |
%% {dict_insert, dict_key(), dict_val()} |
@@ -159,19 +164,16 @@
start_link(Options) ->
case parse_opt(Options, default_state(), [], []) of
- {ok, S, Dict2, Clients} when S#state.trace_global == false ->
- case gen_server:start_link(?MODULE, [S, Dict2], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
- unlink(Pid),
- start_clients(Pid, Clients);
- {ok,Pid} ->
- start_clients(Pid, Clients);
- {error, Reason} ->
- {error, Reason}
- end;
- {ok, S, Dict2, Clients} when S#state.trace_global == true ->
- case gen_server:start_link({global, ?MODULE}, ?MODULE, [S, Dict2], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
+ {ok, S, Dict2, Clients} ->
+ Res =
+ case S#state.trace_global of
+ false ->
+ gen_server:start_link(?MODULE, [S, Dict2], []);
+ true ->
+ gen_server:start_link({global, ?MODULE}, ?MODULE, [S, Dict2], [])
+ end,
+ case Res of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
unlink(Pid),
start_clients(Pid, Clients);
{ok,Pid} ->
@@ -185,6 +187,7 @@ start_link(Options) ->
default_state() ->
#state{parent_pid = self(),
+ auto_shutdown = false,
event_order = trace_ts,
subscribers = [],
trace_global = false,
@@ -196,28 +199,30 @@ default_state() ->
parse_opt([], S, Dict, Clients) ->
{Mod, Pattern} = et_selector:make_pattern(S#state.trace_pattern),
Fun = fun(E) -> et_selector:parse_event(Mod, E) end,
- Default = {dict_insert, {filter, collector}, Fun},
+ Default = {dict_insert, {filter, ?DEFAULT_FILTER_NAME}, Fun},
{ok, S#state{trace_pattern = {Mod, Pattern}}, [Default | Dict], Clients};
parse_opt([H | T], S, Dict, Clients) ->
case H of
- {parent_pid, Parent} when Parent == undefined ->
+ {parent_pid, Parent} when Parent =:= undefined ->
parse_opt(T, S#state{parent_pid = Parent}, Dict, Clients);
- {parent_pid, Parent} when pid(Parent) ->
+ {parent_pid, Parent} when is_pid(Parent) ->
parse_opt(T, S#state{parent_pid = Parent}, Dict, Clients);
- {event_order, Order} when Order == trace_ts ->
+ {auto_shutdown, Bool} when Bool =:= true; Bool =:= false ->
+ parse_opt(T, S#state{auto_shutdown = Bool}, Dict, Clients);
+ {event_order, Order} when Order =:= trace_ts ->
parse_opt(T, S#state{event_order = Order}, Dict, Clients);
- {event_order, Order} when Order == event_ts ->
+ {event_order, Order} when Order =:= event_ts ->
parse_opt(T, S#state{event_order = Order}, Dict, Clients);
{dict_insert, {filter, Name}, Fun} ->
if
- atom(Name), function(Fun) ->
+ is_atom(Name), is_function(Fun) ->
parse_opt(T, S, Dict ++ [H], Clients);
true ->
{error, {bad_option, H}}
end;
{dict_insert, {subscriber, Pid}, _Val} ->
if
- pid(Pid) ->
+ is_pid(Pid) ->
parse_opt(T, S, Dict ++ [H], Clients);
true ->
{error, {bad_option, H}}
@@ -228,17 +233,17 @@ parse_opt([H | T], S, Dict, Clients) ->
parse_opt(T, S, Dict ++ [H], Clients);
{trace_client, Client = {_, _}} ->
parse_opt(T, S, Dict, Clients ++ [Client]);
- {trace_global, Bool} when Bool == false ->
+ {trace_global, Bool} when Bool =:= false ->
parse_opt(T, S#state{trace_global = Bool}, Dict, Clients);
- {trace_global, Bool} when Bool == true ->
+ {trace_global, Bool} when Bool =:= true ->
parse_opt(T, S#state{trace_global = Bool}, Dict, Clients);
- {trace_pattern, {Mod, _} = Pattern} when atom(Mod) ->
+ {trace_pattern, {Mod, _} = Pattern} when is_atom(Mod) ->
parse_opt(T, S#state{trace_pattern = Pattern}, Dict, Clients);
{trace_pattern, undefined = Pattern} ->
parse_opt(T, S#state{trace_pattern = Pattern}, Dict, Clients);
- {trace_port, Port} when integer(Port) ->
+ {trace_port, Port} when is_integer(Port) ->
parse_opt(T, S#state{trace_port = Port}, Dict, Clients);
- {trace_max_queue, MaxQueue} when integer(MaxQueue) ->
+ {trace_max_queue, MaxQueue} when is_integer(MaxQueue) ->
parse_opt(T, S#state{trace_port = MaxQueue}, Dict, Clients);
Bad ->
{error, {bad_option, Bad}}
@@ -352,19 +357,19 @@ do_load_event_file(Fun, Fd, Cont, Acc, FileName, BadBytes) ->
%% Returns: {ok, Continuation} | exit(Reason)
%%----------------------------------------------------------------------
-report(CollectorPid, TraceOrEvent) when pid(CollectorPid) ->
+report(CollectorPid, TraceOrEvent) when is_pid(CollectorPid) ->
case get_table_handle(CollectorPid) of
- {ok, TH} when record(TH, table_handle) ->
+ {ok, TH} when is_record(TH, table_handle) ->
report(TH, TraceOrEvent);
{error, Reason} ->
exit(Reason)
end;
-report(TH, TraceOrEvent) when record(TH, table_handle) ->
+report(TH, TraceOrEvent) when is_record(TH, table_handle) ->
Fun = TH#table_handle.filter,
case Fun(TraceOrEvent) of
false ->
{ok, TH};
- true when record(TraceOrEvent, event) ->
+ true when is_record(TraceOrEvent, event) ->
Key = make_key(TH, TraceOrEvent),
case catch ets:insert(TH#table_handle.event_tab, {Key, TraceOrEvent}) of
true ->
@@ -373,7 +378,7 @@ report(TH, TraceOrEvent) when record(TH, table_handle) ->
%% Refresh the report handle and try again
report(TH#table_handle.collector_pid, TraceOrEvent)
end;
- {true, Event} when record(Event, event) ->
+ {true, Event} when is_record(Event, event) ->
Key = make_key(TH, Event),
case catch ets:insert(TH#table_handle.event_tab, {Key, Event}) of
true ->
@@ -401,7 +406,7 @@ report(TH, TraceOrEvent) when record(TH, table_handle) ->
report(TH#table_handle.collector_pid, TraceOrEvent)
end
end;
-report(TH, end_of_trace) when record(TH, table_handle) ->
+report(TH, end_of_trace) when is_record(TH, table_handle) ->
{ok, TH};
report(_, Bad) ->
exit({bad_event, Bad}).
@@ -410,7 +415,7 @@ report_event(CollectorPid, DetailLevel, FromTo, Label, Contents) ->
report_event(CollectorPid, DetailLevel, FromTo, FromTo, Label, Contents).
report_event(CollectorPid, DetailLevel, From, To, Label, Contents)
- when integer(DetailLevel), DetailLevel >= 0, DetailLevel =< 100, list(Contents) ->
+ when is_integer(DetailLevel), DetailLevel >= 0, DetailLevel =< 100 ->
TS= erlang:now(),
E = #event{detail_level = DetailLevel,
trace_ts = TS,
@@ -431,32 +436,38 @@ report_event(CollectorPid, DetailLevel, From, To, Label, Contents)
%% Key = record(event_ts) | record(trace_ts)
%%----------------------------------------------------------------------
-make_key(TH, Stuff) when record(TH, table_handle) ->
+make_key(TH, Stuff) when is_record(TH, table_handle) ->
make_key(TH#table_handle.event_order, Stuff);
make_key(trace_ts, Stuff) ->
if
- record(Stuff, event) ->
+ is_record(Stuff, event) ->
#event{trace_ts = R, event_ts = P} = Stuff,
#trace_ts{trace_ts = R, event_ts = P};
- record(Stuff, trace_ts) ->
+ is_record(Stuff, trace_ts) ->
Stuff;
- record(Stuff, event_ts) ->
+ is_record(Stuff, event_ts) ->
#event_ts{trace_ts = R, event_ts = P} = Stuff,
#trace_ts{trace_ts = R, event_ts = P}
end;
make_key(event_ts, Stuff) ->
if
- record(Stuff, event) ->
+ is_record(Stuff, event) ->
#event{trace_ts = R, event_ts = P} = Stuff,
#event_ts{trace_ts = R, event_ts = P};
- record(Stuff, event_ts) ->
+ is_record(Stuff, event_ts) ->
Stuff;
- record(Stuff, trace_ts) ->
+ is_record(Stuff, trace_ts) ->
#trace_ts{trace_ts = R, event_ts = P} = Stuff,
#event_ts{trace_ts = R, event_ts = P}
end.
%%----------------------------------------------------------------------
+%%----------------------------------------------------------------------
+
+get_table_size(CollectorPid) when is_pid(CollectorPid) ->
+ call(CollectorPid, get_table_size).
+
+%%----------------------------------------------------------------------
%% get_table_handle(CollectorPid) -> Handle
%%
%% Return a table handle
@@ -465,7 +476,7 @@ make_key(event_ts, Stuff) ->
%% Handle = record(table_handle)
%%----------------------------------------------------------------------
-get_table_handle(CollectorPid) when pid(CollectorPid) ->
+get_table_handle(CollectorPid) when is_pid(CollectorPid) ->
call(CollectorPid, get_table_handle).
%%----------------------------------------------------------------------
@@ -480,7 +491,7 @@ get_table_handle(CollectorPid) when pid(CollectorPid) ->
get_global_pid() ->
case global:whereis_name(?MODULE) of
- CollectorPid when pid(CollectorPid) ->
+ CollectorPid when is_pid(CollectorPid) ->
CollectorPid;
undefined ->
exit(global_collector_not_started)
@@ -505,7 +516,7 @@ change_pattern(CollectorPid, RawPattern) ->
call(CollectorPid, {change_pattern, Pattern}).
%%----------------------------------------------------------------------
-%% dict_insert(CollectorPid, {filter, collector}, FilterFun) -> ok
+%% dict_insert(CollectorPid, {filter, all}, FilterFun) -> ok
%% dict_insert(CollectorPid, {subscriber, SubscriberPid}, Void) -> ok
%% dict_insert(CollectorPid, Key, Val) -> ok
%%
@@ -532,14 +543,14 @@ change_pattern(CollectorPid, RawPattern) ->
dict_insert(CollectorPid, Key = {filter, Name}, Fun) ->
if
- atom(Name), function(Fun) ->
+ is_atom(Name), is_function(Fun) ->
call(CollectorPid, {dict_insert, Key, Fun});
true ->
exit({badarg, Key})
end;
dict_insert(CollectorPid, Key = {subscriber, Pid}, Val) ->
if
- pid(Pid) ->
+ is_pid(Pid) ->
call(CollectorPid, {dict_insert, Key, Val});
true ->
exit({badarg, Key})
@@ -626,9 +637,9 @@ multicast(CollectorPid, Msg) ->
%% Pid = dbg_trace_client_pid()
%%----------------------------------------------------------------------
-start_trace_client(CollectorPid, Type, FileName) when Type == event_file ->
+start_trace_client(CollectorPid, Type, FileName) when Type =:= event_file ->
load_event_file(CollectorPid, FileName);
-start_trace_client(CollectorPid, Type, FileName) when Type == file ->
+start_trace_client(CollectorPid, Type, FileName) when Type =:= file ->
WaitFor = {make_ref(), end_of_trace},
EventFun = fun(E, {ReplyTo, {ok, TH}}) -> {ReplyTo, report(TH, E)} end,
EndFun = fun({ReplyTo, {ok, _TH}}) -> ReplyTo ! WaitFor, ReplyTo end,
@@ -658,9 +669,9 @@ start_trace_client(CollectorPid, Type, Parameters) ->
{trace_client_pid, Pid}.
trace_spec_wrapper(EventFun, EndFun, EventInitialAcc)
- when function(EventFun), function(EndFun) ->
+ when is_function(EventFun), is_function(EndFun) ->
{fun(Trace, Acc) ->
- case Trace == end_of_trace of
+ case Trace =:= end_of_trace of
true -> EndFun(Acc);
false -> EventFun(Trace, Acc)
end
@@ -702,24 +713,24 @@ iterate(Handle, Prev, Limit) ->
%% Acc = NewAcc = term()
%%----------------------------------------------------------------------
-iterate(_, _, Limit, _, Acc) when Limit == 0 ->
+iterate(_, _, Limit, _, Acc) when Limit =:= 0 ->
Acc;
-iterate(CollectorPid, Prev, Limit, Fun, Acc) when pid(CollectorPid) ->
+iterate(CollectorPid, Prev, Limit, Fun, Acc) when is_pid(CollectorPid) ->
case get_table_handle(CollectorPid) of
- {ok, TH} when record(TH, table_handle) ->
+ {ok, TH} when is_record(TH, table_handle) ->
iterate(TH, Prev, Limit, Fun, Acc);
{error, Reason} ->
exit(Reason)
end;
-iterate(TH, Prev, Limit, Fun, Acc) when record(TH, table_handle) ->
+iterate(TH, Prev, Limit, Fun, Acc) when is_record(TH, table_handle) ->
if
- Limit == infinity ->
+ Limit =:= infinity ->
next_iterate(TH, Prev, Limit, Fun, Acc);
- integer(Limit), Limit > 0 ->
+ is_integer(Limit), Limit > 0 ->
next_iterate(TH, Prev, Limit, Fun, Acc);
- Limit == '-infinity' ->
+ Limit =:= '-infinity' ->
prev_iterate(TH, Prev, Limit, Fun, Acc);
- integer(Limit), Limit < 0 ->
+ is_integer(Limit), Limit < 0 ->
prev_iterate(TH, Prev, Limit, Fun, Acc)
end.
@@ -793,7 +804,7 @@ prev_iterate(TH, Prev, Limit, Fun, Acc) ->
lookup_and_apply(TH, Prev, Next, Limit, 1, Fun, Acc)
end.
-lookup_and_apply(TH, _Prev, Next, Limit, Incr, Fun, _Acc) when Fun == undefined ->
+lookup_and_apply(TH, _Prev, Next, Limit, Incr, Fun, _Acc) when Fun =:= undefined ->
Limit2 = incr(Limit, Incr),
iterate(TH, Next, Limit2, Fun, Next);
lookup_and_apply(TH, Prev, Next, Limit, Incr, Fun, Acc) ->
@@ -801,17 +812,33 @@ lookup_and_apply(TH, Prev, Next, Limit, Incr, Fun, Acc) ->
case catch ets:lookup_element(Tab, Next, 2) of
{'EXIT', _} ->
iterate(TH#table_handle.collector_pid, Prev, Limit, Fun, Acc);
- E when record(E, event) ->
+ E when is_record(E, event) ->
Acc2 = Fun(E, Acc),
Limit2 = incr(Limit, Incr),
iterate(TH, Next, Limit2, Fun, Acc2)
end.
+lookup(CollectorPid, Key) when is_pid(CollectorPid) ->
+ case get_table_handle(CollectorPid) of
+ {ok, TH} when is_record(TH, table_handle) ->
+ lookup(TH, Key);
+ {error, Reason} ->
+ {error, Reason}
+ end;
+lookup(TH, Key) when is_record(TH, table_handle) ->
+ Tab = TH#table_handle.event_tab,
+ case catch ets:lookup_element(Tab, Key, 2) of
+ {'EXIT', _} ->
+ {error, enoent};
+ E when is_record(E, event) ->
+ {ok, E}
+ end.
+
incr(Val, Incr) ->
if
- Val == infinity -> Val;
- Val == '-infinity' -> Val;
- integer(Val) -> Val + Incr
+ Val =:= infinity -> Val;
+ Val =:= '-infinity' -> Val;
+ is_integer(Val) -> Val + Incr
end.
%%----------------------------------------------------------------------
@@ -824,13 +851,18 @@ incr(Val, Incr) ->
%% table_handle() = record(table_handle)
%%----------------------------------------------------------------------
-clear_table(CollectorPid) when pid(CollectorPid) ->
+clear_table(CollectorPid) when is_pid(CollectorPid) ->
call(CollectorPid, clear_table);
-clear_table(TH) when record(TH, table_handle) ->
+clear_table(TH) when is_record(TH, table_handle) ->
clear_table(TH#table_handle.collector_pid).
call(CollectorPid, Request) ->
- gen_server:call(CollectorPid, Request, infinity).
+ try
+ gen_server:call(CollectorPid, Request, infinity)
+ catch
+ exit:{noproc,_} ->
+ {error, no_collector}
+ end.
%%%----------------------------------------------------------------------
%%% Callback functions from gen_server
@@ -849,7 +881,7 @@ init([InitialS, Dict]) ->
case InitialS#state.parent_pid of
undefined ->
ignore;
- Pid when pid(Pid) ->
+ Pid when is_pid(Pid) ->
link(Pid)
end,
Funs = [fun init_tables/1,
@@ -860,7 +892,7 @@ init([InitialS, Dict]) ->
init_tables(S) ->
EventTab = ets:new(et_events, [ordered_set, {keypos, 1}, public]),
DictTab = ets:new(et_dict, [ordered_set, {keypos, 1}, public]),
- S#state{event_tab = EventTab, dict_tab = DictTab}.
+ S#state{event_tab = EventTab, dict_tab = DictTab, event_tab_size = 0}.
init_global(S) ->
case S#state.trace_global of
@@ -889,44 +921,53 @@ init_global(S) ->
handle_call({multicast, Msg}, _From, S) ->
do_multicast(S#state.subscribers, Msg),
- {reply, ok, S};
+ reply(ok, S);
handle_call(Msg = {dict_insert, _Key, _Val}, _From, S) ->
S2 = do_dict_insert(Msg, S),
- {reply, ok, S2};
+ reply(ok, S2);
handle_call(Msg = {dict_delete, _Key}, _From, S) ->
- S2 = do_dict_delete(Msg, S),
- {reply, ok, S2};
-
+ try
+ S2 = do_dict_delete(Msg, S),
+ reply(ok, S2)
+ catch
+ throw:{stop, R} ->
+ opt_unlink(S#state.parent_pid),
+ {stop, R, S}
+ end;
handle_call({dict_lookup, Key}, _From, S) ->
Reply = ets:lookup(S#state.dict_tab, Key),
- {reply, Reply, S};
+ reply(Reply, S);
handle_call({dict_match, Pattern}, _From, S) ->
case catch ets:match_object(S#state.dict_tab, Pattern) of
{'EXIT', _Reason} ->
- {reply, [], S};
+ reply([], S);
Matching ->
- {reply, Matching, S}
+ reply(Matching, S)
end;
handle_call(get_table_handle, _From, S) ->
- [{_, TableFilter}] = ets:lookup(S#state.dict_tab, {filter, collector}),
+ [{_, TableFilter}] = ets:lookup(S#state.dict_tab, {filter, ?DEFAULT_FILTER_NAME}),
TH = #table_handle{collector_pid = self(),
event_tab = S#state.event_tab,
event_order = S#state.event_order,
filter = TableFilter},
- {reply, {ok, TH}, S};
+ reply({ok, TH}, S);
+
+handle_call(get_table_size, _From, S) ->
+ Size = ets:info(S#state.event_tab, size),
+ reply({ok, Size}, S);
handle_call(close, _From, S) ->
case S#state.file of
undefined ->
- {reply, {error, file_not_open}, S};
+ reply({error, file_not_open}, S);
F ->
Reply = disk_log:close(F#file.desc),
S2 = S#state{file = undefined},
- {reply, Reply, S2}
+ reply(Reply, S2)
end;
handle_call({save_event_file, FileName, Options}, _From, S) ->
Default = #file{name = FileName,
@@ -934,7 +975,7 @@ handle_call({save_event_file, FileName, Options}, _From, S) ->
file_opt = write,
table_opt = keep},
case parse_file_options(Default, Options) of
- {ok, F} when record(F, file) ->
+ {ok, F} when is_record(F, file) ->
case file_open(F) of
{ok, Fd} ->
F2 = F#file{desc = Fd},
@@ -966,16 +1007,16 @@ handle_call({save_event_file, FileName, Options}, _From, S) ->
end,
case F2#file.table_opt of
keep ->
- {reply, Reply2, S3};
+ reply(Reply2, S3);
clear ->
S4 = do_clear_table(S3),
- {reply, Reply2, S4}
+ reply(Reply2, S4)
end;
{error, Reason} ->
- {reply, {error, {file_open, Reason}}, S}
+ reply({error, {file_open, Reason}}, S)
end;
{error, Reason} ->
- {reply, {error, Reason}, S}
+ reply({error, Reason}, S)
end;
handle_call({change_pattern, Pattern}, _From, S) ->
@@ -983,11 +1024,11 @@ handle_call({change_pattern, Pattern}, _From, S) ->
rpc:multicall(Ns, et_selector, change_pattern, [Pattern]),
Reply = {old_pattern, S#state.trace_pattern},
S2 = S#state{trace_pattern = Pattern},
- {reply, Reply, S2};
+ reply(Reply, S2);
handle_call(clear_table, _From, S) ->
S2 = do_clear_table(S),
- {reply, ok, S2};
+ reply(ok, S2);
handle_call(stop, _From, S) ->
do_multicast(S#state.subscribers, close),
@@ -999,7 +1040,7 @@ handle_call(stop, _From, S) ->
handle_call(Request, From, S) ->
ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
[?MODULE, self(), Request, From, S]),
- {reply, {error, {bad_request, Request}}, S}.
+ reply({error, {bad_request, Request}}, S).
%%----------------------------------------------------------------------
%% Func: handle_cast/2
@@ -1011,7 +1052,7 @@ handle_call(Request, From, S) ->
handle_cast(Msg, S) ->
ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
[?MODULE, self(), Msg, S]),
- {noreply, S}.
+ noreply(S).
%%----------------------------------------------------------------------
%% Func: handle_info/2
@@ -1020,54 +1061,67 @@ handle_cast(Msg, S) ->
%% {stop, Reason, State} (terminate/2 is called)
%%----------------------------------------------------------------------
+handle_info(timeout, S) ->
+ S2 = check_size(S),
+ noreply(S2);
handle_info({nodeup, Node}, S) ->
Port = S#state.trace_port,
MaxQueue = S#state.trace_max_queue,
case rpc:call(Node, ?MODULE, start_trace_port, [{Port, MaxQueue}]) of
{ok, _} ->
- listen_on_trace_port(Node, Port, S);
- {error, Reason} when Reason == already_started->
+ S2 = listen_on_trace_port(Node, Port, S),
+ noreply(S2);
+ {error, Reason} when Reason =:= already_started->
ok = error_logger:format("~p(~p): producer ignored(~p:~p):~n ~p~n",
[?MODULE, self(), Node, Port, Reason]),
S2 = S#state{trace_port = Port + 1},
- {noreply, S2};
+ noreply(S2);
{badrpc, Reason} ->
ok = error_logger:format("~p(~p): producer ignored(~p:~p):~n ~p~n",
[?MODULE, self(), Node, Port, Reason]),
S2 = S#state{trace_port = Port + 1},
- {noreply, S2};
+ noreply(S2);
{error, Reason} ->
self() ! {nodeup, Node},
ok = error_logger:format("~p(~p): producer retry(~p:~p):~n ~p~n",
[?MODULE, self(), Node, Port, Reason]),
S2 = S#state{trace_port = Port + 1},
- {noreply, S2}
+ noreply(S2)
end;
handle_info({nodedown, Node}, S) ->
- {noreply, S#state{trace_nodes = S#state.trace_nodes -- [Node]}};
+ noreply(S#state{trace_nodes = S#state.trace_nodes -- [Node]});
handle_info({register_trace_client, Pid}, S) ->
link(Pid),
- {noreply, S};
+ noreply(S);
-handle_info({'EXIT', Pid, Reason}, S) when Pid == S#state.parent_pid ->
+handle_info({'EXIT', Pid, Reason}, S) when Pid =:= S#state.parent_pid ->
{stop, Reason, S};
-handle_info(Info = {'EXIT', Pid, _Reason}, S) ->
- OldSubscribers = S#state.subscribers,
+handle_info(Info = {'EXIT', Pid, Reason}, S) ->
+ OldSubscribers = S#state.subscribers,
case lists:member(Pid, OldSubscribers) of
- true ->
- S2 = do_dict_delete({dict_delete, {subscriber, Pid}}, S),
- {noreply, S2};
+ true when Reason =:= shutdown ->
+ try
+ S2 = do_dict_delete({dict_delete, {subscriber, Pid}}, S),
+ noreply(S2)
+ catch
+ throw:{stop, R} ->
+ opt_unlink(S#state.parent_pid),
+ {stop, R, S}
+ end;
+ true ->
+ opt_unlink(S#state.parent_pid),
+ {stop, Reason, S};
false ->
ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
[?MODULE, self(), Info, S]),
- {noreply, S}
+ noreply(S)
end;
handle_info(Info, S) ->
ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
[?MODULE, self(), Info, S]),
- {noreply, S}.
+ noreply(S).
listen_on_trace_port(Node, Port, S) ->
[_Name, Host] = string:tokens(atom_to_list(Node), [$@]),
@@ -1075,20 +1129,17 @@ listen_on_trace_port(Node, Port, S) ->
{trace_client_pid, RemotePid} ->
rpc:call(Node, et_selector, change_pattern, [S#state.trace_pattern]),
link(RemotePid),
- S2 = S#state{trace_nodes = [Node | S#state.trace_nodes],
- trace_port = Port + 1},
- {noreply, S2};
- {'EXIT', Reason} when Reason == already_started->
+ S#state{trace_nodes = [Node | S#state.trace_nodes],
+ trace_port = Port + 1};
+ {'EXIT', Reason} when Reason =:= already_started->
ok = error_logger:format("~p(~p): consumer ignored(~p:~p): ~p~n",
[?MODULE, self(), Node, Port, Reason]),
- S2 = S#state{trace_port = Port + 1},
- {noreply, S2};
+ S#state{trace_port = Port + 1};
{'EXIT', Reason} ->
self() ! {nodeup, Node},
ok = error_logger:format("~p(~p): consumer retry(~p:~p):~n ~p~n",
[?MODULE, self(), Node, Port, Reason]),
- S2 = S#state{trace_port = Port + 1},
- {noreply, S2}
+ S#state{trace_port = Port + 1}
end.
%%----------------------------------------------------------------------
@@ -1120,7 +1171,7 @@ do_clear_table(S) ->
NewTab = ets:new(et_events, [ordered_set, {keypos, 1}, public]),
S#state{event_tab = NewTab}.
-do_dict_insert(Msg = {dict_insert, Key = {subscriber, Pid}, Val}, S) when pid(Pid) ->
+do_dict_insert(Msg = {dict_insert, Key = {subscriber, Pid}, Val}, S) when is_pid(Pid) ->
OldSubscribers = S#state.subscribers,
NewSubscribers =
case lists:member(Pid, OldSubscribers) of
@@ -1133,6 +1184,8 @@ do_dict_insert(Msg = {dict_insert, Key = {subscriber, Pid}, Val}, S) when pid(Pi
[Pid | OldSubscribers]
end,
do_multicast(NewSubscribers, Msg),
+ Size = ets:info(S#state.event_tab, size),
+ do_multicast(NewSubscribers, {more_events, Size}),
ets:insert(S#state.dict_tab, {Key, Val}),
S#state{subscribers = NewSubscribers};
do_dict_insert(Msg = {dict_insert, Key, Val}, S) ->
@@ -1147,11 +1200,18 @@ do_dict_delete(Msg = {dict_delete, Key = {subscriber, Pid}}, S) ->
case lists:member(Pid, OldSubscribers) of
true ->
unlink(Pid),
- S#state{subscribers = OldSubscribers -- [Pid]};
+ S2 = S#state{subscribers = OldSubscribers -- [Pid]},
+ if
+ S2#state.auto_shutdown,
+ S2#state.subscribers =:= [] ->
+ throw({stop, shutdown});
+ true ->
+ S2
+ end;
false ->
S
end;
-do_dict_delete({dict_delete, {filter, collector}}, S) ->
+do_dict_delete({dict_delete, {filter, ?DEFAULT_FILTER_NAME}}, S) ->
S;
do_dict_delete(Msg = {dict_delete, Key}, S) ->
do_multicast(S#state.subscribers, Msg),
@@ -1202,3 +1262,33 @@ do_multicast([Pid | Pids], Msg) ->
do_multicast(Pids, Msg);
do_multicast([], _Msg) ->
ok.
+
+opt_unlink(Pid) ->
+ if
+ Pid =:= undefined ->
+ ignore;
+ true ->
+ unlink(Pid)
+ end.
+
+reply(Reply, #state{subscribers = []} = S) ->
+ {reply, Reply, S};
+reply(Reply, S) ->
+ {reply, Reply, S, 500}.
+
+noreply(#state{subscribers = []} = S) ->
+ {noreply, S};
+noreply(S) ->
+ {noreply, S, 500}.
+
+check_size(S) ->
+ Size = ets:info(S#state.event_tab, size),
+ if
+ Size =:= S#state.event_tab_size ->
+ S;
+ true ->
+ %% Tell the subscribers that more events are available
+ Msg = {more_events, Size},
+ do_multicast(S#state.subscribers, Msg),
+ S#state{event_tab_size = Size}
+ end.
diff --git a/lib/et/src/et_contents_viewer.erl b/lib/et/src/et_gs_contents_viewer.erl
index 29ca93ca64..f6a87bd608 100644
--- a/lib/et/src/et_contents_viewer.erl
+++ b/lib/et/src/et_gs_contents_viewer.erl
@@ -1,26 +1,26 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% Purpose: Displays details of a trace event
%%----------------------------------------------------------------------
--module(et_contents_viewer).
+-module(et_gs_contents_viewer).
-behaviour(gen_server).
@@ -75,7 +75,7 @@ start_link(Options) ->
case parse_opt(Options, default_state()) of
{ok, S} ->
case gen_server:start_link(?MODULE, [S], []) of
- {ok, ContentsPid} when S#state.parent_pid /= self() ->
+ {ok, ContentsPid} when S#state.parent_pid =/= self() ->
unlink(ContentsPid),
{ok, ContentsPid};
Other ->
@@ -88,8 +88,8 @@ start_link(Options) ->
default_state() ->
#state{parent_pid = self(),
viewer_pid = undefined,
- active_filter = collector,
- filters = [#filter{name = collector, function = fun(E) -> E end}],
+ active_filter = ?DEFAULT_FILTER_NAME,
+ filters = [?DEFAULT_FILTER],
width = 600,
height = 300}.
@@ -97,11 +97,11 @@ parse_opt([], S) ->
Name = S#state.active_filter,
Filters = S#state.filters,
if
- S#state.event == undefined ->
+ S#state.event =:= undefined ->
{error, {badarg, no_event}};
- atom(Name) ->
+ is_atom(Name) ->
case lists:keysearch(Name, #filter.name, Filters) of
- {value, F} when record(F, filter) ->
+ {value, F} when is_record(F, filter) ->
{ok, S#state{active_filter = Name}};
false ->
{error, {badarg, {no_such_filter, Name, Filters}}}
@@ -109,27 +109,27 @@ parse_opt([], S) ->
end;
parse_opt([H | T], S) ->
case H of
- {parent_pid, ParentPid} when pid(ParentPid) ->
+ {parent_pid, ParentPid} when is_pid(ParentPid) ->
parse_opt(T, S#state{parent_pid = ParentPid});
- {viewer_pid, ViewerPid} when pid(ViewerPid) ->
+ {viewer_pid, ViewerPid} when is_pid(ViewerPid) ->
parse_opt(T, S#state{viewer_pid = ViewerPid});
{event_order, trace_ts} ->
parse_opt(T, S#state{event_order = trace_ts});
{event_order, event_ts} ->
parse_opt(T, S#state{event_order = event_ts});
- {event, Event} when record(Event, event) ->
+ {event, Event} when is_record(Event, event) ->
parse_opt(T, S#state{event = Event});
- {active_filter, Name} when atom(Name) ->
+ {active_filter, Name} when is_atom(Name) ->
parse_opt(T, S#state{active_filter = Name});
- F when record(F, filter),
- atom(F#filter.name),
- function(F#filter.function) ->
+ F when is_record(F, filter),
+ is_atom(F#filter.name),
+ is_function(F#filter.function) ->
Filters = lists:keydelete(F#filter.name, #filter.name, S#state.filters),
Filters2 = lists:keysort(#filter.name, [F | Filters]),
parse_opt(T, S#state{filters = Filters2});
- {width, Width} when integer(Width), Width > 0 ->
+ {width, Width} when is_integer(Width), Width > 0 ->
parse_opt(T, S#state{width = Width});
- {height, Height} when integer(Height), Height > 0 ->
+ {height, Height} when is_integer(Height), Height > 0 ->
parse_opt(T, S#state{height = Height});
Bad ->
{error, {bad_option, Bad}}
@@ -164,7 +164,7 @@ call(ContentsPid, Request) ->
%% {stop, Reason}
%%----------------------------------------------------------------------
-init([S]) when record(S, state) ->
+init([S]) when is_record(S, state) ->
process_flag(trap_exit, true),
S2 = create_window(S),
{ok, S2}.
@@ -223,11 +223,11 @@ handle_info({gs, Button, click, Data, _Other}, S) ->
FileName = ["et_contents_viewer_", now_to_string(TimeStamp), ".save"],
file:write_file(lists:flatten(FileName), Bin),
{noreply, S};
- _PopupMenuItem when record(Data, filter) ->
+ _PopupMenuItem when is_record(Data, filter) ->
F = Data,
ChildState= S#state{active_filter = F#filter.name},
case gen_server:start_link(?MODULE, [ChildState], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
+ {ok, Pid} when S#state.parent_pid =/= self() ->
unlink(Pid),
{noreply, S};
_ ->
@@ -312,11 +312,11 @@ handle_info({gs, _Obj, keypress, _, [KeySym, _Keycode, _Shift, _Control | _]}, S
{noreply, S};
0 ->
- case lists:keysearch(collector, #filter.name, S#state.filters) of
- {value, F} when record(F, filter) ->
+ case lists:keysearch(?DEFAULT_FILTER_NAME, #filter.name, S#state.filters) of
+ {value, F} when is_record(F, filter) ->
ChildState= S#state{active_filter = F#filter.name},
case gen_server:start_link(?MODULE, [ChildState], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
+ {ok, Pid} when S#state.parent_pid =/= self() ->
unlink(Pid);
_ ->
ignore
@@ -325,12 +325,12 @@ handle_info({gs, _Obj, keypress, _, [KeySym, _Keycode, _Shift, _Control | _]}, S
ignore
end,
{noreply, S};
- Int when integer(Int), Int > 0, Int =< 9 ->
+ Int when is_integer(Int), Int > 0, Int =< 9 ->
case catch lists:nth(Int, S#state.filters) of
- F when record(F, filter) ->
+ F when is_record(F, filter) ->
ChildState= S#state{active_filter = F#filter.name},
case gen_server:start_link(?MODULE, [ChildState], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
+ {ok, Pid} when S#state.parent_pid =/= self() ->
unlink(Pid);
_ ->
ignore
@@ -356,7 +356,7 @@ handle_info({gs, _Obj, configure, [], [W, H | _]}, S) ->
{noreply, S2};
handle_info({'EXIT', Pid, Reason}, S) ->
if
- Pid == S#state.parent_pid ->
+ Pid =:= S#state.parent_pid ->
unlink(Pid),
{stop, Reason, S};
true ->
@@ -428,7 +428,7 @@ create_filter_menu(Bar, Filters) ->
Menu = gs:menu(Button, []),
gs:menuitem(Menu, [{label, {text, "Select Filter"}}, {bg, lightblue}, {enable, false}]),
gs:menuitem(Menu, [{itemtype, separator}]),
- Item = fun(F, N) when F#filter.name == collector->
+ Item = fun(F, N) when F#filter.name =:= ?DEFAULT_FILTER_NAME->
Label = lists:concat([pad_string(F#filter.name, 20), "(0)"]),
gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
N + 1;
@@ -449,9 +449,9 @@ create_hide_menu(Bar, S) ->
From = E#event.from,
To = E#event.to,
if
- S#state.viewer_pid == undefined ->
+ S#state.viewer_pid =:= undefined ->
ignore;
- From == To ->
+ From =:= To ->
gs:menuitem(Menu, [{label, {text, "Hide actor in Viewer "}}, {bg, lightblue}, {enable, false}]),
gs:menuitem(Menu, [{itemtype, separator}]),
gs:menuitem({hide, [From]}, Menu, [{label, {text,"From=To (f|t|b)"}}]),
@@ -483,9 +483,9 @@ create_search_menu(Bar, S) ->
{bg, lightblue}, {enable, false}]),
gs:menuitem(Menu, [{itemtype, separator}]),
if
- S#state.viewer_pid == undefined ->
+ S#state.viewer_pid =:= undefined ->
S;
- From == To ->
+ From =:= To ->
Key = et_collector:make_key(S#state.event_order, E),
ModeS = {search_actors, forward, Key, [From]},
ModeR = {search_actors, reverse, Key, [From]},
@@ -508,7 +508,7 @@ config_editor(Editor, S) ->
case catch FilterFun(Event) of
true ->
do_config_editor(Editor, Event, lightblue, S#state.event_order);
- {true, Event2} when record(Event2, event) ->
+ {true, Event2} when is_record(Event2, event) ->
do_config_editor(Editor, Event2, lightblue, S#state.event_order);
false ->
do_config_editor(Editor, Event, red, S#state.event_order);
@@ -536,7 +536,7 @@ term_to_string(Term) ->
end.
now_to_string({Mega, Sec, Micro} = Now)
- when integer(Mega), integer(Sec), integer(Micro) ->
+ when is_integer(Mega), is_integer(Sec), is_integer(Micro) ->
{{Y, Mo, D}, {H, Mi, S}} = calendar:now_to_universal_time(Now),
lists:concat([Y, "-", Mo, "-", D, " ", H, ".", Mi, ".", S, ".", Micro]);
now_to_string(Other) ->
@@ -548,14 +548,14 @@ event_to_string(Event, TsKey) ->
Deep =
["DETAIL LEVEL: ", term_to_string(Event#event.detail_level),
"\nLABEL: ", term_to_string(Event#event.label),
- case Event#event.from == Event#event.to of
+ case Event#event.from =:= Event#event.to of
true ->
["\nACTOR: ", term_to_string(Event#event.from)];
false ->
["\nFROM: ", term_to_string(Event#event.from),
"\nTO: ", term_to_string(Event#event.to)]
end,
- case ReportedTs == ParsedTs of
+ case ReportedTs =:= ParsedTs of
true ->
["\nPARSED: ", now_to_string(ParsedTs)];
false ->
@@ -571,9 +571,9 @@ event_to_string(Event, TsKey) ->
"\nCONTENTS:\n\n", term_to_string(Event#event.contents)],
lists:flatten(Deep).
-pad_string(Atom, MinLen) when atom(Atom) ->
+pad_string(Atom, MinLen) when is_atom(Atom) ->
pad_string(atom_to_list(Atom), MinLen);
-pad_string(String, MinLen) when integer(MinLen), MinLen >= 0 ->
+pad_string(String, MinLen) when is_integer(MinLen), MinLen >= 0 ->
Len = length(String),
case Len >= MinLen of
true ->
@@ -584,7 +584,7 @@ pad_string(String, MinLen) when integer(MinLen), MinLen >= 0 ->
send_viewer_event(S, Event) ->
case S#state.viewer_pid of
- ViewerPid when pid(ViewerPid) ->
+ ViewerPid when is_pid(ViewerPid) ->
ViewerPid ! {et, Event};
undefined ->
ignore
diff --git a/lib/et/src/et_gs_viewer.erl b/lib/et/src/et_gs_viewer.erl
new file mode 100644
index 0000000000..7235269aff
--- /dev/null
+++ b/lib/et/src/et_gs_viewer.erl
@@ -0,0 +1,1483 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Displays a sequence chart for trace events (messages/actions)
+%%----------------------------------------------------------------------
+
+-module(et_gs_viewer).
+
+-behaviour(gen_server).
+
+%% External exports
+-export([start_link/1]).
+
+%% gen_server callbacks
+-export([init/1, terminate/2, code_change/3,
+ handle_call/3, handle_cast/2, handle_info/2]).
+
+-include("../include/et.hrl").
+-include("et_internal.hrl").
+
+-define(unknown, "UNKNOWN").
+
+-record(state,
+ {parent_pid, % Pid of parent process
+ collector_pid, % Pid of collector process
+ event_order, % Field to be used as primary key
+ trace_pattern, % Collector trace pattern
+ active_filter, % Name of the active filter
+ filters, % List of possible filters
+ selected_actor, % Actor selected by user
+ first_event, % Key of first event (regardless of visibility)
+ last_event, % Key of last event (regardless of visibility)
+ max_events, % Maximum number of shown events
+ events, % Queue containg all event keys (regardless of visibility)
+ max_actors, % Maximum number of shown actors
+ actors, % List of known actors
+ refresh_needed, % Refresh is needed in order to show all actors
+ display_mode, % Display all or only matching actors
+ detail_level, % Show only events with lesser detail level
+ hide_actions, % Hide/show events where to == from actor (bool)
+ hide_unknown, % Hide/show events with unknown actor (bool)
+ is_suspended, % Suspend viewer updates (bool)
+ title, % GUI: Window title
+ win, % GUI: Window object
+ menubar, % GUI: Menu bar object
+ packer, % GUI: Packer object
+ width, % GUI: Window width
+ height, % GUI: Window height
+ scale, % GUI: Scaling factor on canvas
+ font, % GUI: Font to be used on text labels
+ canvas_width, % GUI: Canvas width
+ canvas_height, % GUI: Canvas height
+ canvas, % GUI: Canvas object
+ y_pos}). % GUI: Current y position on canvas
+
+-record(actor, {name, string}).
+
+-define(initial_x, 10).
+-define(incr_x, 60).
+-define(initial_y, 15).
+-define(incr_y, 15).
+-define(detail_level_min, 0).
+-define(detail_level_max, 100).
+
+%%%----------------------------------------------------------------------
+%%% Client side
+%%%----------------------------------------------------------------------
+
+start_link(Options) ->
+ case parse_opt(Options, default_state(), []) of
+ {ok, S, CollectorOpt} ->
+ case S#state.collector_pid of
+ CollectorPid when is_pid(CollectorPid) ->
+ case gen_server:start_link(?MODULE, [S], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid),
+ {ok, Pid};
+ Other ->
+ Other
+ end;
+ undefined ->
+ case et_collector:start_link(CollectorOpt) of
+ {ok, CollectorPid} ->
+ S2 = S#state{collector_pid = CollectorPid},
+ case gen_server:start_link(?MODULE, [S2], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid),
+ {ok, Pid};
+ Other ->
+ Other
+ end;
+ {error, Reason} ->
+ {error, {et_collector, Reason}}
+ end
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+default_state() ->
+ #state{parent_pid = self(),
+ collector_pid = undefined,
+ detail_level = ?detail_level_max,
+ active_filter = ?DEFAULT_FILTER_NAME,
+ filters = [?DEFAULT_FILTER],
+ event_order = trace_ts,
+ is_suspended = false,
+ max_events = 100,
+ first_event = first,
+ last_event = first,
+ events = queue_new(),
+ max_actors = 5,
+ actors = [create_actor(?unknown)],
+ selected_actor = ?unknown,
+ hide_actions = false,
+ hide_unknown = false,
+ refresh_needed = false,
+ display_mode = all,
+ scale = 2,
+ canvas_height = 0,
+ canvas_width = 0,
+ width = 800,
+ height = 600}.
+
+parse_opt([], S, CollectorOpt) ->
+ {ok, S, [{parent_pid, S#state.parent_pid} | CollectorOpt]};
+parse_opt([H | T], S, CollectorOpt) ->
+ case H of
+ {parent_pid, Parent} when Parent =:= undefined ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{parent_pid = Parent}, CollectorOpt2);
+ {parent_pid, Parent} when is_pid(Parent) ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{parent_pid = Parent}, CollectorOpt2);
+ {title, Title} ->
+ parse_opt(T, S#state{title = name_to_string(Title)}, CollectorOpt);
+ {detail_level, Level} when is_integer(Level),
+ Level >= ?detail_level_min,
+ Level =< ?detail_level_max ->
+ parse_opt(T, S#state{detail_level = Level}, CollectorOpt);
+ {detail_level, max} ->
+ parse_opt(T, S#state{detail_level = ?detail_level_max}, CollectorOpt);
+ {detail_level, min} ->
+ parse_opt(T, S#state{detail_level = ?detail_level_min}, CollectorOpt);
+ {is_suspended, true} ->
+ parse_opt(T, S#state{is_suspended = true}, CollectorOpt);
+ {is_suspended, false} ->
+ parse_opt(T, S#state{is_suspended = false}, CollectorOpt);
+ {scale, Scale} when is_integer(Scale), Scale > 0 ->
+ parse_opt(T, S#state{scale = Scale}, CollectorOpt);
+ {width, W} when is_integer(W), W > 0 ->
+ parse_opt(T, S#state{width = W, canvas_width = W}, CollectorOpt);
+ {height, WH} when is_integer(WH), WH > 0 ->
+ parse_opt(T, S#state{height = WH, canvas_height = WH}, CollectorOpt);
+ {collector_pid, Pid} when is_pid(Pid) ->
+ parse_opt(T, S#state{collector_pid = Pid}, CollectorOpt);
+ {collector_pid, undefined} ->
+ parse_opt(T, S#state{collector_pid = undefined}, CollectorOpt);
+ {active_filter, Name} when is_atom(Name) ->
+ parse_opt(T, S#state{active_filter = Name}, CollectorOpt);
+ {event_order, trace_ts} -> %% BUGBUG: Verify event_order with collector
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{event_order = trace_ts}, CollectorOpt2);
+ {event_order, event_ts} -> %% BUGBUG: Verify event_order with collector
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{event_order = event_ts}, CollectorOpt2);
+ {trace_port, _Port} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_max_queue, _Queue} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_pattern, _Pattern} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_global, _Boolean} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_client, _Client} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {dict_insert, {filter, Name}, Fun} ->
+ if
+ is_atom(Name), is_function(Fun) ->
+ F = #filter{name = Name, function = Fun},
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{filters = Filters ++ [F]}, CollectorOpt2);
+ true ->
+ {error, {bad_option, H}}
+ end;
+ {dict_insert, {subscriber, Pid}, _Val} ->
+ if
+ is_pid(Pid) ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ true ->
+ {error, {bad_option, H}}
+ end;
+ {dict_insert, _Key, _Val} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {dict_delete, {filter, Name}} ->
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{filters = Filters}, CollectorOpt2);
+ {dict_delete, _Key} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {max_events, Max} when is_integer(Max), Max > 0->
+ parse_opt(T, S#state{max_events = Max}, CollectorOpt);
+ {max_events, Max} when Max =:= infinity ->
+ parse_opt(T, S#state{max_events = Max}, CollectorOpt);
+ {max_actors, Max} when is_integer(Max), Max >= 0->
+ parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
+ {max_actors, Max} when Max =:= infinity ->
+ parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
+ {actors, ActorNames} when is_list(ActorNames) ->
+ ActorNames2 =
+ case lists:member(?unknown, ActorNames) of
+ false -> [?unknown | ActorNames];
+ true -> ActorNames
+ end,
+ Actors = [create_actor(Name) || Name <- ActorNames2],
+ parse_opt(T, S#state{actors = Actors}, CollectorOpt);
+ {first_event, First} ->
+ parse_opt(T, S#state{first_event = First}, CollectorOpt);
+ {hide_unknown, Bool} when Bool =:= false ->
+ parse_opt(T, S#state{hide_unknown = Bool}, CollectorOpt);
+ {hide_unknown, Bool} when Bool =:= true ->
+ parse_opt(T, S#state{hide_unknown = Bool}, CollectorOpt);
+ {hide_actions, Bool} when Bool =:= false ->
+ parse_opt(T, S#state{hide_actions = Bool}, CollectorOpt);
+ {hide_actions, Bool} when Bool =:= true ->
+ parse_opt(T, S#state{hide_actions = Bool}, CollectorOpt);
+ {display_mode, Mode = all} ->
+ parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
+ {display_mode, Mode = {search_actors, Dir, _Key, Actors}} when is_list(Actors), Dir =:= forward ->
+ parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
+ {display_mode, Mode = {search_actors, Dir, _Key, Actors}} when is_list(Actors), Dir =:= reverse ->
+ parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
+
+ Bad ->
+ {error, {bad_option, Bad}}
+ end;
+parse_opt(BadList, _S, _CollectorOpt) ->
+ {error, {bad_option_list, BadList}}.
+
+do_dict_insert({filter, Name}, Fun, S) when is_atom(Name), is_function(Fun) ->
+ F = #filter{name = Name, function = Fun},
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ Filters2 = lists:keysort(#filter.name, [F | Filters]),
+ gs:destroy(filter_menu),
+ create_filter_menu(S#state.active_filter, Filters2),
+ S#state{filters = Filters2};
+do_dict_insert(_Key, _Val, S) ->
+ %% ok = error_logger:format("~p(~p): handle_info({et, {dict_insert, ~p, ~p}})~n",
+ %% [?MODULE, self(), Key, Val]),
+ S.
+
+do_dict_delete({filter, Name}, S) when is_atom(Name), Name =/= S#state.active_filter ->
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ gs:destroy(filter_menu),
+ create_filter_menu(S#state.active_filter, Filters),
+ S#state{filters = Filters};
+do_dict_delete(_Key, S) ->
+ %% ok = error_logger:format("~p(~p): handle_info({et, {dict_delete, ~p}})~n",
+ %% [?MODULE, self(), Key]),
+ S.
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+
+init([S]) when is_record(S, state) ->
+ process_flag(trap_exit, true),
+ InitialTimeout = 0,
+ case S#state.parent_pid of
+ undefined ->
+ ignore;
+ Pid when is_pid(Pid) ->
+ link(Pid)
+ end,
+ et_collector:dict_insert(S#state.collector_pid,
+ {subscriber, self()},
+ ?MODULE),
+ {ok, create_main_window(S), InitialTimeout}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_call(get_collector_pid, _From, S) ->
+ Reply = S#state.collector_pid,
+ reply(Reply, S);
+handle_call(stop, _From, S) ->
+ gs:destroy(S#state.win),
+ {stop, shutdown, ok, S};
+handle_call(Request, From, S) ->
+ ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
+ [?MODULE, self(), Request, From, S]),
+ Reply = {error, {bad_request, Request}},
+ reply(Reply, S).
+
+%%----------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_cast(Msg, S) ->
+ ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
+ [?MODULE, self(), Msg, S]),
+ noreply(S).
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_info({et, {more_events, _Size}}, S) ->
+ noreply(S);
+handle_info({et, {insert_actors, ActorNames}}, S) when is_list(ActorNames) ->
+ Fun = fun(N, Actors) ->
+ case lists:keymember(N, #actor.name, Actors) of
+ true -> Actors;
+ false -> Actors ++ [create_actor(N)]
+ end
+ end,
+ Actors = lists:foldl(Fun, S#state.actors, ActorNames),
+ S2 = refresh_main_window(S#state{actors = Actors}),
+ noreply(S2);
+handle_info({et, {delete_actors, ActorNames}}, S) when is_list(ActorNames)->
+ Fun = fun(N, Actors) when N =:= ?unknown ->
+ Actors;
+ (N, Actors) ->
+ lists:keydelete(N, #actor.name, Actors)
+ end,
+ New = lists:foldl(Fun, S#state.actors, ActorNames),
+ S2 = refresh_main_window(S#state{actors = New}),
+ noreply(S2);
+handle_info({et, {dict_insert, Key, Val}}, S) ->
+ S2 = do_dict_insert(Key, Val, S),
+ noreply(S2);
+handle_info({et, {dict_delete, Key}}, S) ->
+ S2 = do_dict_delete(Key, S),
+ noreply(S2);
+handle_info({et, first}, S) ->
+ S2 = scroll_first(S),
+ noreply(S2);
+handle_info({et, prev}, S) ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+handle_info({et, next}, S) ->
+ S2 = scroll_next(S),
+ noreply(S2);
+handle_info({et, last}, S) ->
+ S2 = scroll_last(S),
+ noreply(S2);
+handle_info({et, refresh}, S) ->
+ S2 = refresh_main_window(S),
+ noreply(S2);
+handle_info({et, {display_mode, Mode}}, S) ->
+ S2 = change_display_mode(Mode, S),
+ noreply(S2);
+handle_info({et, close}, S) ->
+ gs:destroy(S#state.win),
+ {stop, shutdown, S};
+handle_info({gs, Button, click, Data, Other} = Click, S) ->
+ CollectorPid = S#state.collector_pid,
+ case Button of
+ close ->
+ gs:destroy(S#state.win),
+ {stop, shutdown, S};
+ suspended ->
+ case Other of
+ [_Text, _Group, Bool | _] when Bool =:= true ->
+ S2 = do_suspend(S),
+ noreply(S2);
+ [_Text, _Group, Bool | _] when Bool =:= false ->
+ S2 = do_resume(S),
+ noreply(S2);
+ _ ->
+ click_error(Click, S),
+ noreply(S)
+ end;
+ hide_actions ->
+ case Other of
+ [_Text, _Group, Bool | _] when Bool =:= true ->
+ S2 = refresh_main_window(S#state{hide_actions = Bool}),
+ noreply(S2);
+ [_Text, _Group, Bool | _] when Bool =:= false ->
+ S2 = refresh_main_window(S#state{hide_actions = Bool}),
+ noreply(S2);
+ _ ->
+ click_error(Click, S),
+ noreply(S)
+ end;
+ hide_unknown ->
+ case Other of
+ [_Text, _Group, Bool | _] when Bool =:= true ->
+ S2 = refresh_main_window(S#state{hide_unknown = Bool}),
+ noreply(S2);
+ [_Text, _Group, Bool | _] when Bool =:= false ->
+ S2 = refresh_main_window(S#state{hide_unknown = Bool}),
+ noreply(S2);
+ _ ->
+ click_error(Click, S),
+ noreply(S)
+ end;
+ up ->
+ S2 = scroll_up(S),
+ noreply(S2);
+ down ->
+ S2 = scroll_down(S),
+ noreply(S2);
+ first ->
+ S2 = scroll_first(S),
+ noreply(S2);
+ prev ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ next ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ last ->
+ S2 = scroll_last(S),
+ noreply(S2);
+ refresh ->
+ S2 = refresh_main_window(S),
+ noreply(S2);
+ {display_mode, Mode} ->
+ S2 = change_display_mode(Mode, S),
+ noreply(S2);
+ close_all ->
+ close_all(S);
+ close_all_others ->
+ close_all_others(S);
+ first_all ->
+ et_collector:multicast(CollectorPid, first),
+ noreply(S);
+ prev_all ->
+ et_collector:multicast(CollectorPid, prev),
+ noreply(S);
+ next_all ->
+ et_collector:multicast(CollectorPid, next),
+ noreply(S);
+ last_all ->
+ et_collector:multicast(CollectorPid, last),
+ noreply(S);
+ refresh_all ->
+ et_collector:multicast(CollectorPid, refresh),
+ noreply(S);
+ clear_all ->
+ et_collector:clear_table(CollectorPid),
+ et_collector:multicast(CollectorPid, refresh),
+ noreply(S);
+ load_all ->
+ et_collector:start_trace_client(CollectorPid, event_file, "et_viewer.log"),
+ noreply(S);
+ save_all ->
+ et_collector:save_event_file(CollectorPid,
+ "et_viewer.log",
+ [existing, write, keep]),
+ noreply(S);
+ {open_viewer, Scale} ->
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+ _Level when Data =:= detail_level, is_integer(hd(Other)),
+ hd(Other) >= ?detail_level_min,
+ hd(Other) =< ?detail_level_max ->
+ S2 = S#state{detail_level = hd(Other)},
+ noreply(S2);
+ _PopupMenuItem when is_record(Data, filter) ->
+ open_viewer(S#state.scale, Data#filter.name, [?unknown], S),
+ noreply(S);
+ _ ->
+ click_error(Click, S),
+ noreply(S)
+ end;
+handle_info({gs, _Obj, destroy,_, _}, S) ->
+ gs:destroy(S#state.win),
+ {stop, shutdown, S};
+handle_info({gs, _Obj, buttonpress, _, [_Button, X, Y | _]}, S) ->
+ S3 =
+ case y_to_n(Y, S) of
+ actor ->
+ %% Actor click
+ case S#state.actors of
+ [] ->
+ S;
+ _ ->
+ N = x_to_n(X, S),
+ A = lists:nth(N, S#state.actors),
+ S#state{selected_actor = A}
+ end;
+ {event, N} ->
+ %% Event click
+ List = queue_to_list(S#state.events),
+ S2 = S#state{events = list_to_queue(List)},
+
+ Key = lists:nth(N, List),
+ Pid = S#state.collector_pid,
+ Fun = fun create_contents_window/2,
+ case et_collector:iterate(Pid, Key, -1) of
+ Prev when Prev =:= Key ->
+ et_collector:iterate(Pid, first, 1, Fun, S2);
+ Prev ->
+ et_collector:iterate(Pid, Prev, 1, Fun, S2)
+ end
+ end,
+ noreply(S3);
+handle_info({gs, _Obj, buttonrelease, _, [_Button, X, Y | _]}, S) ->
+ S2 =
+ case y_to_n(Y, S) of
+ actor ->
+ %% Actor click
+ case S#state.actors of
+ [] ->
+ S;
+ Actors ->
+ N = x_to_n(X, S),
+ New = lists:nth(N, S#state.actors),
+ Old = S#state.selected_actor,
+ case New#actor.name =:= Old#actor.name of
+ true ->
+ A = S#state.selected_actor,
+ toggle_search_for_actor(A#actor.name, S);
+ false ->
+ move_actor(Old, New, Actors, S)
+ end
+ end;
+ {event, _N} ->
+ %% Event click ignored
+ S
+ end,
+ noreply(S2);
+handle_info({gs, _Obj, keypress, _, [KeySym, _Keycode, _Shift, _Control | _]} = Key, S) ->
+ case KeySym of
+ 'c' ->
+ close_all_others(S);
+ 'C' ->
+ close_all(S);
+ 'Up' ->
+ S2 = scroll_up(S),
+ noreply(S2);
+ 'Down' ->
+ S2 = scroll_down(S),
+ noreply(S2);
+ 'f' ->
+ S2 = scroll_first(S),
+ noreply(S2);
+ 'p' ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ 'Prior' ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ 'n' ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ 'Next' ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ 'l' ->
+ S2 = scroll_last(S),
+ noreply(S2);
+ 'r' ->
+ S2 = refresh_main_window(S),
+ noreply(S2);
+ 'F' ->
+ et_collector:multicast(S#state.collector_pid, first),
+ noreply(S);
+ 'P' ->
+ et_collector:multicast(S#state.collector_pid, prev),
+ noreply(S);
+ 'N' ->
+ et_collector:multicast(S#state.collector_pid, next),
+ noreply(S);
+ 'L' ->
+ et_collector:multicast(S#state.collector_pid, last),
+ noreply(S);
+ 'R' ->
+ et_collector:multicast(S#state.collector_pid, refresh),
+ noreply(S);
+
+ 'a' ->
+ S2 = S#state{display_mode = all},
+ S3 = refresh_main_window(S2),
+ noreply(S3);
+
+ 'equal' ->
+ Scale = S#state.scale,
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+ 'plus' ->
+ Scale = S#state.scale + 1,
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+ 'minus' ->
+ case S#state.scale of
+ 1 ->
+ gs:config(S#state.canvas, beep);
+ Scale ->
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale - 1, S#state.active_filter, Actors, S)
+ end,
+ noreply(S);
+ 0 ->
+ case lists:keysearch(?DEFAULT_FILTER_NAME, #filter.name, S#state.filters) of
+ {value, F} when is_record(F, filter) ->
+ open_viewer(S#state.scale, F#filter.name, [?unknown], S);
+ false ->
+ gs:config(S#state.canvas, beep)
+ end,
+ noreply(S);
+ Int when is_integer(Int), Int > 0, Int =< 9 ->
+ case catch lists:nth(Int, S#state.filters) of
+ F when is_record(F, filter) ->
+ open_viewer(S#state.scale, F#filter.name, [?unknown], S);
+ {'EXIT', _} ->
+ gs:config(S#state.canvas, beep)
+ end,
+ noreply(S);
+
+ 'Shift_L' ->
+ noreply(S);
+ 'Shift_R' ->
+ noreply(S);
+ 'Caps_Lock' ->
+ noreply(S);
+
+ _ ->
+ click_error(Key, S),
+ noreply(S)
+ end;
+handle_info({gs, _Obj,configure, [], [W, H | _]}, S) ->
+ gs:config(S#state.packer, [{width, W}, {height, H}]),
+ S2 = S#state{width = W, height = H},
+ noreply(S2);
+handle_info(timeout, S) ->
+ Try =
+ case S#state.display_mode of
+ {search_actors, reverse, _, _} ->
+ -10;
+ _ ->
+ 10
+ end,
+ if
+ S#state.is_suspended =:= true ->
+ {noreply, S, infinity};
+ S#state.max_events =:= infinity ->
+ display_more_events(Try, S);
+ true ->
+ Needed = S#state.max_events - queue_length(S#state.events),
+ if
+ Needed =< 0 -> {noreply, S, infinity};
+ Needed > 10 -> display_more_events(Try, S);
+ Needed =< 10 -> display_more_events(Needed, S)
+ end
+ end;
+
+handle_info({'EXIT', Pid, Reason}, S) ->
+ if
+ Pid =:= S#state.collector_pid ->
+ unlink(Pid),
+ gs:destroy(S#state.win),
+ {stop, Reason, S};
+ Pid =:= S#state.parent_pid ->
+ unlink(Pid),
+ gs:destroy(S#state.win),
+ {stop, Reason, S};
+ true ->
+ noreply(S)
+ end;
+handle_info(Info, S) ->
+ ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
+ [?MODULE, self(), Info, S]),
+ noreply(S).
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%----------------------------------------------------------------------
+
+terminate(_Reason, _S) ->
+ ignore.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Convert process state when code is changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+
+code_change(_OldVsn, S, _Extra) ->
+ {ok, S}.
+
+%%%----------------------------------------------------------------------
+%%% Handle suspend/resume
+%%%----------------------------------------------------------------------
+
+reply(Reply, S) ->
+ case queue_length(S#state.events) of
+ _ when S#state.is_suspended =:= true ->
+ {reply, Reply, S, infinity};
+ _ when S#state.max_events =:= infinity ->
+ {reply, Reply, S, 500};
+ N when N >= S#state.max_events ->
+ {reply, Reply, S, infinity};
+ _ ->
+ {reply, Reply, S, 0}
+ end.
+
+noreply(S) ->
+ case queue_length(S#state.events) of
+ _ when S#state.is_suspended =:= true ->
+ {noreply, S, infinity};
+ _ when S#state.max_events =:= infinity ->
+ {noreply, S, 500};
+ N when N >= S#state.max_events ->
+ {noreply, S, infinity};
+ _ ->
+ {noreply, S, 0}
+ end.
+
+do_suspend(S) ->
+ config_suspend(S#state{is_suspended = true}).
+
+do_resume(S) ->
+ config_suspend(S#state{is_suspended = false}).
+
+config_suspend(S) ->
+ Suspended = S#state.is_suspended,
+ gs:config(refresh, [{enable, not Suspended}]),
+ gs:config(refresh_all, [{enable, not Suspended}]),
+ gs:config(clear_all, [{enable, not Suspended}]),
+ S.
+
+refresh_main_window(S) ->
+ Pid = S#state.collector_pid,
+ Key = S#state.first_event,
+ case et_collector:iterate(Pid, Key, -1) of
+ Prev when Prev =:= Key ->
+ scroll_first(S);
+ _Prev ->
+ S2 = S#state{last_event = S#state.first_event},
+ clear_canvas(S2)
+ end.
+
+scroll_first(S) ->
+ S2 = S#state{first_event = first, last_event = first},
+ clear_canvas(S2).
+
+scroll_prev(S) ->
+ Try =
+ case S#state.max_events of
+ infinity -> -10;
+ Max -> -Max
+ end,
+ Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, Try),
+ S2 = S#state{first_event = Key, last_event = Key},
+ clear_canvas(S2).
+
+scroll_next(S) ->
+ S2 = S#state{first_event = S#state.last_event},
+ clear_canvas(S2).
+
+scroll_up(S) ->
+ Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, -5),
+ S2 = S#state{first_event = Key, last_event = Key},
+ clear_canvas(S2).
+
+scroll_down(S) ->
+ Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, 5),
+ S2 = S#state{first_event = Key, last_event = Key},
+ clear_canvas(S2).
+
+scroll_last(S) ->
+ S2 = S#state{first_event = last, last_event = last},
+ clear_canvas(S2).
+
+change_display_mode(Mode, S) ->
+ case Mode of
+ all ->
+ S2 = S#state{display_mode = Mode},
+ refresh_main_window(S2);
+ {search_actors, _Dir, _Key, []} ->
+ S2 = S#state{display_mode = all},
+ refresh_main_window(S2);
+ {search_actors, _Dir, Key, Actors} when is_list(Actors) ->
+ Pid = S#state.collector_pid,
+ Prev = et_collector:iterate(Pid, Key, -1),
+ S2 = S#state{first_event = Prev,
+ last_event = Prev,
+ display_mode = Mode},
+ clear_canvas(S2)
+ end.
+
+close_all(S) ->
+ et_collector:multicast(S#state.collector_pid, close),
+ timer:sleep(timer:seconds(1)),
+ spawn(et_collector, stop, [S#state.collector_pid]),
+ gs:destroy(S#state.win),
+ {stop, shutdown, S}.
+
+close_all_others(S) ->
+ Fun =
+ fun({{subscriber, Pid}, _}) ->
+ if
+ Pid =:= self() ->
+ ignore;
+ true ->
+ unlink(Pid),
+ Pid ! {et, close}
+ end
+ end,
+ All = et_collector:dict_match(S#state.collector_pid,
+ {{subscriber, '_'}, '_'}),
+ lists:foreach(Fun, All),
+ noreply(S).
+
+click_error(Click, S) ->
+ gs:config(S#state.canvas, beep),
+ io:format("~p: ignored: ~p~n", [?MODULE, Click]).
+
+%%%----------------------------------------------------------------------
+%%% Clone viewer
+%%%----------------------------------------------------------------------
+
+open_viewer(Scale, FilterName, Actors, S) ->
+ Filters = [{dict_insert, {filter, F#filter.name}, F#filter.function}
+ || F <- S#state.filters],
+ Options =
+ [{parent_pid, S#state.parent_pid},
+ {title, S#state.title},
+ {collector_pid, S#state.collector_pid},
+ {is_suspended, S#state.is_suspended},
+ {detail_level, S#state.detail_level},
+ {active_filter, FilterName},
+ {event_order, S#state.event_order},
+ {first_event, S#state.first_event},
+ {max_events, S#state.max_events},
+ {max_actors, S#state.max_actors},
+ {hide_actions, S#state.hide_actions},
+ {hide_unknown, S#state.hide_unknown},
+ {is_suspended, S#state.is_suspended},
+ {actors, Actors},
+ {scale, Scale},
+ {width, S#state.width},
+ {height, S#state.height} | Filters],
+ case start_link(Options) of
+ {ok, ViewerPid} ->
+ unlink(ViewerPid),
+ ok;
+ {error, Reason} ->
+ ok = error_logger:format("~p: Failed to start a new window: ~p~n",
+ [?MODULE, Reason])
+ end.
+
+%%%----------------------------------------------------------------------
+%%% Handle graphics
+%%%----------------------------------------------------------------------
+
+create_main_window(S) ->
+ Font = select_font(S#state.scale),
+ GS = gs:start(),
+ Name = name_to_string(S#state.active_filter),
+ Title = case S#state.title of
+ undefined -> atom_to_list(?MODULE);
+ Explicit -> name_to_string(Explicit)
+ end,
+ WinOpt = [{title, Title ++ " (filter: " ++ Name ++ ")"},
+ {configure, true},
+ {width, S#state.width},
+ {height, S#state.height}],
+ Win = gs:window(GS, WinOpt),
+ Bar = gs:menubar(Win, []),
+
+ create_file_menu(Bar),
+ create_viewer_menu(Bar),
+ create_collector_menu(Bar),
+ gs:menubutton(filter_button, Bar, [{label, {text, "Filter"}}]),
+ create_filter_menu(S#state.active_filter, S#state.filters),
+ create_help_menu(Bar),
+
+ config_suspend(S),
+
+ PackerOpt = [{packer_x, [{fixed, 5}, {fixed, 40}, {fixed, 40},
+ {stretch, 1}, {fixed, 5}]},
+ {packer_y, [{fixed, 30}, {fixed, 30},
+ {stretch, 1}, {fixed, 30}]},
+ {x, 0}, {y, 30}],
+ Packer = gs:frame(Win, PackerOpt),
+ gs:checkbutton(suspended, Packer, [{label,{text,"Freeze"}},
+ {x, 10}, {y, 0},
+ {width, 120}, {align, w},
+ {select, S#state.is_suspended}]),
+ gs:checkbutton(hide_actions, Packer, [{label,{text,"Hide From=To"}},
+ {x, 10}, {y, 20},
+ {width, 120}, {align, w},
+ {select, S#state.hide_actions}]),
+ gs:checkbutton(hide_unknown, Packer, [{label,{text,"Hide Unknown"}},
+ {x, 10}, {y, 40},
+ {width, 120}, {align, w},
+ {select, S#state.hide_unknown}]),
+ gs:scale(Packer, [{text,"Detail Level"},
+ {range, {?detail_level_min, ?detail_level_max}},
+ {orient, horizontal},
+ {x, 150}, {y, 0}, {height, 65}, {width, 200},
+ {pos, S#state.detail_level}, {data, detail_level}]),
+ CanvasW = calc_canvas_width(S),
+ CanvasH = calc_canvas_height(S),
+ CanOpt = [{pack_xy, {{2, 4}, 3}}, {vscroll, right}, {hscroll, bottom},
+ {scrollregion, {2, 2, CanvasW, CanvasH}}],
+ Canvas = gs:canvas(Packer, CanOpt),
+ gs:config(Canvas, [{buttonpress, true}, {buttonrelease, true}]),
+ gs:config(Packer, [{width, S#state.width}, {height, S#state.height}]),
+ gs:config(Win, [{map, true}, {keypress, true}]),
+ S2 = S#state{title = Title,
+ win = Win, font = Font, packer = Packer,
+ canvas_width = CanvasW, canvas_height = CanvasH,
+ canvas = Canvas,
+ y_pos = ?initial_y * S#state.scale},
+ draw_all_actors(S2).
+
+select_font(Scale) when is_integer(Scale) ->
+ case Scale of
+ 1 -> {courier, 7};
+ 2 -> {courier, 10};
+ 3 -> {courier, 12};
+ 4 -> {courier, 14};
+ S -> {courier, S * 4}
+ end.
+
+create_file_menu(Bar) ->
+ Button = gs:menubutton(Bar, [{label, {text, "File"}}]),
+ Menu = gs:menu(Button, []),
+ gs:menuitem(close_all, Menu, [{label, {text, "Close Collector and all Viewers (C) "}}]),
+ gs:menuitem(close_all_others, Menu, [{label, {text, "Close other Viewers, but keep Collector (c)"}}]),
+ gs:menuitem(close, Menu, [{label, {text, "Close this Viewer, but keep Collector"}}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+
+ gs:menuitem(clear_all, Menu, [{label, {text, "Clear Collector"}}]),
+ gs:menuitem(load_all, Menu, [{label, {text, "Load Collector from the file \"et_viewer.log\""}}]),
+ gs:menuitem(save_all, Menu, [{label, {text, "Save Collector to the file \"et_viewer.log\""}}]).
+
+create_viewer_menu(Bar) ->
+ Button = gs:menubutton(Bar, [{label, {text, "Viewer"}}]),
+ Menu = gs:menu(Button, []),
+ gs:menuitem(Menu, [{label, {text, "Scroll this Viewer"}}, {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(first, Menu, [{label, {text, "First (f)"}}]),
+ gs:menuitem(prev, Menu, [{label, {text, "Prev (p)"}}]),
+ gs:menuitem(next, Menu, [{label, {text, "Next (n)"}}]),
+ gs:menuitem(last, Menu, [{label, {text, "Last (l)"}}]),
+ gs:menuitem(refresh, Menu, [{label, {text, "Refresh (r)"}}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(up, Menu, [{label, {text, "Up 5 (Up)"}}]),
+ gs:menuitem(down, Menu, [{label, {text, "Down 5 (Down)"}}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(Menu, [{label, {text, "Search in this Viewer"}}, {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem({mode, all}, Menu, [{label, {text, "Abort search. Display all (a)"}}]).
+
+create_collector_menu(Bar) ->
+ Button = gs:menubutton(Bar, [{label, {text, "Collector"}}]),
+ Menu = gs:menu(Button, []),
+ gs:menuitem(Menu, [{label, {text, "Scroll all Viewers"}}, {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(first_all, Menu, [{label, {text, "First (F)"}}]),
+ gs:menuitem(prev_all, Menu, [{label, {text, "Prev (P)"}}]),
+ gs:menuitem(next_all, Menu, [{label, {text, "Next (N)"}}]),
+ gs:menuitem(last_all, Menu, [{label, {text, "Last (L)"}}]),
+ gs:menuitem(refresh_all, Menu, [{label, {text, "Refresh (R)"}}]).
+
+create_filter_menu(ActiveFilterName, Filters) ->
+ Menu = gs:menu(filter_menu, filter_button, []),
+ Item = fun(F, N) when F#filter.name =:= collector ->
+ Label = lists:concat([pad_string(F#filter.name, 20), "(0)"]),
+ gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
+ N + 1;
+ (F, N) ->
+ Label = lists:concat([pad_string(F#filter.name, 20), "(", N, ")"]),
+ gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
+ N + 1
+ end,
+ gs:menuitem(Menu, [{label, {text, "Same Filter New Scale"}}, {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ {value, Filter} = lists:keysearch(ActiveFilterName, #filter.name, Filters),
+ Same = lists:concat([pad_string(ActiveFilterName, 20), "(=)"]),
+ Larger = lists:concat([pad_string(ActiveFilterName, 20), "(+)"]),
+ Smaller = lists:concat([pad_string(ActiveFilterName, 20), "(-)"]),
+ gs:menuitem(Menu, [{label, {text, Same}}, {data, Filter}]),
+ gs:menuitem(Menu, [{label, {text, Smaller}}, {data, Filter}]),
+ gs:menuitem(Menu, [{label, {text, Larger}}, {data, Filter}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(Menu, [{label, {text, "New Filter Same Scale"}}, {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ lists:foldl(Item, 1, Filters).
+
+create_help_menu(Bar) ->
+ Button = gs:menubutton(Bar, [{label, {text, "Help"}}]),
+ Menu = gs:menu(Button, []),
+ gs:menuitem(Menu, [{label, {text, "Display details of an event"}},
+ {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{label, {text, " Single click on the name tag or the arrow (Mouse-1)"}},
+ {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(Menu, [{label, {text, "Toggle actor search"}},
+ {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{label, {text, " Single click on the name tag (Mouse-1)"}},
+ {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(Menu, [{label, {text, "Move actor"}},
+ {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{label, {text, " se drag and drop on name tag (Mouse-1)"}},
+ {enable,false}]).
+
+clear_canvas(S) ->
+ gs:destroy(S#state.canvas),
+ CanvasW = calc_canvas_width(S),
+ CanvasH = calc_canvas_height(S),
+ CanOpt = [{pack_xy, {{2, 4}, 3}}, {vscroll, right}, {hscroll, bottom},
+ {scrollregion, {2, 2, CanvasW, CanvasH}}],
+ Canvas = gs:canvas(S#state.packer, CanOpt),
+ gs:config(S#state.packer, [{width, S#state.width}, {height, S#state.height}]),
+ gs:config(Canvas, [{buttonpress, true}, {buttonrelease, true}]),
+ S2 = S#state{refresh_needed = false,
+ y_pos = ?initial_y * S#state.scale,
+ canvas = Canvas,
+ canvas_width = CanvasW,
+ canvas_height = CanvasH,
+ events = queue_new()},
+ draw_all_actors(S2).
+
+calc_canvas_width(S) ->
+ Min = calc_min_actors(S),
+ CanvasW = ((2 * ?initial_x) + (Min * ?incr_x)) * S#state.scale,
+ lists:max([CanvasW, S#state.width - (15 * S#state.scale), S#state.canvas_width]).
+
+calc_canvas_height(S) ->
+ Min = calc_min_events(S),
+ CanvasH = ((2 * ?initial_y) + (Min * ?incr_y)) * S#state.scale,
+ lists:max([CanvasH, S#state.height - (4 * 30), S#state.canvas_height]).
+
+calc_min_actors(S) ->
+ Max = S#state.max_actors,
+ N = length(S#state.actors),
+ if
+ Max =:= infinity ->
+ N * 2;
+ Max < N ->
+ N;
+ true ->
+ Max
+ end.
+
+calc_min_events(S) ->
+ Max = S#state.max_events,
+ N = queue_length(S#state.events),
+ if
+ Max =:= infinity ->
+ N * 2;
+ Max < N ->
+ N;
+ true ->
+ Max
+ end.
+
+display_more_events(Try, S) ->
+ Name = S#state.active_filter,
+ {value, F} = lists:keysearch(Name, #filter.name, S#state.filters),
+ FilterFun = F#filter.function,
+ Fun = fun(Event, State) ->
+ case catch FilterFun(Event) of
+ true ->
+ State2 = ensure_key(Event, State),
+ opt_display_event(Event, State2);
+ {true, Event2} ->
+ State2 = ensure_key(Event2, State),
+ opt_display_event(Event2, State2);
+ false ->
+ ensure_key(Event, State);
+ Bad ->
+ Contents = {bad_filter, Name, Bad, Event},
+ Event2 = Event#event{contents = Contents,
+ from = bad_filter,
+ to = bad_filter},
+ State2 = ensure_key(Event2, State),
+ opt_display_event(Event2, State2)
+ end
+ end,
+ Pid = S#state.collector_pid,
+ S2 = et_collector:iterate(Pid, S#state.last_event, Try, Fun, S),
+ case queue_length(S2#state.events) - queue_length(S#state.events) of
+ Diff when Diff =:= Try ->
+ %% Got as much as requested, look for more
+ %% io:format("Done: ~p~n", [{Try, Diff}]),
+ {noreply, S2, 0};
+ _Diff when S2#state.first_event =:= S#state.first_event,
+ S2#state.last_event =:= S#state.last_event ->
+ %% Got lesser than requested, wait a while before looking for more
+ %% io:format("More: ~p~n", [{Try, Diff}]),
+ {noreply, S2, 500};
+ _Diff ->
+ %% Got lesser than requested, look for more
+ %% io:format("More2: ~p~n", [{Try, Diff}]),
+ {noreply, S2, 0}
+ end.
+
+ensure_key(E, S) when is_record(E, event), is_record(S, state) ->
+ Key = et_collector:make_key(S#state.event_order, E),
+ case S#state.first_event of
+ first ->
+ S#state{first_event = Key, last_event = Key};
+ last ->
+ S#state{first_event = Key, last_event = Key};
+ _ ->
+ S#state{last_event = Key}
+ end.
+
+opt_display_event(E, S) ->
+ case S#state.display_mode of
+ all ->
+ display_event(E, S);
+ {search_actors, _Dir, _FirstKey, Actors} ->
+ %% Key = S#state.last_event,
+ From = select_actor_name(E#event.from, S),
+ case lists:member(From, Actors) of
+ true ->
+ display_event(E, S);
+ false ->
+ To = select_actor_name(E#event.to, S),
+ case lists:member(To, Actors) of
+ true ->
+ display_event(E, S);
+ false ->
+ S
+ end
+ end
+ end.
+
+select_actor_name(Name, S) ->
+ case lists:keymember(Name, #actor.name, S#state.actors) of
+ true -> Name;
+ false -> ?unknown
+ end.
+
+display_event(E, S) when E#event.detail_level < S#state.detail_level ->
+ {FromRefresh, From} = ensure_actor(E#event.from, S),
+ {FromName, FromPos, S2} = From,
+ {ToRefresh, To} = ensure_actor(E#event.to, S2),
+ {ToName, ToPos, S3} = To,
+ if
+ FromRefresh =/= false, ToRefresh =/= false ->
+ Key = S#state.last_event,
+ refresh_beep(S),
+ S3#state{refresh_needed = true,
+ events = queue_in(Key, S3#state.events)};
+ FromName =:= ToName ->
+ case S#state.hide_actions of
+ true ->
+ S3;
+ false ->
+ Label = name_to_string(E#event.label),
+ draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S3)
+ end;
+ true ->
+ Label = name_to_string(E#event.label),
+ draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S3)
+ end;
+display_event(_, S) ->
+ S.
+
+draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S) ->
+ Key = S#state.last_event,
+ case S#state.y_pos + (?incr_y * S#state.scale) of
+ _ when S#state.hide_unknown =:= true, FromName =:= ?unknown ->
+ S;
+ _ when S#state.hide_unknown =:= true, ToName =:= ?unknown ->
+ S;
+ Y when Y > S#state.canvas_height ->
+ refresh_beep(S),
+ S#state{refresh_needed = true,
+ events = queue_in(Key, S#state.events)};
+ Y ->
+ S2 = S#state{y_pos = Y, events = queue_in(Key, S#state.events)},
+ S3 = draw_arrow(FromPos, ToPos, S2),
+ draw_label(Label, FromName, ToName, FromPos, ToPos, S3)
+ end.
+
+refresh_beep(S) ->
+ case S#state.refresh_needed of
+ false ->
+ gs:config(S#state.canvas, beep),
+ gs:config(S#state.canvas, beep),
+ gs:config(S#state.canvas, beep);
+ true ->
+ ignore
+ end.
+
+draw_arrow(Pos, Pos, S) ->
+ S;
+draw_arrow(FromPos, ToPos, S) ->
+ Y = S#state.y_pos,
+ CanOpts = [{coords, [{FromPos , Y}, {ToPos, Y}]},
+ {arrow, last},{width, 1}, {fg, black}],
+ gs:line(S#state.canvas, CanOpts),
+ S.
+
+draw_label(Label, FromName, ToName, FromPos, ToPos, S) ->
+ Colour =
+ if
+ FromName =:= ?unknown,
+ ToName =:= ?unknown -> blue; %turquoise;
+ FromName =:= ?unknown -> orange;
+ ToName =:= ?unknown -> orange;
+ FromPos =:= ToPos -> blue;
+ true -> red
+ end,
+ Scale = S#state.scale,
+ X = lists:min([FromPos, ToPos]) + (6 * Scale),
+ Y = S#state.y_pos,
+ write_text(Label, X, Y, Colour, S),
+ S.
+
+draw_all_actors(State) ->
+ Scale = State#state.scale,
+ Fun = fun(A, X) ->
+ draw_actor(A, X, State),
+ X + (?incr_x * Scale)
+ end,
+ lists:foldl(Fun, ?initial_x * Scale, State#state.actors),
+ State.
+
+%% Returns: {NeedsRefreshBool, {ActorPos, NewsS, NewActors}}
+ensure_actor(Name, S) ->
+ do_ensure_actor(Name, S, S#state.actors, 0).
+
+do_ensure_actor(Name, S, [H | _], N) when H#actor.name =:= Name ->
+ Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
+ {false, {Name, Pos, S}};
+do_ensure_actor(Name, S, [_ | T], N) ->
+ do_ensure_actor(Name, S, T, N + 1);
+do_ensure_actor(Name, S, [], N) ->
+ %% A brand new actor, let's see if it does fit
+ Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
+ MaxActors = S#state.max_actors,
+ if
+ is_integer(MaxActors), N > MaxActors ->
+ %% Failed on max_actors limit, put into unknown
+ %% Assume that unknown always is in actor list
+ ensure_actor(?unknown, S);
+ Pos > (S#state.canvas_width - ((?initial_x - 15) * S#state.scale)) ->
+ %% New actor does not fit in canvas, refresh needed
+ A = create_actor(Name),
+ draw_actor(A, Pos, S),
+ {true, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}};
+ true ->
+ %% New actor fits in canvas. Draw the new actor.
+ A = create_actor(Name),
+ draw_actor(A, Pos, S),
+ {false, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}}
+ end.
+
+draw_actor(A, LineX, S) ->
+ Scale = S#state.scale,
+ TextX = LineX - (5 * Scale),
+ TextY = ?initial_y * Scale,
+ LineTopY = TextY + ((?incr_y / 2) * Scale),
+ LineBotY = S#state.canvas_height - ((?incr_y / 2) * Scale),
+ Colour = case A#actor.name of
+ ?unknown -> orange;
+ _ -> red
+ end,
+ write_text(A#actor.string, TextX, TextY, Colour, S),
+ LineOpt = [{coords, [{LineX, LineTopY}, {LineX, LineBotY}]},
+ {width, 1}, {fg, Colour}],
+ gs:line(S#state.canvas, LineOpt).
+
+toggle_search_for_actor(ActorName,S) ->
+ case S#state.display_mode of
+ all ->
+ io:format("~p: search for: ~p ++ ~p~n", [?MODULE, [], [ActorName]]),
+ %% Search for this actor
+ Key = S#state.first_event,
+ Actors = [ActorName],
+ Mode = {search_actors, forward, Key, Actors},
+ change_display_mode(Mode, S);
+ {search_actors, Dir, Key, Actors}->
+ Actors2 =
+ case lists:member(ActorName, Actors) of
+ true ->
+ io:format("~p: search for: ~p -- ~p~n", [?MODULE, Actors, [ActorName]]),
+ %% Remove actor from search list
+ Actors -- [ActorName];
+ false ->
+ io:format("~p: search for: ~p ++ ~p~n", [?MODULE, Actors, [ActorName]]),
+ %% Add actor from search list
+ [ActorName | Actors]
+ end,
+ Mode2 = {search_actors, Dir, Key, Actors2},
+ change_display_mode(Mode2, S)
+ end.
+
+move_actor(From, To, Actors, S) ->
+ Pos = #actor.name,
+ ToName = To#actor.name,
+ FromName = From#actor.name,
+ ToIx = actor_index(ToName, Pos, Actors),
+ FromIx = actor_index(FromName, Pos, Actors),
+ if
+ FromIx =/= 0, ToIx =/= 0, ToIx > FromIx ->
+ Actors2 = lists:keydelete(FromName, Pos, Actors),
+ Actors3 = insert_actor_after(From, To, Actors2),
+ S2 = S#state{actors = Actors3},
+ refresh_main_window(S2);
+ FromIx =/= 0, ToIx =/= 0 ->
+ Actors2 = lists:keydelete(FromName, Pos, Actors),
+ Actors3 = insert_actor_before(From, To, Actors2),
+ S2 = S#state{actors = Actors3},
+ refresh_main_window(S2);
+ true ->
+ %% Ignore
+ S
+ end.
+
+insert_actor_after(From, To, [H | T]) ->
+ case To#actor.name =:= H#actor.name of
+ true -> [H, From | T];
+ false -> [H | insert_actor_after(From, To, T)]
+ end;
+insert_actor_after(_From, _To, []) ->
+ [].
+
+insert_actor_before(From, To, [H | T]) ->
+ case To#actor.name =:= H#actor.name of
+ true -> [From, H | T];
+ false -> [H | insert_actor_before(From, To, T)]
+ end;
+insert_actor_before(_From, _To, []) ->
+ [].
+
+actor_index(_Key, _Pos, []) ->
+ 0;
+actor_index(Key, Pos, [H | T]) ->
+ case Key =:= element(Pos, H) of
+ false -> actor_index(Key, Pos, T) + 1;
+ true -> 1
+ end.
+
+y_to_n(Y, S) ->
+ Y2 = ((Y / S#state.scale) - ?initial_y + (?incr_y / 2)),
+ N = round(Y2 / ?incr_y - 0.2),
+ MaxN = queue_length(S#state.events),
+ if
+ N =< 0 -> actor;
+ N > MaxN -> actor;
+ true -> {event, N}
+ end.
+
+x_to_n(X, S) ->
+ Scale = S#state.scale,
+ Len = length(S#state.actors),
+ X2 = X - (?initial_x * Scale),
+ N = X2 / (?incr_x * Scale),
+ N2 = trunc(N + 1.5),
+ if
+ N2 > Len -> Len;
+ N2 < 1 -> 1;
+ true -> N2
+ end.
+
+write_text(Text, X, Y, Colour, S) ->
+ Opt = [{coords, [{X, Y - (?incr_y * S#state.scale / 2)}]},
+ {font, S#state.font}, {fg, Colour}, {text, Text}],
+ gs:text(S#state.canvas, Opt).
+
+create_contents_window(Event, S) ->
+ Options = [{viewer_pid, self()},
+ {event, Event},
+ {event_order, S#state.event_order},
+ {active_filter, S#state.active_filter}
+ | S#state.filters],
+ case et_gs_contents_viewer:start_link(Options) of
+ {ok, _Pid} ->
+ S;
+ {error, Reason} ->
+ ok = error_logger:format("~p(~p): create_contents_window(~p) ->~n ~p~n",
+ [?MODULE, self(), Options, Reason]),
+ S
+ end.
+
+%%%----------------------------------------------------------------------
+%%% String padding of actors
+%%%----------------------------------------------------------------------
+
+create_actor(Name) ->
+ String = name_to_string(Name),
+ PaddedString = pad_string(String, 8),
+ #actor{name = Name, string = PaddedString}.
+
+name_to_string(Name) ->
+ case catch io_lib:format("~s", [Name]) of
+ {'EXIT', _} -> lists:flatten(io_lib:format("~w", [Name]));
+ GoodString -> lists:flatten(GoodString)
+ end.
+
+pad_string(Atom, MinLen) when is_atom(Atom) ->
+ pad_string(atom_to_list(Atom), MinLen);
+pad_string(String, MinLen) when is_integer(MinLen), MinLen >= 0 ->
+ Len = length(String),
+ case Len >= MinLen of
+ true ->
+ String;
+ false ->
+ String ++ lists:duplicate(MinLen - Len, $ )
+ end.
+
+%%%----------------------------------------------------------------------
+%%% Queue management
+%%%----------------------------------------------------------------------
+
+queue_new() ->
+ {0, [], []}.
+
+queue_in(X, {Size, In, Out}) ->
+ {Size + 1, [X | In], Out}.
+
+%% queue_out(Q) ->
+%% case Q of
+%% {Size, In, [H | Out]} -> {{value, H}, {Size - 1, In, Out}};
+%% {Size, [], []} -> {empty, {Size, [], []}};
+%% {Size, In, _} -> queue_out({Size, [], lists:reverse(In)})
+%% end.
+
+queue_to_list({_Size, [], Out}) ->
+ Out;
+queue_to_list({_Size, In, Out}) ->
+ Out ++ lists:reverse(In).
+
+queue_length({Size, _In, _Out}) ->
+ Size.
+
+list_to_queue(List) when is_list(List) ->
+ {length(List), [], List}.
diff --git a/lib/et/src/et_internal.hrl b/lib/et/src/et_internal.hrl
index b6f84f5b4b..1feb161ef1 100644
--- a/lib/et/src/et_internal.hrl
+++ b/lib/et/src/et_internal.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
@@ -21,3 +21,6 @@
%%----------------------------------------------------------------------
-record(filter, {name, function}).
+
+-define(DEFAULT_FILTER_NAME, all).
+-define(DEFAULT_FILTER, #filter{name = ?DEFAULT_FILTER_NAME, function = fun(E) -> E end}).
diff --git a/lib/et/src/et_selector.erl b/lib/et/src/et_selector.erl
index 845359622d..66f5723bad 100644
--- a/lib/et/src/et_selector.erl
+++ b/lib/et/src/et_selector.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
@@ -41,14 +41,14 @@
%%
%% detail_level() = min | max | integer(X) when X =< 0, X >= 100
%%
-%% min - minimum level of tracing (ignore calls to report_event/4,5)
-%% max - maximum level of tracing (all calls to report_event/4,5)
+%% min - minimum level of tracing (ignore calls to trace_me/4,5)
+%% max - maximum level of tracing (all calls to trace_me/4,5)
%% integer() - explicit detail level of tracing
%%----------------------------------------------------------------------
make_pattern(undefined) ->
{undefined, undefined};
-make_pattern({Mod, Pattern}) when atom(Mod) ->
+make_pattern({Mod, Pattern}) when is_atom(Mod) ->
case Pattern of
min ->
{Mod, []};
@@ -57,7 +57,7 @@ make_pattern({Mod, Pattern}) when atom(Mod) ->
Body = [],
Cond = [],
{Mod, [{Head, Cond, Body}]};
- DetailLevel when integer(DetailLevel) ->
+ DetailLevel when is_integer(DetailLevel) ->
Head = ['$1', '_', '_', '_', '_'],
Body = [],
Cond = [{ '<', '$1', DetailLevel}],
@@ -80,28 +80,31 @@ make_pattern({Mod, Pattern}) when atom(Mod) ->
%% detail_level() = min | max | integer(X) when X =<0, X >= 100
%% empty_match_spec() = []
%%
-%% Min detail level deactivates tracing of calls to report_event/4,5
+%% Min detail level deactivates tracing of calls to trace_me/4,5
%%
-%% Max detail level activates tracing of all calls to report_event/4,5
+%% Max detail level activates tracing of all calls to trace_me/4,5
%%
%% integer(X) detail level activates tracing of all calls to
-%% report_event/4,5 whose detail level argument is lesser than X.
+%% trace_me/4,5 whose detail level argument is lesser than X.
%%
-%% An empty match spec deactivates tracing of calls to report_event/4,5
+%% An empty match spec deactivates tracing of calls to trace_me/4,5
%%
-%% Other match specs activates tracing of calls to report_event/4,5
+%% Other match specs activates tracing of calls to trace_me/4,5
%% accordlingly with erlang:trace_pattern/2.
%%----------------------------------------------------------------------
-change_pattern({Mod, Pattern}) when atom(Mod) ->
- MFA = {Mod, report_event, 5},
+change_pattern({Mod, Pattern}) when is_atom(Mod) ->
+ MFA = {Mod, trace_me, 5},
case Pattern of
undefined ->
ignore;
[] ->
+ error_to_exit(old_ctp(MFA)),
error_to_exit(dbg:ctp(MFA)),
error_to_exit(dbg:p(all, clear));
- List when list(List) ->
+ List when is_list(List) ->
+ error_to_exit(old_ctp(MFA)),
+ error_to_exit(old_tp(MFA, Pattern)),
error_to_exit(dbg:ctp(MFA)),
error_to_exit(dbg:tp(MFA, Pattern)),
error_to_exit(dbg:p(all, [call, timestamp]));
@@ -110,6 +113,18 @@ change_pattern({Mod, Pattern}) when atom(Mod) ->
end,
ok.
+old_ctp({Mod, _Fun, Args}) ->
+ case Mod of
+ et -> ignore;
+ _ -> dbg:ctp({Mod, report_event, Args})
+ end.
+
+old_tp({Mod, _Fun, Args}, Pattern) ->
+ case Mod of
+ et -> ignore;
+ _ -> dbg:tp({Mod, report_event, Args}, Pattern)
+ end.
+
error_to_exit({error, Reason}) ->
exit(Reason);
error_to_exit({ok, Res}) ->
@@ -148,7 +163,7 @@ error_to_exit({ok, Res}) ->
%% label - Label intended to provide a brief event summary.
%% contents - All nitty gritty details of the event.
%%
-%% See et:report_event/4 and et:report_event/5 for details.
+%% See et:trace_me/4 and et:trace_me/5 for details.
%%
%% Returns:
%%
@@ -161,7 +176,7 @@ error_to_exit({ok, Res}) ->
%% should be dropped
%%----------------------------------------------------------------------
-parse_event(_Mod, E) when record(E, event) ->
+parse_event(_Mod, E) when is_record(E, event) ->
true;
parse_event(Mod, Trace) ->
ParsedTS = erlang:now(),
@@ -293,6 +308,14 @@ parse_event(Mod, Trace, ParsedTS, ReportedTS, From, Label, Contents) ->
{msg, Msg}]}};
call ->
case Contents of
+ [{M, trace_me, [UserDetailLevel, UserFrom, UserTo, UserLabel, UserContents]}] when M == Mod, Mod /= undefined ->
+ {true, #event{detail_level = UserDetailLevel,
+ trace_ts = ReportedTS,
+ event_ts = ParsedTS,
+ from = UserFrom,
+ to = UserTo,
+ label = UserLabel,
+ contents = UserContents}}; % Term
[{M, report_event, [UserDetailLevel, UserFrom, UserTo, UserLabel, UserContents]}] when M == Mod, Mod /= undefined ->
{true, #event{detail_level = UserDetailLevel,
trace_ts = ReportedTS,
@@ -358,6 +381,21 @@ parse_event(Mod, Trace, ParsedTS, ReportedTS, From, Label, Contents) ->
{to, From},
{mfa, MFA},
{return, ReturnValue}]}};
+ exception_from ->
+ DetailLevel = 54,
+ [MFA, Exception] = Contents,
+ {true, #event{detail_level = DetailLevel,
+ trace_ts = ReportedTS,
+ event_ts = ParsedTS,
+ from = From,
+ to = From,
+ label = Label,
+ contents = [{label, Label},
+ {detail_level, DetailLevel},
+ {from, From},
+ {to, From},
+ {mfa, MFA},
+ {exception, Exception}]}};
spawn ->
DetailLevel = 25,
[NewPid, MFA] = Contents,
diff --git a/lib/et/src/et_viewer.erl b/lib/et/src/et_viewer.erl
index ede2c401eb..d9bd01f8d0 100644
--- a/lib/et/src/et_viewer.erl
+++ b/lib/et/src/et_viewer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
@@ -22,66 +22,23 @@
-module(et_viewer).
--behaviour(gen_server).
%% External exports
-export([file/1,
start/0,
start/1,
+ start/2,
start_link/1,
+ start_link/2,
+ open_event/2,
stop/1,
get_collector_pid/1]).
-%% gen_server callbacks
--export([init/1, terminate/2, code_change/3,
- handle_call/3, handle_cast/2, handle_info/2]).
-
-include("../include/et.hrl").
-include("et_internal.hrl").
-define(unknown, "UNKNOWN").
--record(state,
- {parent_pid, % Pid of parent process
- collector_pid, % Pid of collector process
- event_order, % Field to be used as primary key
- trace_pattern, % Collector trace pattern
- active_filter, % Name of the active filter
- filters, % List of possible filters
- selected_actor, % Actor selected by user
- first_event, % Key of first event (regardless of visibility)
- last_event, % Key of last event (regardless of visibility)
- max_events, % Maximum number of shown events
- events, % Queue containg all event keys (regardless of visibility)
- max_actors, % Maximum number of shown actors
- actors, % List of known actors
- refresh_needed, % Refresh is needed in order to show all actors
- display_mode, % Display all or only matching actors
- detail_level, % Show only events with lesser detail level
- hide_actions, % Hide/show events where to == from actor (bool)
- hide_unknown, % Hide/show events with unknown actor (bool)
- is_suspended, % Suspend viewer updates (bool)
- title, % GUI: Window title
- win, % GUI: Window object
- menubar, % GUI: Menu bar object
- packer, % GUI: Packer object
- width, % GUI: Window width
- height, % GUI: Window height
- scale, % GUI: Scaling factor on canvas
- font, % GUI: Font to be used on text labels
- canvas_width, % GUI: Canvas width
- canvas_height, % GUI: Canvas height
- canvas, % GUI: Canvas object
- y_pos}). % GUI: Current y position on canvas
-
--record(actor, {name, string}).
-
--define(initial_x, 10).
--define(incr_x, 60).
--define(initial_y, 15).
--define(incr_y, 15).
--define(detail_level_min, 0).
--define(detail_level_max, 100).
%%%----------------------------------------------------------------------
%%% Client side
@@ -99,7 +56,7 @@
%%----------------------------------------------------------------------
file(FileName) ->
- start_link([{trace_client, {file, FileName}}]).
+ start_link([{trace_client, {file, FileName}}], default).
%%----------------------------------------------------------------------
%% start() -> ok
@@ -113,14 +70,19 @@ file(FileName) ->
%%----------------------------------------------------------------------
start() ->
- start([{trace_global, true}]).
+ start([{trace_global, true}], default).
%%----------------------------------------------------------------------
%% start(Options) -> {ok, ViewerPid} | {error, Reason}
%%----------------------------------------------------------------------
+start(GUI) when GUI =:= wx; GUI =:= gs; GUI =:= default ->
+ start_link([{trace_global, true}], GUI);
start(Options) ->
- start_link([{parent_pid, undefined} | Options]).
+ start_link([{parent_pid, undefined} | Options], default).
+
+start(Options, GUI) ->
+ start_link([{parent_pid, undefined} | Options], GUI).
%%----------------------------------------------------------------------
%% start_link(Options) -> {ok, ViewerPid} | {error, Reason}
@@ -177,216 +139,31 @@ start(Options) ->
%% and returns false | true | {true, NewEvent}.
%%----------------------------------------------------------------------
-start_link(Options) ->
- case parse_opt(Options, default_state(), []) of
- {ok, S, CollectorOpt} ->
- case S#state.collector_pid of
- CollectorPid when pid(CollectorPid) ->
- case gen_server:start_link(?MODULE, [S], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
- unlink(Pid),
- {ok, Pid};
- Other ->
- Other
- end;
- undefined ->
- case et_collector:start_link(CollectorOpt) of
- {ok, CollectorPid} ->
- S2 = S#state{collector_pid = CollectorPid},
- case gen_server:start_link(?MODULE, [S2], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
- unlink(Pid),
- {ok, Pid};
- Other ->
- Other
- end;
- {error, Reason} ->
- {error, {et_collector, Reason}}
- end
- end;
- {error, Reason} ->
- {error, Reason}
- end.
-
-default_state() ->
- #state{parent_pid = self(),
- collector_pid = undefined,
- detail_level = ?detail_level_max,
- active_filter = collector,
- filters = [#filter{name = collector, function = fun(E) -> E end}],
- event_order = trace_ts,
- is_suspended = false,
- max_events = 100,
- first_event = first,
- last_event = first,
- events = queue_new(),
- max_actors = 5,
- actors = [create_actor(?unknown)],
- selected_actor = ?unknown,
- hide_actions = false,
- hide_unknown = false,
- refresh_needed = false,
- display_mode = all,
- scale = 2,
- canvas_height = 0,
- canvas_width = 0,
- width = 800,
- height = 600}.
-
-parse_opt([], S, CollectorOpt) ->
- {ok, S, [{parent_pid, S#state.parent_pid} | CollectorOpt]};
-parse_opt([H | T], S, CollectorOpt) ->
- case H of
- {parent_pid, Parent} when Parent == undefined ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{parent_pid = Parent}, CollectorOpt2);
- {parent_pid, Parent} when pid(Parent) ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{parent_pid = Parent}, CollectorOpt2);
- {title, Title} ->
- parse_opt(T, S#state{title = name_to_string(Title)}, CollectorOpt);
- {detail_level, Level} when integer(Level),
- Level >= ?detail_level_min,
- Level =< ?detail_level_max ->
- parse_opt(T, S#state{detail_level = Level}, CollectorOpt);
- {detail_level, max} ->
- parse_opt(T, S#state{detail_level = ?detail_level_max}, CollectorOpt);
- {detail_level, min} ->
- parse_opt(T, S#state{detail_level = ?detail_level_min}, CollectorOpt);
- {is_suspended, true} ->
- parse_opt(T, S#state{is_suspended = true}, CollectorOpt);
- {is_suspended, false} ->
- parse_opt(T, S#state{is_suspended = false}, CollectorOpt);
- {scale, Scale} when integer(Scale), Scale > 0 ->
- parse_opt(T, S#state{scale = Scale}, CollectorOpt);
- {width, W} when integer(W), W > 0 ->
- parse_opt(T, S#state{width = W, canvas_width = W}, CollectorOpt);
- {height, WH} when integer(WH), WH > 0 ->
- parse_opt(T, S#state{height = WH, canvas_height = WH}, CollectorOpt);
- {collector_pid, Pid} when pid(Pid) ->
- parse_opt(T, S#state{collector_pid = Pid}, CollectorOpt);
- {collector_pid, undefined} ->
- parse_opt(T, S#state{collector_pid = undefined}, CollectorOpt);
- {active_filter, Name} when atom(Name) ->
- parse_opt(T, S#state{active_filter = Name}, CollectorOpt);
- {event_order, trace_ts} -> %% BUGBUG: Verify event_order with collector
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{event_order = trace_ts}, CollectorOpt2);
- {event_order, event_ts} -> %% BUGBUG: Verify event_order with collector
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{event_order = event_ts}, CollectorOpt2);
- {trace_port, _Port} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {trace_max_queue, _Queue} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {trace_pattern, _Pattern} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {trace_global, _Boolean} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {trace_client, _Client} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {dict_insert, {filter, Name}, Fun} ->
- if
- atom(Name), function(Fun) ->
- F = #filter{name = Name, function = Fun},
- Filters = lists:keydelete(Name, #filter.name, S#state.filters),
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{filters = Filters ++ [F]}, CollectorOpt2);
- true ->
- {error, {bad_option, H}}
- end;
- {dict_insert, {subscriber, Pid}, _Val} ->
- if
- pid(Pid) ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- true ->
- {error, {bad_option, H}}
- end;
- {dict_insert, _Key, _Val} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {dict_delete, {filter, Name}} ->
- Filters = lists:keydelete(Name, #filter.name, S#state.filters),
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{filters = Filters}, CollectorOpt2);
- {dict_delete, _Key} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {max_events, Max} when integer(Max), Max > 0->
- parse_opt(T, S#state{max_events = Max}, CollectorOpt);
- {max_events, Max} when Max == infinity ->
- parse_opt(T, S#state{max_events = Max}, CollectorOpt);
- {max_actors, Max} when integer(Max), Max >= 0->
- parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
- {max_actors, Max} when Max == infinity ->
- parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
- {actors, ActorNames} when list(ActorNames) ->
- ActorNames2 =
- case lists:member(?unknown, ActorNames) of
- false -> [?unknown | ActorNames];
- true -> ActorNames
- end,
- Actors = [create_actor(Name) || Name <- ActorNames2],
- parse_opt(T, S#state{actors = Actors}, CollectorOpt);
- {first_event, First} ->
- parse_opt(T, S#state{first_event = First}, CollectorOpt);
- {hide_unknown, Bool} when Bool == false ->
- parse_opt(T, S#state{hide_unknown = Bool}, CollectorOpt);
- {hide_unknown, Bool} when Bool == true ->
- parse_opt(T, S#state{hide_unknown = Bool}, CollectorOpt);
- {hide_actions, Bool} when Bool == false ->
- parse_opt(T, S#state{hide_actions = Bool}, CollectorOpt);
- {hide_actions, Bool} when Bool == true ->
- parse_opt(T, S#state{hide_actions = Bool}, CollectorOpt);
- {display_mode, Mode = all} ->
- parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
- {display_mode, Mode = {search_actors, Dir, _Key, Actors}} when list(Actors), Dir == forward ->
- parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
- {display_mode, Mode = {search_actors, Dir, _Key, Actors}} when list(Actors), Dir == reverse ->
- parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
+start_link(GUI) when GUI =:= wx; GUI =:= gs; GUI =:= default ->
+ start_link([{trace_global, true}], GUI);
+start_link(Options) ->
+ start_link(Options, default).
- Bad ->
- {error, {bad_option, Bad}}
- end;
-parse_opt(BadList, _S, _CollectorOpt) ->
- {error, {bad_option_list, BadList}}.
+start_link(Options, GUI) ->
+ case GUI of
+ wx ->
+ et_wx_viewer:start_link(Options);
+ gs ->
+ et_gs_viewer:start_link(Options);
+ default ->
+ start_link(Options, which_gui())
+ end.
-do_dict_insert({filter, Name}, Fun, S) when atom(Name), function(Fun) ->
- F = #filter{name = Name, function = Fun},
- Filters = lists:keydelete(Name, #filter.name, S#state.filters),
- Filters2 = lists:keysort(#filter.name, [F | Filters]),
- gs:destroy(filter_menu),
- create_filter_menu(S#state.active_filter, Filters2),
- S#state{filters = Filters2};
-do_dict_insert(_Key, _Val, S) ->
- %% ok = error_logger:format("~p(~p): handle_info({et, {dict_insert, ~p, ~p}})~n",
- %% [?MODULE, self(), Key, Val]),
- S.
-do_dict_delete({filter, Name}, S) when atom(Name), Name /= S#state.active_filter ->
- Filters = lists:keydelete(Name, #filter.name, S#state.filters),
- gs:destroy(filter_menu),
- create_filter_menu(S#state.active_filter, Filters),
- S#state{filters = Filters};
-do_dict_delete(_Key, S) ->
- %% ok = error_logger:format("~p(~p): handle_info({et, {dict_delete, ~p}})~n",
- %% [?MODULE, self(), Key]),
- S.
+which_gui() ->
+ try
+ wx:new(),
+ wx:destroy(),
+ wx
+ catch _:_ ->
+ gs
+ end.
-%%----------------------------------------------------------------------
-%% get_collector_pid(ViewerPid) -> CollectorPid
-%%
-%% Returns the identifier of the collector process
-%%
-%% ViewerPid = pid()
-%% CollectorPid = pid()
-%%----------------------------------------------------------------------
get_collector_pid(ViewerPid) ->
call(ViewerPid, get_collector_pid).
@@ -402,1201 +179,14 @@ get_collector_pid(ViewerPid) ->
stop(ViewerPid) ->
call(ViewerPid, stop).
-call(ViewerPid, Request) ->
- gen_server:call(ViewerPid, Request, infinity).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_server
-%%%----------------------------------------------------------------------
%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%%----------------------------------------------------------------------
-init([S]) when record(S, state) ->
- process_flag(trap_exit, true),
- InitialTimeout = 0,
- case S#state.parent_pid of
- undefined ->
- ignore;
- Pid when pid(Pid) ->
- link(Pid)
- end,
- et_collector:dict_insert(S#state.collector_pid,
- {subscriber, self()},
- ?MODULE),
- {ok, create_main_window(S), InitialTimeout}.
+open_event(ViewerPid, N) ->
+ call(ViewerPid, {open_event, N}).
%%----------------------------------------------------------------------
-%% Func: handle_call/3
-%% Returns: {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} | (terminate/2 is called)
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-
-handle_call(get_collector_pid, _From, S) ->
- Reply = S#state.collector_pid,
- reply(Reply, S);
-handle_call(stop, _From, S) ->
- gs:destroy(S#state.win),
- {stop, shutdown, ok, S};
-handle_call(Request, From, S) ->
- ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
- [?MODULE, self(), Request, From, S]),
- Reply = {error, {bad_request, Request}},
- reply(Reply, S).
-
-%%----------------------------------------------------------------------
-%% Func: handle_cast/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-
-handle_cast(Msg, S) ->
- ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
- [?MODULE, self(), Msg, S]),
- noreply(S).
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-
-handle_info({et, {insert_actors, ActorNames}}, S) when list(ActorNames) ->
- Fun = fun(N, Actors) ->
- case lists:keymember(N, #actor.name, Actors) of
- true -> Actors;
- false -> Actors ++ [create_actor(N)]
- end
- end,
- Actors = lists:foldl(Fun, S#state.actors, ActorNames),
- S2 = refresh_main_window(S#state{actors = Actors}),
- noreply(S2);
-handle_info({et, {delete_actors, ActorNames}}, S) when list(ActorNames)->
- Fun = fun(N, Actors) when N == ?unknown ->
- Actors;
- (N, Actors) ->
- lists:keydelete(N, #actor.name, Actors)
- end,
- New = lists:foldl(Fun, S#state.actors, ActorNames),
- S2 = refresh_main_window(S#state{actors = New}),
- noreply(S2);
-handle_info({et, {dict_insert, Key, Val}}, S) ->
- S2 = do_dict_insert(Key, Val, S),
- noreply(S2);
-handle_info({et, {dict_delete, Key}}, S) ->
- S2 = do_dict_delete(Key, S),
- noreply(S2);
-handle_info({et, first}, S) ->
- S2 = scroll_first(S),
- noreply(S2);
-handle_info({et, prev}, S) ->
- S2 = scroll_prev(S),
- noreply(S2);
-handle_info({et, next}, S) ->
- S2 = scroll_next(S),
- noreply(S2);
-handle_info({et, last}, S) ->
- S2 = scroll_last(S),
- noreply(S2);
-handle_info({et, refresh}, S) ->
- S2 = refresh_main_window(S),
- noreply(S2);
-handle_info({et, {display_mode, Mode}}, S) ->
- S2 = change_display_mode(Mode, S),
- noreply(S2);
-handle_info({et, close}, S) ->
- gs:destroy(S#state.win),
- {stop, shutdown, S};
-handle_info({gs, Button, click, Data, Other} = Click, S) ->
- CollectorPid = S#state.collector_pid,
- case Button of
- close ->
- gs:destroy(S#state.win),
- {stop, shutdown, S};
- suspended ->
- case Other of
- [_Text, _Group, Bool | _] when Bool == true ->
- S2 = do_suspend(S),
- noreply(S2);
- [_Text, _Group, Bool | _] when Bool == false ->
- S2 = do_resume(S),
- noreply(S2);
- _ ->
- click_error(Click, S),
- noreply(S)
- end;
- hide_actions ->
- case Other of
- [_Text, _Group, Bool | _] when Bool == true ->
- S2 = refresh_main_window(S#state{hide_actions = Bool}),
- noreply(S2);
- [_Text, _Group, Bool | _] when Bool == false ->
- S2 = refresh_main_window(S#state{hide_actions = Bool}),
- noreply(S2);
- _ ->
- click_error(Click, S),
- noreply(S)
- end;
- hide_unknown ->
- case Other of
- [_Text, _Group, Bool | _] when Bool == true ->
- S2 = refresh_main_window(S#state{hide_unknown = Bool}),
- noreply(S2);
- [_Text, _Group, Bool | _] when Bool == false ->
- S2 = refresh_main_window(S#state{hide_unknown = Bool}),
- noreply(S2);
- _ ->
- click_error(Click, S),
- noreply(S)
- end;
- up ->
- S2 = scroll_up(S),
- noreply(S2);
- down ->
- S2 = scroll_down(S),
- noreply(S2);
- first ->
- S2 = scroll_first(S),
- noreply(S2);
- prev ->
- S2 = scroll_prev(S),
- noreply(S2);
- next ->
- S2 = scroll_next(S),
- noreply(S2);
- last ->
- S2 = scroll_last(S),
- noreply(S2);
- refresh ->
- S2 = refresh_main_window(S),
- noreply(S2);
- {display_mode, Mode} ->
- S2 = change_display_mode(Mode, S),
- noreply(S2);
- close_all ->
- close_all(S);
- close_all_others ->
- close_all_others(S);
- first_all ->
- et_collector:multicast(CollectorPid, first),
- noreply(S);
- prev_all ->
- et_collector:multicast(CollectorPid, prev),
- noreply(S);
- next_all ->
- et_collector:multicast(CollectorPid, next),
- noreply(S);
- last_all ->
- et_collector:multicast(CollectorPid, last),
- noreply(S);
- refresh_all ->
- et_collector:multicast(CollectorPid, refresh),
- noreply(S);
- clear_all ->
- et_collector:clear_table(CollectorPid),
- et_collector:multicast(CollectorPid, refresh),
- noreply(S);
- load_all ->
- et_collector:start_trace_client(CollectorPid, event_file, "et_viewer.log"),
- noreply(S);
- save_all ->
- et_collector:save_event_file(CollectorPid,
- "et_viewer.log",
- [existing, write, keep]),
- noreply(S);
- {open_viewer, Scale} ->
- Actors = [A#actor.name || A <- S#state.actors],
- open_viewer(Scale, S#state.active_filter, Actors, S),
- noreply(S);
- _Level when Data == detail_level, integer(hd(Other)),
- hd(Other) >= ?detail_level_min,
- hd(Other) =< ?detail_level_max ->
- S2 = S#state{detail_level = hd(Other)},
- noreply(S2);
- _PopupMenuItem when record(Data, filter) ->
- open_viewer(S#state.scale, Data#filter.name, [?unknown], S),
- noreply(S);
- _ ->
- click_error(Click, S),
- noreply(S)
- end;
-handle_info({gs, _Obj, destroy,_, _}, S) ->
- gs:destroy(S#state.win),
- {stop, shutdown, S};
-handle_info({gs, _Obj, buttonpress, _, [_Button, X, Y | _]}, S) ->
- S3 =
- case y_to_n(Y, S) of
- actor ->
- %% Actor click
- case S#state.actors of
- [] ->
- S;
- _ ->
- N = x_to_n(X, S),
- A = lists:nth(N, S#state.actors),
- S#state{selected_actor = A}
- end;
- {event, N} ->
- %% Event click
- List = queue_to_list(S#state.events),
- S2 = S#state{events = list_to_queue(List)},
-
- Key = lists:nth(N, List),
- Pid = S#state.collector_pid,
- Fun = fun create_contents_window/2,
- case et_collector:iterate(Pid, Key, -1) of
- Prev when Prev == Key ->
- et_collector:iterate(Pid, first, 1, Fun, S2);
- Prev ->
- et_collector:iterate(Pid, Prev, 1, Fun, S2)
- end
- end,
- noreply(S3);
-handle_info({gs, _Obj, buttonrelease, _, [_Button, X, Y | _]}, S) ->
- S2 =
- case y_to_n(Y, S) of
- actor ->
- %% Actor click
- case S#state.actors of
- [] ->
- S;
- Actors ->
- N = x_to_n(X, S),
- New = lists:nth(N, S#state.actors),
- Old = S#state.selected_actor,
- case New#actor.name == Old#actor.name of
- true ->
- A = S#state.selected_actor,
- toggle_search_for_actor(A#actor.name, S);
- false ->
- move_actor(Old, New, Actors, S)
- end
- end;
- {event, _N} ->
- %% Event click ignored
- S
- end,
- noreply(S2);
-handle_info({gs, _Obj, keypress, _, [KeySym, _Keycode, _Shift, _Control | _]} = Key, S) ->
- case KeySym of
- 'c' ->
- close_all_others(S);
- 'C' ->
- close_all(S);
- 'Up' ->
- S2 = scroll_up(S),
- noreply(S2);
- 'Down' ->
- S2 = scroll_down(S),
- noreply(S2);
- 'f' ->
- S2 = scroll_first(S),
- noreply(S2);
- 'p' ->
- S2 = scroll_prev(S),
- noreply(S2);
- 'Prior' ->
- S2 = scroll_prev(S),
- noreply(S2);
- 'n' ->
- S2 = scroll_next(S),
- noreply(S2);
- 'Next' ->
- S2 = scroll_next(S),
- noreply(S2);
- 'l' ->
- S2 = scroll_last(S),
- noreply(S2);
- 'r' ->
- S2 = refresh_main_window(S),
- noreply(S2);
- 'F' ->
- et_collector:multicast(S#state.collector_pid, first),
- noreply(S);
- 'P' ->
- et_collector:multicast(S#state.collector_pid, prev),
- noreply(S);
- 'N' ->
- et_collector:multicast(S#state.collector_pid, next),
- noreply(S);
- 'L' ->
- et_collector:multicast(S#state.collector_pid, last),
- noreply(S);
- 'R' ->
- et_collector:multicast(S#state.collector_pid, refresh),
- noreply(S);
-
- 'a' ->
- S2 = S#state{display_mode = all},
- S3 = refresh_main_window(S2),
- noreply(S3);
-
- 'equal' ->
- Scale = S#state.scale,
- Actors = [A#actor.name || A <- S#state.actors],
- open_viewer(Scale, S#state.active_filter, Actors, S),
- noreply(S);
- 'plus' ->
- Scale = S#state.scale + 1,
- Actors = [A#actor.name || A <- S#state.actors],
- open_viewer(Scale, S#state.active_filter, Actors, S),
- noreply(S);
- 'minus' ->
- case S#state.scale of
- 1 ->
- gs:config(S#state.canvas, beep);
- Scale ->
- Actors = [A#actor.name || A <- S#state.actors],
- open_viewer(Scale - 1, S#state.active_filter, Actors, S)
- end,
- noreply(S);
- 0 ->
- case lists:keysearch(collector, #filter.name, S#state.filters) of
- {value, F} when record(F, filter) ->
- open_viewer(S#state.scale, F#filter.name, [?unknown], S);
- false ->
- gs:config(S#state.canvas, beep)
- end,
- noreply(S);
- Int when integer(Int), Int > 0, Int =< 9 ->
- case catch lists:nth(Int, S#state.filters) of
- F when record(F, filter) ->
- open_viewer(S#state.scale, F#filter.name, [?unknown], S);
- {'EXIT', _} ->
- gs:config(S#state.canvas, beep)
- end,
- noreply(S);
-
- 'Shift_L' ->
- noreply(S);
- 'Shift_R' ->
- noreply(S);
- 'Caps_Lock' ->
- noreply(S);
-
- _ ->
- click_error(Key, S),
- noreply(S)
- end;
-handle_info({gs, _Obj,configure, [], [W, H | _]}, S) ->
- gs:config(S#state.packer, [{width, W}, {height, H}]),
- S2 = S#state{width = W, height = H},
- noreply(S2);
-handle_info(timeout, S) ->
- Try =
- case S#state.display_mode of
- {search_actors, reverse, _, _} ->
- -10;
- _ ->
- 10
- end,
- if
- S#state.is_suspended == true ->
- {noreply, S, infinity};
- S#state.max_events == infinity ->
- display_more_events(Try, S);
- true ->
- Needed = S#state.max_events - queue_length(S#state.events),
- if
- Needed =< 0 -> {noreply, S, infinity};
- Needed > 10 -> display_more_events(Try, S);
- Needed =< 10 -> display_more_events(Needed, S)
- end
- end;
-
-handle_info({'EXIT', Pid, Reason}, S) ->
- if
- Pid == S#state.collector_pid ->
- unlink(Pid),
- gs:destroy(S#state.win),
- {stop, Reason, S};
- Pid == S#state.parent_pid ->
- unlink(Pid),
- gs:destroy(S#state.win),
- {stop, Reason, S};
- true ->
- noreply(S)
- end;
-handle_info(Info, S) ->
- ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
- [?MODULE, self(), Info, S]),
- noreply(S).
-
-%%----------------------------------------------------------------------
-%% Func: terminate/2
-%% Purpose: Shutdown the server
-%% Returns: any (ignored by gen_server)
-%%----------------------------------------------------------------------
-
-terminate(_Reason, _S) ->
- ignore.
-
-%%----------------------------------------------------------------------
-%% Func: code_change/3
-%% Purpose: Convert process state when code is changed
-%% Returns: {ok, NewState}
-%%----------------------------------------------------------------------
-
-code_change(_OldVsn, S, _Extra) ->
- {ok, S}.
-
-%%%----------------------------------------------------------------------
-%%% Handle suspend/resume
-%%%----------------------------------------------------------------------
-
-reply(Reply, S) ->
- case queue_length(S#state.events) of
- _ when S#state.is_suspended == true ->
- {reply, Reply, S, infinity};
- _ when S#state.max_events == infinity ->
- {reply, Reply, S, 500};
- N when N >= S#state.max_events ->
- {reply, Reply, S, infinity};
- _ ->
- {reply, Reply, S, 0}
- end.
-
-noreply(S) ->
- case queue_length(S#state.events) of
- _ when S#state.is_suspended == true ->
- {noreply, S, infinity};
- _ when S#state.max_events == infinity ->
- {noreply, S, 500};
- N when N >= S#state.max_events ->
- {noreply, S, infinity};
- _ ->
- {noreply, S, 0}
- end.
-
-do_suspend(S) ->
- config_suspend(S#state{is_suspended = true}).
-
-do_resume(S) ->
- config_suspend(S#state{is_suspended = false}).
-
-config_suspend(S) ->
- Suspended = S#state.is_suspended,
- gs:config(refresh, [{enable, not Suspended}]),
- gs:config(refresh_all, [{enable, not Suspended}]),
- gs:config(clear_all, [{enable, not Suspended}]),
- S.
-
-refresh_main_window(S) ->
- Pid = S#state.collector_pid,
- Key = S#state.first_event,
- case et_collector:iterate(Pid, Key, -1) of
- Prev when Prev == Key ->
- scroll_first(S);
- _Prev ->
- S2 = S#state{last_event = S#state.first_event},
- clear_canvas(S2)
- end.
-
-scroll_first(S) ->
- S2 = S#state{first_event = first, last_event = first},
- clear_canvas(S2).
-
-scroll_prev(S) ->
- Try =
- case S#state.max_events of
- infinity -> -10;
- Max -> -Max
- end,
- Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, Try),
- S2 = S#state{first_event = Key, last_event = Key},
- clear_canvas(S2).
-
-scroll_next(S) ->
- S2 = S#state{first_event = S#state.last_event},
- clear_canvas(S2).
-
-scroll_up(S) ->
- Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, -5),
- S2 = S#state{first_event = Key, last_event = Key},
- clear_canvas(S2).
-
-scroll_down(S) ->
- Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, 5),
- S2 = S#state{first_event = Key, last_event = Key},
- clear_canvas(S2).
-
-scroll_last(S) ->
- S2 = S#state{first_event = last, last_event = last},
- clear_canvas(S2).
-
-change_display_mode(Mode, S) ->
- case Mode of
- all ->
- S2 = S#state{display_mode = Mode},
- refresh_main_window(S2);
- {search_actors, _Dir, _Key, []} ->
- S2 = S#state{display_mode = all},
- refresh_main_window(S2);
- {search_actors, _Dir, Key, Actors} when list(Actors) ->
- Pid = S#state.collector_pid,
- Prev = et_collector:iterate(Pid, Key, -1),
- S2 = S#state{first_event = Prev,
- last_event = Prev,
- display_mode = Mode},
- clear_canvas(S2)
- end.
-
-close_all(S) ->
- et_collector:multicast(S#state.collector_pid, close),
- timer:sleep(timer:seconds(1)),
- spawn(et_collector, stop, [S#state.collector_pid]),
- gs:destroy(S#state.win),
- {stop, shutdown, S}.
-
-close_all_others(S) ->
- Fun =
- fun({{subscriber, Pid}, _}) ->
- if
- Pid == self() ->
- ignore;
- true ->
- unlink(Pid),
- Pid ! {et, close}
- end
- end,
- All = et_collector:dict_match(S#state.collector_pid,
- {{subscriber, '_'}, '_'}),
- lists:foreach(Fun, All),
- noreply(S).
-
-click_error(Click, S) ->
- gs:config(S#state.canvas, beep),
- io:format("~p: ignored: ~p~n", [?MODULE, Click]).
-
-%%%----------------------------------------------------------------------
-%%% Clone viewer
-%%%----------------------------------------------------------------------
-open_viewer(Scale, FilterName, Actors, S) ->
- Filters = [{dict_insert, {filter, F#filter.name}, F#filter.function}
- || F <- S#state.filters],
- Options =
- [{parent_pid, S#state.parent_pid},
- {title, S#state.title},
- {collector_pid, S#state.collector_pid},
- {is_suspended, S#state.is_suspended},
- {detail_level, S#state.detail_level},
- {active_filter, FilterName},
- {event_order, S#state.event_order},
- {first_event, S#state.first_event},
- {max_events, S#state.max_events},
- {max_actors, S#state.max_actors},
- {hide_actions, S#state.hide_actions},
- {hide_unknown, S#state.hide_unknown},
- {is_suspended, S#state.is_suspended},
- {actors, Actors},
- {scale, Scale},
- {width, S#state.width},
- {height, S#state.height} | Filters],
- case start_link(Options) of
- {ok, ViewerPid} ->
- unlink(ViewerPid),
- ok;
- {error, Reason} ->
- ok = error_logger:format("~p: Failed to start a new window: ~p~n",
- [?MODULE, Reason])
- end.
-
-%%%----------------------------------------------------------------------
-%%% Handle graphics
-%%%----------------------------------------------------------------------
-
-create_main_window(S) ->
- Font = select_font(S#state.scale),
- GS = gs:start(),
- Name = name_to_string(S#state.active_filter),
- Title = case S#state.title of
- undefined -> atom_to_list(?MODULE);
- Explicit -> name_to_string(Explicit)
- end,
- WinOpt = [{title, Title ++ " (filter: " ++ Name ++ ")"},
- {configure, true},
- {width, S#state.width},
- {height, S#state.height}],
- Win = gs:window(GS, WinOpt),
- Bar = gs:menubar(Win, []),
-
- create_file_menu(Bar),
- create_viewer_menu(Bar),
- create_collector_menu(Bar),
- gs:menubutton(filter_button, Bar, [{label, {text, "Filter"}}]),
- create_filter_menu(S#state.active_filter, S#state.filters),
- create_help_menu(Bar),
-
- config_suspend(S),
-
- PackerOpt = [{packer_x, [{fixed, 5}, {fixed, 40}, {fixed, 40},
- {stretch, 1}, {fixed, 5}]},
- {packer_y, [{fixed, 30}, {fixed, 30},
- {stretch, 1}, {fixed, 30}]},
- {x, 0}, {y, 30}],
- Packer = gs:frame(Win, PackerOpt),
- gs:checkbutton(suspended, Packer, [{label,{text,"Freeze"}},
- {x, 10}, {y, 0},
- {width, 120}, {align, w},
- {select, S#state.is_suspended}]),
- gs:checkbutton(hide_actions, Packer, [{label,{text,"Hide From=To"}},
- {x, 10}, {y, 20},
- {width, 120}, {align, w},
- {select, S#state.hide_actions}]),
- gs:checkbutton(hide_unknown, Packer, [{label,{text,"Hide Unknown"}},
- {x, 10}, {y, 40},
- {width, 120}, {align, w},
- {select, S#state.hide_unknown}]),
- gs:scale(Packer, [{text,"Detail Level"},
- {range, {?detail_level_min, ?detail_level_max}},
- {orient, horizontal},
- {x, 150}, {y, 0}, {height, 65}, {width, 200},
- {pos, S#state.detail_level}, {data, detail_level}]),
- CanvasW = calc_canvas_width(S),
- CanvasH = calc_canvas_height(S),
- CanOpt = [{pack_xy, {{2, 4}, 3}}, {vscroll, right}, {hscroll, bottom},
- {scrollregion, {2, 2, CanvasW, CanvasH}}],
- Canvas = gs:canvas(Packer, CanOpt),
- gs:config(Canvas, [{buttonpress, true}, {buttonrelease, true}]),
- gs:config(Packer, [{width, S#state.width}, {height, S#state.height}]),
- gs:config(Win, [{map, true}, {keypress, true}]),
- S2 = S#state{title = Title,
- win = Win, font = Font, packer = Packer,
- canvas_width = CanvasW, canvas_height = CanvasH,
- canvas = Canvas,
- y_pos = ?initial_y * S#state.scale},
- draw_all_actors(S2).
-
-select_font(Scale) when integer(Scale) ->
- case Scale of
- 1 -> {courier, 7};
- 2 -> {courier, 10};
- 3 -> {courier, 12};
- 4 -> {courier, 14};
- S -> {courier, S * 4}
- end.
-
-create_file_menu(Bar) ->
- Button = gs:menubutton(Bar, [{label, {text, "File"}}]),
- Menu = gs:menu(Button, []),
- gs:menuitem(close_all, Menu, [{label, {text, "Close Collector and all Viewers (C) "}}]),
- gs:menuitem(close_all_others, Menu, [{label, {text, "Close other Viewers, but keep Collector (c)"}}]),
- gs:menuitem(close, Menu, [{label, {text, "Close this Viewer, but keep Collector"}}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
-
- gs:menuitem(clear_all, Menu, [{label, {text, "Clear Collector"}}]),
- gs:menuitem(load_all, Menu, [{label, {text, "Load Collector from the file \"et_viewer.log\""}}]),
- gs:menuitem(save_all, Menu, [{label, {text, "Save Collector to the file \"et_viewer.log\""}}]).
-
-create_viewer_menu(Bar) ->
- Button = gs:menubutton(Bar, [{label, {text, "Viewer"}}]),
- Menu = gs:menu(Button, []),
- gs:menuitem(Menu, [{label, {text, "Scroll this Viewer"}}, {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(first, Menu, [{label, {text, "First (f)"}}]),
- gs:menuitem(prev, Menu, [{label, {text, "Prev (p)"}}]),
- gs:menuitem(next, Menu, [{label, {text, "Next (n)"}}]),
- gs:menuitem(last, Menu, [{label, {text, "Last (l)"}}]),
- gs:menuitem(refresh, Menu, [{label, {text, "Refresh (r)"}}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(up, Menu, [{label, {text, "Up 5 (Up)"}}]),
- gs:menuitem(down, Menu, [{label, {text, "Down 5 (Down)"}}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(Menu, [{label, {text, "Search in this Viewer"}}, {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem({mode, all}, Menu, [{label, {text, "Abort search. Display all (a)"}}]).
-
-create_collector_menu(Bar) ->
- Button = gs:menubutton(Bar, [{label, {text, "Collector"}}]),
- Menu = gs:menu(Button, []),
- gs:menuitem(Menu, [{label, {text, "Scroll all Viewers"}}, {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(first_all, Menu, [{label, {text, "First (F)"}}]),
- gs:menuitem(prev_all, Menu, [{label, {text, "Prev (P)"}}]),
- gs:menuitem(next_all, Menu, [{label, {text, "Next (N)"}}]),
- gs:menuitem(last_all, Menu, [{label, {text, "Last (L)"}}]),
- gs:menuitem(refresh_all, Menu, [{label, {text, "Refresh (R)"}}]).
-
-create_filter_menu(ActiveFilterName, Filters) ->
- Menu = gs:menu(filter_menu, filter_button, []),
- Item = fun(F, N) when F#filter.name == collector ->
- Label = lists:concat([pad_string(F#filter.name, 20), "(0)"]),
- gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
- N + 1;
- (F, N) ->
- Label = lists:concat([pad_string(F#filter.name, 20), "(", N, ")"]),
- gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
- N + 1
- end,
- gs:menuitem(Menu, [{label, {text, "Same Filter New Scale"}}, {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- {value, Filter} = lists:keysearch(ActiveFilterName, #filter.name, Filters),
- Same = lists:concat([pad_string(ActiveFilterName, 20), "(=)"]),
- Larger = lists:concat([pad_string(ActiveFilterName, 20), "(+)"]),
- Smaller = lists:concat([pad_string(ActiveFilterName, 20), "(-)"]),
- gs:menuitem(Menu, [{label, {text, Same}}, {data, Filter}]),
- gs:menuitem(Menu, [{label, {text, Smaller}}, {data, Filter}]),
- gs:menuitem(Menu, [{label, {text, Larger}}, {data, Filter}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(Menu, [{label, {text, "New Filter Same Scale"}}, {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- lists:foldl(Item, 1, Filters).
-
-create_help_menu(Bar) ->
- Button = gs:menubutton(Bar, [{label, {text, "Help"}}]),
- Menu = gs:menu(Button, []),
- gs:menuitem(Menu, [{label, {text, "Display details of an event"}},
- {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{label, {text, " Single click on the name tag or the arrow (Mouse-1)"}},
- {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(Menu, [{label, {text, "Toggle actor search"}},
- {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{label, {text, " Single click on the name tag (Mouse-1)"}},
- {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(Menu, [{label, {text, "Move actor"}},
- {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{label, {text, " se drag and drop on name tag (Mouse-1)"}},
- {enable,false}]).
-
-clear_canvas(S) ->
- gs:destroy(S#state.canvas),
- CanvasW = calc_canvas_width(S),
- CanvasH = calc_canvas_height(S),
- CanOpt = [{pack_xy, {{2, 4}, 3}}, {vscroll, right}, {hscroll, bottom},
- {scrollregion, {2, 2, CanvasW, CanvasH}}],
- Canvas = gs:canvas(S#state.packer, CanOpt),
- gs:config(S#state.packer, [{width, S#state.width}, {height, S#state.height}]),
- gs:config(Canvas, [{buttonpress, true}, {buttonrelease, true}]),
- S2 = S#state{refresh_needed = false,
- y_pos = ?initial_y * S#state.scale,
- canvas = Canvas,
- canvas_width = CanvasW,
- canvas_height = CanvasH,
- events = queue_new()},
- draw_all_actors(S2).
-
-calc_canvas_width(S) ->
- Min = calc_min_actors(S),
- CanvasW = ((2 * ?initial_x) + (Min * ?incr_x)) * S#state.scale,
- lists:max([CanvasW, S#state.width - (15 * S#state.scale), S#state.canvas_width]).
-
-calc_canvas_height(S) ->
- Min = calc_min_events(S),
- CanvasH = ((2 * ?initial_y) + (Min * ?incr_y)) * S#state.scale,
- lists:max([CanvasH, S#state.height - (4 * 30), S#state.canvas_height]).
-
-calc_min_actors(S) ->
- Max = S#state.max_actors,
- N = length(S#state.actors),
- if
- Max == infinity ->
- N * 2;
- Max < N ->
- N;
- true ->
- Max
- end.
-
-calc_min_events(S) ->
- Max = S#state.max_events,
- N = queue_length(S#state.events),
- if
- Max == infinity ->
- N * 2;
- Max < N ->
- N;
- true ->
- Max
- end.
-
-display_more_events(Try, S) ->
- Name = S#state.active_filter,
- {value, F} = lists:keysearch(Name, #filter.name, S#state.filters),
- FilterFun = F#filter.function,
- Fun = fun(Event, State) ->
- case catch FilterFun(Event) of
- true ->
- State2 = ensure_key(Event, State),
- opt_display_event(Event, State2);
- {true, Event2} ->
- State2 = ensure_key(Event2, State),
- opt_display_event(Event2, State2);
- false ->
- ensure_key(Event, State);
- Bad ->
- Contents = {bad_filter, Name, Bad, Event},
- Event2 = Event#event{contents = Contents,
- from = bad_filter,
- to = bad_filter},
- State2 = ensure_key(Event2, State),
- opt_display_event(Event2, State2)
- end
- end,
- Pid = S#state.collector_pid,
- S2 = et_collector:iterate(Pid, S#state.last_event, Try, Fun, S),
- case queue_length(S2#state.events) - queue_length(S#state.events) of
- Diff when Diff == Try ->
- %% Got as much as requested, look for more
- %% io:format("Done: ~p~n", [{Try, Diff}]),
- {noreply, S2, 0};
- _Diff when S2#state.first_event == S#state.first_event,
- S2#state.last_event == S#state.last_event ->
- %% Got lesser than requested, wait a while before looking for more
- %% io:format("More: ~p~n", [{Try, Diff}]),
- {noreply, S2, 500};
- _Diff ->
- %% Got lesser than requested, look for more
- %% io:format("More2: ~p~n", [{Try, Diff}]),
- {noreply, S2, 0}
- end.
-
-ensure_key(E, S) when record(E, event), record(S, state) ->
- Key = et_collector:make_key(S#state.event_order, E),
- case S#state.first_event of
- first ->
- S#state{first_event = Key, last_event = Key};
- last ->
- S#state{first_event = Key, last_event = Key};
- _ ->
- S#state{last_event = Key}
- end.
-
-opt_display_event(E, S) ->
- case S#state.display_mode of
- all ->
- display_event(E, S);
- {search_actors, _Dir, _FirstKey, Actors} ->
- %% Key = S#state.last_event,
- From = select_actor_name(E#event.from, S),
- case lists:member(From, Actors) of
- true ->
- display_event(E, S);
- false ->
- To = select_actor_name(E#event.to, S),
- case lists:member(To, Actors) of
- true ->
- display_event(E, S);
- false ->
- S
- end
- end
- end.
-
-select_actor_name(Name, S) ->
- case lists:keymember(Name, #actor.name, S#state.actors) of
- true -> Name;
- false -> ?unknown
- end.
-
-display_event(E, S) when E#event.detail_level < S#state.detail_level ->
- {FromRefresh, From} = ensure_actor(E#event.from, S),
- {FromName, FromPos, S2} = From,
- {ToRefresh, To} = ensure_actor(E#event.to, S2),
- {ToName, ToPos, S3} = To,
- if
- FromRefresh /= false, ToRefresh /= false ->
- Key = S#state.last_event,
- refresh_beep(S),
- S3#state{refresh_needed = true,
- events = queue_in(Key, S3#state.events)};
- FromName == ToName ->
- case S#state.hide_actions of
- true ->
- S3;
- false ->
- Label = name_to_string(E#event.label),
- draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S3)
- end;
- true ->
- Label = name_to_string(E#event.label),
- draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S3)
- end;
-display_event(_, S) ->
- S.
-
-draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S) ->
- Key = S#state.last_event,
- case S#state.y_pos + (?incr_y * S#state.scale) of
- _ when S#state.hide_unknown == true, FromName == ?unknown ->
- S;
- _ when S#state.hide_unknown == true, ToName == ?unknown ->
- S;
- Y when Y > S#state.canvas_height ->
- refresh_beep(S),
- S#state{refresh_needed = true,
- events = queue_in(Key, S#state.events)};
- Y ->
- S2 = S#state{y_pos = Y, events = queue_in(Key, S#state.events)},
- S3 = draw_arrow(FromPos, ToPos, S2),
- draw_label(Label, FromName, ToName, FromPos, ToPos, S3)
- end.
-
-refresh_beep(S) ->
- case S#state.refresh_needed of
- false ->
- gs:config(S#state.canvas, beep),
- gs:config(S#state.canvas, beep),
- gs:config(S#state.canvas, beep);
- true ->
- ignore
- end.
-
-draw_arrow(Pos, Pos, S) ->
- S;
-draw_arrow(FromPos, ToPos, S) ->
- Y = S#state.y_pos,
- CanOpts = [{coords, [{FromPos , Y}, {ToPos, Y}]},
- {arrow, last},{width, 1}, {fg, black}],
- gs:line(S#state.canvas, CanOpts),
- S.
-
-draw_label(Label, FromName, ToName, FromPos, ToPos, S) ->
- Colour =
- if
- FromName == ?unknown,
- ToName == ?unknown -> blue; %turquoise;
- FromName == ?unknown -> orange;
- ToName == ?unknown -> orange;
- FromPos == ToPos -> blue;
- true -> red
- end,
- Scale = S#state.scale,
- X = lists:min([FromPos, ToPos]) + (6 * Scale),
- Y = S#state.y_pos,
- write_text(Label, X, Y, Colour, S),
- S.
-
-draw_all_actors(State) ->
- Scale = State#state.scale,
- Fun = fun(A, X) ->
- draw_actor(A, X, State),
- X + (?incr_x * Scale)
- end,
- lists:foldl(Fun, ?initial_x * Scale, State#state.actors),
- State.
-
-%% Returns: {NeedsRefreshBool, {ActorPos, NewsS, NewActors}}
-ensure_actor(Name, S) ->
- do_ensure_actor(Name, S, S#state.actors, 0).
-
-do_ensure_actor(Name, S, [H | _], N) when H#actor.name == Name ->
- Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
- {false, {Name, Pos, S}};
-do_ensure_actor(Name, S, [_ | T], N) ->
- do_ensure_actor(Name, S, T, N + 1);
-do_ensure_actor(Name, S, [], N) ->
- %% A brand new actor, let's see if it does fit
- Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
- MaxActors = S#state.max_actors,
- if
- integer(MaxActors), N > MaxActors ->
- %% Failed on max_actors limit, put into unknown
- %% Assume that unknown always is in actor list
- ensure_actor(?unknown, S);
- Pos > (S#state.canvas_width - ((?initial_x - 15) * S#state.scale)) ->
- %% New actor does not fit in canvas, refresh needed
- A = create_actor(Name),
- draw_actor(A, Pos, S),
- {true, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}};
- true ->
- %% New actor fits in canvas. Draw the new actor.
- A = create_actor(Name),
- draw_actor(A, Pos, S),
- {false, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}}
- end.
-
-draw_actor(A, LineX, S) ->
- Scale = S#state.scale,
- TextX = LineX - (5 * Scale),
- TextY = ?initial_y * Scale,
- LineTopY = TextY + ((?incr_y / 2) * Scale),
- LineBotY = S#state.canvas_height - ((?incr_y / 2) * Scale),
- Colour = case A#actor.name of
- ?unknown -> orange;
- _ -> red
- end,
- write_text(A#actor.string, TextX, TextY, Colour, S),
- LineOpt = [{coords, [{LineX, LineTopY}, {LineX, LineBotY}]},
- {width, 1}, {fg, Colour}],
- gs:line(S#state.canvas, LineOpt).
-
-toggle_search_for_actor(ActorName,S) ->
- case S#state.display_mode of
- all ->
- io:format("~p: search for: ~p ++ ~p~n", [?MODULE, [], [ActorName]]),
- %% Search for this actor
- Key = S#state.first_event,
- Actors = [ActorName],
- Mode = {search_actors, forward, Key, Actors},
- change_display_mode(Mode, S);
- {search_actors, Dir, Key, Actors}->
- Actors2 =
- case lists:member(ActorName, Actors) of
- true ->
- io:format("~p: search for: ~p -- ~p~n", [?MODULE, Actors, [ActorName]]),
- %% Remove actor from search list
- Actors -- [ActorName];
- false ->
- io:format("~p: search for: ~p ++ ~p~n", [?MODULE, Actors, [ActorName]]),
- %% Add actor from search list
- [ActorName | Actors]
- end,
- Mode2 = {search_actors, Dir, Key, Actors2},
- change_display_mode(Mode2, S)
- end.
-
-move_actor(From, To, Actors, S) ->
- Pos = #actor.name,
- ToName = To#actor.name,
- FromName = From#actor.name,
- ToIx = actor_index(ToName, Pos, Actors),
- FromIx = actor_index(FromName, Pos, Actors),
- if
- FromIx /= 0, ToIx /= 0, ToIx > FromIx ->
- Actors2 = lists:keydelete(FromName, Pos, Actors),
- Actors3 = insert_actor_after(From, To, Actors2),
- S2 = S#state{actors = Actors3},
- refresh_main_window(S2);
- FromIx /= 0, ToIx /= 0 ->
- Actors2 = lists:keydelete(FromName, Pos, Actors),
- Actors3 = insert_actor_before(From, To, Actors2),
- S2 = S#state{actors = Actors3},
- refresh_main_window(S2);
- true ->
- %% Ignore
- S
- end.
-
-insert_actor_after(From, To, [H | T]) ->
- case To#actor.name == H#actor.name of
- true -> [H, From | T];
- false -> [H | insert_actor_after(From, To, T)]
- end;
-insert_actor_after(_From, _To, []) ->
- [].
-
-insert_actor_before(From, To, [H | T]) ->
- case To#actor.name == H#actor.name of
- true -> [From, H | T];
- false -> [H | insert_actor_before(From, To, T)]
- end;
-insert_actor_before(_From, _To, []) ->
- [].
-
-actor_index(_Key, _Pos, []) ->
- 0;
-actor_index(Key, Pos, [H | T]) ->
- case Key == element(Pos, H) of
- false -> actor_index(Key, Pos, T) + 1;
- true -> 1
- end.
-
-y_to_n(Y, S) ->
- Y2 = ((Y / S#state.scale) - ?initial_y + (?incr_y / 2)),
- N = round(Y2 / ?incr_y - 0.2),
- MaxN = queue_length(S#state.events),
- if
- N =< 0 -> actor;
- N > MaxN -> actor;
- true -> {event, N}
- end.
-
-x_to_n(X, S) ->
- Scale = S#state.scale,
- Len = length(S#state.actors),
- X2 = X - (?initial_x * Scale),
- N = X2 / (?incr_x * Scale),
- N2 = trunc(N + 1.5),
- if
- N2 > Len -> Len;
- N2 < 1 -> 1;
- true -> N2
- end.
-
-write_text(Text, X, Y, Colour, S) ->
- Opt = [{coords, [{X, Y - (?incr_y * S#state.scale / 2)}]},
- {font, S#state.font}, {fg, Colour}, {text, Text}],
- gs:text(S#state.canvas, Opt).
-
-create_contents_window(Event, S) ->
- Options = [{viewer_pid, self()},
- {event, Event},
- {event_order, S#state.event_order},
- {active_filter, S#state.active_filter}
- | S#state.filters],
- case et_contents_viewer:start_link(Options) of
- {ok, _Pid} ->
- S;
- {error, Reason} ->
- ok = error_logger:format("~p(~p): create_contents_window(~p) ->~n ~p~n",
- [?MODULE, self(), Options, Reason]),
- S
- end.
-
-%%%----------------------------------------------------------------------
-%%% String padding of actors
-%%%----------------------------------------------------------------------
-
-create_actor(Name) ->
- String = name_to_string(Name),
- PaddedString = pad_string(String, 8),
- #actor{name = Name, string = PaddedString}.
-
-name_to_string(Name) ->
- case catch io_lib:format("~s", [Name]) of
- {'EXIT', _} -> lists:flatten(io_lib:format("~w", [Name]));
- GoodString -> lists:flatten(GoodString)
- end.
-
-pad_string(Atom, MinLen) when atom(Atom) ->
- pad_string(atom_to_list(Atom), MinLen);
-pad_string(String, MinLen) when integer(MinLen), MinLen >= 0 ->
- Len = length(String),
- case Len >= MinLen of
- true ->
- String;
- false ->
- String ++ lists:duplicate(MinLen - Len, $ )
- end.
-
-%%%----------------------------------------------------------------------
-%%% Queue management
-%%%----------------------------------------------------------------------
-
-queue_new() ->
- {0, [], []}.
-
-queue_in(X, {Size, In, Out}) ->
- {Size + 1, [X | In], Out}.
-
-%% queue_out(Q) ->
-%% case Q of
-%% {Size, In, [H | Out]} -> {{value, H}, {Size - 1, In, Out}};
-%% {Size, [], []} -> {empty, {Size, [], []}};
-%% {Size, In, _} -> queue_out({Size, [], lists:reverse(In)})
-%% end.
-
-queue_to_list({_Size, [], Out}) ->
- Out;
-queue_to_list({_Size, In, Out}) ->
- Out ++ lists:reverse(In).
-
-queue_length({Size, _In, _Out}) ->
- Size.
+call(ViewerPid, Request) ->
+ gen_server:call(ViewerPid, Request, infinity).
-list_to_queue(List) when list(List) ->
- {length(List), [], List}.
diff --git a/lib/et/src/et_wx_contents_viewer.erl b/lib/et/src/et_wx_contents_viewer.erl
new file mode 100644
index 0000000000..8a8d9ef1ee
--- /dev/null
+++ b/lib/et/src/et_wx_contents_viewer.erl
@@ -0,0 +1,700 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Displays details of a trace event
+%%----------------------------------------------------------------------
+
+-module(et_wx_contents_viewer).
+
+-behaviour(wx_object).
+
+%% External exports
+-export([start_link/1,
+ stop/1]).
+
+%% gen_server callbacks
+-export([init/1, terminate/2, code_change/3,
+ handle_call/3, handle_cast/2, handle_info/2,
+ handle_event/2]).
+
+-include("../include/et.hrl").
+-include("et_internal.hrl").
+-include_lib("wx/include/wx.hrl").
+
+-record(state, {parent_pid, % Pid of parent process
+ viewer_pid, % Pid of viewer process
+ event_order, % Field to be used as primary key
+ event, % The original event
+ filtered_event, % Event processed by active filter
+ active_filter, % Name of the active filter
+ filters, % List of possible filters
+ win, % GUI: Frame object
+ frame, % GUI: Frame object
+ panel, % GUI: Panel object
+ width, % GUI: Window width
+ height,
+ editor,
+ menu_data, % GUI: Window height
+ wx_debug, % GUI: WX debug level
+ trap_exit}). % trap_exit process flag
+
+%%%----------------------------------------------------------------------
+%%% Client side
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% start_link(Options) -> {ok, ContentsPid} | {error, Reason}
+%%
+%% Start a viewer for the event contents as window in GS
+%%
+%% Options = [option()]
+%%
+%% option() =
+%%
+%% {parent_pid, pid()} | % Pid of parent process
+%% {viewer_pid, pid()} | % Pid of viewer process
+%% {event_order, event_order()} | % Field to be used as primary key
+%% {active_filter, atom()} | % Name of the active filter
+%% {filter, atom(), fun()} % A named filter fun
+%%
+%% event_order() = 'trace_ts' | 'event_ts'
+%% ContentsPid = pid()
+%% Reason = term()
+%%----------------------------------------------------------------------
+
+start_link(Options) ->
+ case parse_opt(Options, default_state()) of
+ {ok, S} ->
+ try
+ WxRef = wx_object:start_link(?MODULE, [S], []),
+ Pid = wx_object:get_pid(WxRef),
+ if
+ S#state.parent_pid =/= self() ->
+ unlink(Pid);
+ true ->
+ ignore
+ end,
+ {ok, Pid}
+ catch
+ error:Reason ->
+ {error, {'EXIT', Reason, erlang:get_stacktrace()}}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+default_state() ->
+ #state{parent_pid = self(),
+ viewer_pid = undefined,
+ active_filter = ?DEFAULT_FILTER_NAME,
+ filters = [?DEFAULT_FILTER],
+ width = 600,
+ height = 300,
+ wx_debug = 0,
+ trap_exit = true}.
+
+parse_opt([], S) ->
+ Name = S#state.active_filter,
+ Filters = S#state.filters,
+ if
+ S#state.event =:= undefined ->
+ {error, {badarg, no_event}};
+ is_atom(Name) ->
+ case lists:keysearch(Name, #filter.name, Filters) of
+ {value, F} when is_record(F, filter) ->
+ {ok, S#state{active_filter = Name}};
+ false ->
+ {error, {badarg, {no_such_filter, Name, Filters}}}
+ end
+ end;
+parse_opt([H | T], S) ->
+ case H of
+ {parent_pid, ParentPid} when is_pid(ParentPid); ParentPid =:= undefined ->
+ parse_opt(T, S#state{parent_pid = ParentPid});
+ {viewer_pid, ViewerPid} when is_pid(ViewerPid) ->
+ parse_opt(T, S#state{viewer_pid = ViewerPid});
+ {wx_debug, Level} ->
+ parse_opt(T, S#state{wx_debug = Level});
+ {trap_exit, Bool} when Bool =:= true; Bool =:= false->
+ parse_opt(T, S#state{trap_exit = Bool});
+ {event_order, trace_ts} ->
+ parse_opt(T, S#state{event_order = trace_ts});
+ {event_order, event_ts} ->
+ parse_opt(T, S#state{event_order = event_ts});
+ {event, Event} when is_record(Event, event) ->
+ parse_opt(T, S#state{event = Event});
+ {active_filter, Name} when is_atom(Name) ->
+ parse_opt(T, S#state{active_filter = Name});
+ F when is_record(F, filter),
+ is_atom(F#filter.name),
+ is_function(F#filter.function) ->
+ Filters = lists:keydelete(F#filter.name, #filter.name, S#state.filters),
+ Filters2 = lists:keysort(#filter.name, [F | Filters]),
+ parse_opt(T, S#state{filters = Filters2});
+ {width, Width} when is_integer(Width), Width > 0 ->
+ parse_opt(T, S#state{width = Width});
+ {height, Height} when is_integer(Height), Height > 0 ->
+ parse_opt(T, S#state{height = Height});
+ Bad ->
+ {error, {bad_option, Bad}}
+ end;
+parse_opt(BadList, _S) ->
+ {error, {bad_option_list, BadList}}.
+
+%%----------------------------------------------------------------------
+%% stop(ContentsPid) -> ok
+%%
+%% Stops a contents viewer process
+%%
+%% ContentsPid = pid()
+%%----------------------------------------------------------------------
+
+stop(ContentsPid) when is_pid(ContentsPid) ->
+ Type = process,
+ MonitorRef = erlang:monitor(Type, ContentsPid),
+ ContentsPid ! {stop, self()},
+ receive
+ {'DOWN', MonitorRef, Type, ContentsPid, shutdown} ->
+ ok;
+ {'DOWN', MonitorRef, Type, ContentsPid, Reason} ->
+ {error, Reason}
+ end.
+
+%% call(Frame, Request) ->
+%% wx_object:call(Frame, Request, infinity).
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+
+init([S]) when is_record(S, state) ->
+ process_flag(trap_exit, S#state.trap_exit),
+ case S#state.parent_pid of
+ undefined -> ok;
+ ParentPid -> link(ParentPid)
+ end,
+ wx:debug(S#state.wx_debug),
+ S2 = create_window(S),
+ {S2#state.frame, S2}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_call(Request, From, S) ->
+ ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
+ [?MODULE, self(), Request, From, S]),
+ Reply = {error, {bad_request, Request}},
+ {reply, Reply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_cast(Msg, S) ->
+ ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
+ [?MODULE, self(), Msg, S]),
+ {noreply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_event/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_event(#wx{id = Id,
+ event = #wxCommand{type = command_menu_selected}},
+ S) ->
+ case proplists:get_value(Id, S#state.menu_data) of
+ undefined ->
+ ignore;
+ Data when is_record(Data, filter) ->
+ F = Data,
+ ChildState= S#state{active_filter = F#filter.name},
+ case wx_object:start_link(?MODULE, [ChildState], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid);
+ _ ->
+ ignore
+ end;
+ {hide, Actors} ->
+ send_viewer_event(S, {delete_actors, Actors});
+ {show, Actors} ->
+ send_viewer_event(S, {insert_actors, Actors});
+ {mode, Mode} ->
+ send_viewer_event(S, {mode, Mode});
+ Nyi ->
+ ok = error_logger:format("~p: click ~p ignored (nyi)~n",
+ [?MODULE, Nyi])
+ end,
+ case Id of
+ ?wxID_EXIT ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+ ?wxID_SAVE ->
+ Event = S#state.event,
+ TimeStamp =
+ case S#state.event_order of
+ trace_ts -> Event#event.trace_ts;
+ event_ts -> Event#event.event_ts
+ end,
+ FileName = lists:flatten(["et_contents_viewer_", now_to_string(TimeStamp), ".txt"]),
+ Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT,
+ Msg = "Select a file to the events to",
+ case select_file(S#state.frame, Msg, filename:absname(FileName), Style) of
+ {ok, FileName2} ->
+ Bin = list_to_binary(event_to_string(Event, S#state.event_order)),
+ file:write_file(FileName2, Bin);
+ cancel ->
+ ok
+ end,
+ {noreply, S};
+ ?wxID_PRINT ->
+ Html = wxHtmlEasyPrinting:new([{parentWindow, S#state.win}]),
+ Text = "<pre>" ++ wxTextCtrl:getValue(S#state.editor) ++ "</pre>",
+ wxHtmlEasyPrinting:previewText(Html, Text),
+ {noreply, S};
+ _ ->
+ {noreply, S}
+ end;
+handle_event(#wx{event = #wxKey{rawCode = KeyCode}}, S) ->
+ case KeyCode of
+ $c ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, normal, S};
+ $f ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ send_viewer_event(S, {delete_actors, [From]}),
+ {noreply, S};
+ $t ->
+ E = S#state.filtered_event,
+ To = E#event.to,
+ send_viewer_event(S, {delete_actors, [To]}),
+ {noreply, S};
+ $b ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ send_viewer_event(S, {delete_actors, [From, To]}),
+ {noreply, S};
+
+ $F ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ send_viewer_event(S, {insert_actors, [From]}),
+ {noreply, S};
+ $T ->
+ E = S#state.filtered_event,
+ To = E#event.to,
+ send_viewer_event(S, {insert_actors, [To]}),
+ {noreply, S};
+ $B ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ send_viewer_event(S, {insert_actors, [From, To]}),
+ {noreply, S};
+
+ $s ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ First = et_collector:make_key(S#state.event_order, E),
+ Mode = {search_actors, forward, First, [From, To]},
+ send_viewer_event(S, {mode, Mode}),
+ {noreply, S};
+ $r ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ First = et_collector:make_key(S#state.event_order, E),
+ Mode = {search_actors, reverse, First, [From, To]},
+ send_viewer_event(S, {mode, Mode}),
+ {noreply, S};
+ $a ->
+ send_viewer_event(S, {mode, all}),
+ {noreply, S};
+
+ $0 ->
+ case lists:keysearch(?DEFAULT_FILTER_NAME, #filter.name, S#state.filters) of
+ {value, F} when is_record(F, filter) ->
+ ChildState= S#state{active_filter = F#filter.name},
+ case wx_object:start_link(?MODULE, [ChildState], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid);
+ _ ->
+ ignore
+ end;
+ false ->
+ ignore
+ end,
+ {noreply, S};
+ Int when is_integer(Int), Int > $0, Int =< $9 ->
+ case catch lists:nth(Int-$0, S#state.filters) of
+ F when is_record(F, filter) ->
+ ChildState= S#state{active_filter = F#filter.name},
+ case wx_object:start_link(?MODULE, [ChildState], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid);
+ _ ->
+ ignore
+ end;
+ {'EXIT', _} ->
+ ignore
+ end,
+ {noreply, S};
+
+ _ ->
+ io:format("~p: ignored: ~p~n", [?MODULE, KeyCode]),
+ {noreply, S}
+ end;
+handle_event(#wx{event = #wxClose{}}, S) ->
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+handle_event(#wx{event = #wxSize{size = {W, H}}}, S) ->
+ S2 = S#state{width = W, height = H},
+ {noreply, S2};
+handle_event(Wx = #wx{}, S) ->
+ io:format("~p got an unexpected event: ~p\n", [self(), Wx]),
+ {noreply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_info({stop, _From}, S) ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+handle_info({'EXIT', Pid, Reason}, S) ->
+ if
+ Pid =:= S#state.parent_pid ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, Reason, S};
+ true ->
+ {noreply, S}
+ end;
+handle_info(Info, S) ->
+ ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
+ [?MODULE, self(), Info, S]),
+ {noreply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%----------------------------------------------------------------------
+
+terminate(_Reason, _S) ->
+ ignore.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Convert process state when code is changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+
+code_change(_OldVsn, S, _Extra) ->
+ {ok, S}.
+
+%%%----------------------------------------------------------------------
+%%% Handle graphics
+%%%----------------------------------------------------------------------
+
+opt_unlink(Pid) ->
+ if
+ Pid =:= undefined ->
+ ignore;
+ true ->
+ unlink(Pid)
+ end.
+
+create_window(S) ->
+ H = S#state.height,
+ W = S#state.width,
+ Name = S#state.active_filter,
+ Title = lists:concat([?MODULE, " (filter: ", Name, ")"]),
+ WinOpt = [{size, {W,H}}],
+ Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title, WinOpt),
+ wxFrame:createStatusBar(Frame),
+
+ Panel = wxPanel:new(Frame, []),
+ Bar = wxMenuBar:new(),
+ wxFrame:setMenuBar(Frame,Bar),
+ create_file_menu(Bar),
+ Editor = wxTextCtrl:new(Panel, ?wxID_ANY, [{style, 0
+ bor ?wxDEFAULT
+ bor ?wxTE_MULTILINE
+ bor ?wxTE_READONLY
+ bor ?wxTE_DONTWRAP}]),
+ Font = wxFont:new(10, ?wxFONTFAMILY_TELETYPE, ?wxNORMAL, ?wxNORMAL,[]),
+ TextAttr = wxTextAttr:new(?wxBLACK, [{font, Font}]),
+ wxTextCtrl:setDefaultStyle(Editor, TextAttr),
+ Sizer = wxBoxSizer:new(?wxHORIZONTAL),
+ wxSizer:add(Sizer, Editor, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ FilteredEvent = config_editor(Editor, S),
+ S2 = S#state{win = Frame, panel = Panel, filtered_event = FilteredEvent},
+ HideData = create_hide_menu(Bar, S2),
+ SearchData = create_search_menu(Bar, S2),
+ FilterData = create_filter_menu(Bar, S#state.filters),
+ wxFrame:connect(Frame, command_menu_selected, []),
+ wxFrame:connect(Frame, key_up),
+ wxFrame:connect(Frame, close_window, [{skip,true}]),
+ wxFrame:setFocus(Frame),
+ wxPanel:setSizer(Panel, Sizer),
+ wxFrame:show(Frame),
+ S2#state{menu_data = HideData++SearchData++FilterData, editor = Editor, frame = Frame}.
+
+menuitem(Menu, Id, Text, UserData) ->
+ Item = wxMenu:append(Menu, Id, Text),
+ {wxMenuItem:getId(Item), UserData}.
+
+create_file_menu(Bar) ->
+ Menu = wxMenu:new([]),
+ wxMenu:append(Menu, ?wxID_SAVE, "Save"),
+ wxMenu:append(Menu, ?wxID_PRINT,"Print"),
+ wxMenu:appendSeparator(Menu),
+ wxMenu:append(Menu, ?wxID_EXIT, "Close"),
+ wxMenuBar:append(Bar, Menu, "File").
+
+create_filter_menu(Bar, Filters) ->
+ Menu = wxMenu:new([]),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Select Filter"), [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Item = fun(F, {N,Acc}) when F#filter.name =:= ?DEFAULT_FILTER_NAME->
+ Label = lists:concat([pad_string(F#filter.name, 20, $\ , right), "(0)"]),
+ MenuItem = menuitem(Menu, ?wxID_ANY, Label, F),
+ {N + 1, [MenuItem|Acc]};
+ (F, {N, Acc}) ->
+ Name = F#filter.name,
+ Label = lists:concat([pad_string(Name, 20, $\ , right), "(", N, ")"]),
+ MenuItem = menuitem(Menu, ?wxID_ANY, Label, F),
+ {N + 1, [MenuItem|Acc]}
+ end,
+ Filters2 = lists:keysort(#filter.name, Filters),
+ {_,MenuData} = lists:foldl(Item, {1, []}, Filters2),
+ wxMenuBar:append(Bar, Menu, "Filters"),
+ MenuData.
+
+create_hide_menu(Bar, S) ->
+ Menu = wxMenu:new([]),
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ MenuData =
+ if
+ S#state.viewer_pid =:= undefined ->
+ ignore;
+ From =:= To ->
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Hide actor in Viewer "),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Hide = menuitem(Menu, ?wxID_ANY, "From=To (f|t|b)", {hide, [From]}),
+ wxMenu:appendSeparator(Menu),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Show actor in Viewer "),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Show = menuitem(Menu, ?wxID_ANY, "From=To (F|T|B)", {show, [From]}),
+ [Show,Hide];
+ true ->
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Hide actor in Viewer "),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Hide = [menuitem(Menu, ?wxID_ANY, "From (f)", {hide, [From]}),
+ menuitem(Menu, ?wxID_ANY, "To (t)", {hide, [To]}),
+ menuitem(Menu, ?wxID_ANY, "Both (b)", {hide, [From, To]})],
+ wxMenu:appendSeparator(Menu),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Show actor in Viewer "),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Show = [menuitem(Menu, ?wxID_ANY, "From (F)", {show, [From]}),
+ menuitem(Menu, ?wxID_ANY, "To (T)", {show, [To]}),
+ menuitem(Menu, ?wxID_ANY, "Both (B)", {show, [From, To]})],
+ Show++Hide
+ end,
+ wxMenuBar:append(Bar, Menu, "Hide"),
+ MenuData.
+
+create_search_menu(Bar, S) ->
+ Menu = wxMenu:new([]),
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Search in Viewer "),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ MenuData =
+ if
+ S#state.viewer_pid =:= undefined ->
+ [menuitem(Menu, ?wxID_ANY, "Abort search. Display all (a)", {mode, all})];
+ From =:= To ->
+ Key = et_collector:make_key(S#state.event_order, E),
+ ModeS = {search_actors, forward, Key, [From]},
+ ModeR = {search_actors, reverse, Key, [From]},
+ [menuitem(Menu, ?wxID_ANY, "Forward from this event (s)", {mode, ModeS}),
+ menuitem(Menu, ?wxID_ANY, "Reverse from this event (r)", {mode, ModeR}),
+ menuitem(Menu, ?wxID_ANY, "Abort search. Display all (a)", {mode, all})];
+ true ->
+ Key = et_collector:make_key(S#state.event_order, E),
+ ModeS = {search_actors, forward, Key, [From, To]},
+ ModeR = {search_actors, reverse, Key, [From, To]},
+ [menuitem(Menu, ?wxID_ANY, "Forward from this event (s)", {mode, ModeS}),
+ menuitem(Menu, ?wxID_ANY, "Reverse from this event (r)", {mode, ModeR}),
+ menuitem(Menu, ?wxID_ANY, "Abort search. Display all (a)", {mode, all})]
+ end,
+ wxMenuBar:append(Bar, Menu, "Search"),
+ MenuData.
+
+config_editor(Editor, S) ->
+ Event = S#state.event,
+ Name = S#state.active_filter,
+ {value, F} = lists:keysearch(Name, #filter.name, S#state.filters),
+ FilterFun = F#filter.function,
+ case catch FilterFun(Event) of
+ true ->
+ do_config_editor(Editor, Event, lightblue, S#state.event_order);
+ {true, Event2} when is_record(Event2, event) ->
+ do_config_editor(Editor, Event2, lightblue, S#state.event_order);
+ false ->
+ do_config_editor(Editor, Event, red, S#state.event_order);
+ Bad ->
+ Contents = {bad_filter, Name, Bad},
+ BadEvent = Event#event{contents = Contents},
+ do_config_editor(Editor, BadEvent, red, S#state.event_order)
+ end.
+
+do_config_editor(Editor, Event, _Colour, TsKey) ->
+ String = event_to_string(Event, TsKey),
+ wxTextCtrl:appendText(Editor, String),
+ Event.
+
+%%%----------------------------------------------------------------------
+%%% String handling
+%%%----------------------------------------------------------------------
+
+term_to_string(Term) ->
+ case catch io_lib:format("~s", [Term]) of
+ {'EXIT', _} -> io_lib:format("~p", [Term]);
+ GoodString -> GoodString
+ end.
+
+now_to_string({Mega, Sec, Micro} = Now)
+ when is_integer(Mega), is_integer(Sec), is_integer(Micro) ->
+ {{Y, Mo, D}, {H, Mi, S}} = calendar:now_to_universal_time(Now),
+ lists:concat([Y, "-",
+ pad_string(Mo, 2, $0, left), "-",
+ pad_string(D, 2, $0, left),
+ "T",
+ pad_string(H, 2, $0, left), ":",
+ pad_string(Mi, 2, $0, left), ":",
+ pad_string(S, 2, $0, left), ".",
+ Micro]);
+now_to_string(Other) ->
+ term_to_string(Other).
+
+event_to_string(Event, TsKey) ->
+ ReportedTs = Event#event.trace_ts,
+ ParsedTs = Event#event.event_ts,
+ Deep =
+ ["DETAIL LEVEL: ", term_to_string(Event#event.detail_level),
+ "\nLABEL: ", term_to_string(Event#event.label),
+ case Event#event.from =:= Event#event.to of
+ true ->
+ ["\nACTOR: ", term_to_string(Event#event.from)];
+ false ->
+ ["\nFROM: ", term_to_string(Event#event.from),
+ "\nTO: ", term_to_string(Event#event.to)]
+ end,
+ case ReportedTs =:= ParsedTs of
+ true ->
+ ["\nPARSED: ", now_to_string(ParsedTs)];
+ false ->
+ case TsKey of
+ trace_ts ->
+ ["\nTRACE_TS: ", now_to_string(ReportedTs),
+ "\nEVENT_TS: ", now_to_string(ParsedTs)];
+ event_ts ->
+ ["\nEVENT_TS: ", now_to_string(ParsedTs),
+ "\nTRACE_TS: ", now_to_string(ReportedTs)]
+ end
+ end,
+ "\nCONTENTS:\n\n", term_to_string(Event#event.contents)],
+ lists:flatten(Deep).
+
+pad_string(Int, MinLen, Char, Dir) when is_integer(Int) ->
+ pad_string(integer_to_list(Int), MinLen, Char, Dir);
+pad_string(Atom, MinLen, Char, Dir) when is_atom(Atom) ->
+ pad_string(atom_to_list(Atom), MinLen, Char, Dir);
+pad_string(String, MinLen, Char, Dir) when is_integer(MinLen), MinLen >= 0 ->
+ Len = length(String),
+ case {Len >= MinLen, Dir} of
+ {true, _} ->
+ String;
+ {false, right} ->
+ String ++ lists:duplicate(MinLen - Len, Char);
+ {false, left} ->
+ lists:duplicate(MinLen - Len, Char) ++ String
+ end.
+
+send_viewer_event(S, Event) ->
+ case S#state.viewer_pid of
+ ViewerPid when is_pid(ViewerPid) ->
+ ViewerPid ! {et, Event};
+ undefined ->
+ ignore
+ end.
+
+select_file(Frame, Message, DefaultFile, Style) ->
+ Dialog = wxFileDialog:new(Frame,
+ [{message, Message},
+ {defaultDir, filename:dirname(DefaultFile)},
+ {defaultFile, filename:basename(DefaultFile)},
+ {style, Style}]),
+ Choice =
+ case wxMessageDialog:showModal(Dialog) of
+ ?wxID_CANCEL -> cancel;
+ ?wxID_OK -> {ok, wxFileDialog:getPath(Dialog)}
+ end,
+ wxFileDialog:destroy(Dialog),
+ Choice.
diff --git a/lib/et/src/et_wx_viewer.erl b/lib/et/src/et_wx_viewer.erl
new file mode 100644
index 0000000000..1e2677e216
--- /dev/null
+++ b/lib/et/src/et_wx_viewer.erl
@@ -0,0 +1,2124 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Displays a sequence chart for trace events (messages/actions)
+%%----------------------------------------------------------------------
+
+-module(et_wx_viewer).
+
+-behaviour(gen_server).
+
+%% External exports
+-export([start_link/1]).
+
+%% gen_server callbacks
+-export([init/1, terminate/2, code_change/3,
+ handle_call/3, handle_cast/2, handle_info/2]).
+
+-include("../include/et.hrl").
+-include("et_internal.hrl").
+-include_lib("wx/include/wx.hrl").
+
+-define(unknown, "UNKNOWN").
+-define(initial_x, 10).
+-define(incr_x, 60).
+-define(initial_y, 15).
+-define(incr_y, 15).
+-define(detail_level_min, 0).
+-define(detail_level_max, 100).
+
+-record(state,
+ {parent_pid, % Pid of parent process
+ auto_shutdown, % Shutdown collector when last subscriber dies
+ collector_pid, % Pid of collector process
+ event_order, % Field to be used as primary key
+ trace_pattern, % Collector trace pattern
+ active_filter, % Name of the active filter
+ filters, % List of possible filters
+ filter_menu,
+ pending_actor, % Pending actor - move or toggle
+ first_event, % Key of first event (regardless of visibility)
+ last_event, % Key of last event (regardless of visibility)
+ events_per_page, % Maximum number of shown events
+ events, % Queue containg all event keys (regardless of visibility)
+ n_events, % Number of events available in the collector
+ max_actors, % Maximum number of shown actors
+ actors, % List of known actors
+ refresh_needed, % Refresh is needed in order to show all actors
+ detail_level, % Show only events with lesser detail level
+ hide_actions, % Hide/show events where to == from actor (bool)
+ hide_actors, % Hide/show events with unknown actor (bool)
+ display_all,
+ context, % display | print
+ title, % GUI: Window title
+ frame, % GUI: Window object
+ menubar, % GUI: Menu bar object
+ packer, % GUI: Packer object
+ width, % GUI: Window width
+ height, % GUI: Window height
+ scale, % GUI: Scaling factor on canvas
+ normal_font, % GUI: Font to be used on text labels
+ bold_font, % GUI: Font to be used on text labels
+ pen,
+ brush,
+ print_psdd,
+ print_d,
+ canvas_width, % GUI: Canvas width
+ canvas_height, % GUI: Canvas height
+ canvas, % GUI: Canvas object
+ canvas_sizer,
+ scroll_bar, % GUI: Canvas scroll bar
+ y_pos, % GUI: Current y position on canvas
+ menu_data,
+ checkbox_data,
+ hide_actions_box,
+ hide_actors_box,
+ status_bar,
+ event_file,
+ wx_debug, % GUI: WX debug level
+ trap_exit}). % trap_exit process flag
+
+
+-record(actor, {name, string, include, exclude}).
+-record(e, {pos, key, event}).
+
+%%%----------------------------------------------------------------------
+%%% Client side
+%%%----------------------------------------------------------------------
+
+start_link(Options) ->
+ case parse_opt(Options, default_state(), []) of
+ {ok, S, CollectorOpt} ->
+ case S#state.collector_pid of
+ CollectorPid when is_pid(CollectorPid) ->
+ case gen_server:start_link(?MODULE, [S], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid),
+ {ok, Pid};
+ Other ->
+ Other
+ end;
+ undefined ->
+ case et_collector:start_link([{auto_shutdown, true} | CollectorOpt]) of
+ {ok, CollectorPid} ->
+ S2 = S#state{collector_pid = CollectorPid},
+ case gen_server:start_link(?MODULE, [S2], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid),
+ {ok, Pid};
+ Other ->
+ Other
+ end;
+ {error, Reason} ->
+ {error, {et_collector, Reason}}
+ end
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+default_state() ->
+ #state{parent_pid = self(),
+ collector_pid = undefined,
+ n_events = 0,
+ detail_level = ?detail_level_max,
+ active_filter = ?DEFAULT_FILTER_NAME,
+ filters = [?DEFAULT_FILTER],
+ event_order = trace_ts,
+ events_per_page = 100,
+ first_event = first,
+ last_event = first,
+ events = queue_new(),
+ max_actors = 5,
+ actors = [create_actor(?unknown)],
+ pending_actor = ?unknown,
+ hide_actions = false,
+ hide_actors = false,
+ display_all = true,
+ context = display,
+ refresh_needed = false,
+ scale = 2,
+ canvas_height = 0,
+ canvas_width = 0,
+ width = 800,
+ height = 600,
+ event_file = filename:absname("et_viewer.etrace"),
+ wx_debug = 0,
+ trap_exit = true}.
+
+parse_opt([], S, CollectorOpt) ->
+ {ok, S, [{parent_pid, S#state.parent_pid} | CollectorOpt]};
+parse_opt([H | T], S, CollectorOpt) ->
+ case H of
+ {parent_pid, Parent} when is_pid(Parent); Parent =:= undefined ->
+ parse_opt(T, S#state{parent_pid = Parent}, CollectorOpt);
+ {wx_debug, Level} ->
+ parse_opt(T, S#state{wx_debug = Level}, CollectorOpt);
+ {trap_exit, Bool} when Bool =:= true; Bool =:= false->
+ parse_opt(T, S#state{trap_exit = Bool}, CollectorOpt);
+ {title, Title} ->
+ parse_opt(T, S#state{title = name_to_string(Title)}, CollectorOpt);
+ {detail_level, Level} when is_integer(Level),
+ Level >= ?detail_level_min,
+ Level =< ?detail_level_max ->
+ parse_opt(T, S#state{detail_level = Level}, CollectorOpt);
+ {detail_level, max} ->
+ parse_opt(T, S#state{detail_level = ?detail_level_max}, CollectorOpt);
+ {detail_level, min} ->
+ parse_opt(T, S#state{detail_level = ?detail_level_min}, CollectorOpt);
+ {scale, Scale} when is_integer(Scale), Scale > 0 ->
+ parse_opt(T, S#state{scale = Scale}, CollectorOpt);
+ {width, W} when is_integer(W), W > 0 ->
+ parse_opt(T, S#state{width = W, canvas_width = W}, CollectorOpt);
+ {height, WH} when is_integer(WH), WH > 0 ->
+ parse_opt(T, S#state{height = WH, canvas_height = WH}, CollectorOpt);
+ {collector_pid, Pid} when is_pid(Pid) ->
+ parse_opt(T, S#state{collector_pid = Pid}, CollectorOpt);
+ {collector_pid, undefined} ->
+ parse_opt(T, S#state{collector_pid = undefined}, CollectorOpt);
+ {active_filter, Name} when is_atom(Name) ->
+ parse_opt(T, S#state{active_filter = Name}, CollectorOpt);
+ {event_order, trace_ts} -> %% BUGBUG: Verify event_order with collector
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{event_order = trace_ts}, CollectorOpt2);
+ {event_order, event_ts} -> %% BUGBUG: Verify event_order with collector
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{event_order = event_ts}, CollectorOpt2);
+ {trace_port, _Port} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_max_queue, _Queue} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_pattern, _Pattern} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_global, _Boolean} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_client, _Client} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {dict_insert, {filter, Name}, Fun} ->
+ if
+ is_atom(Name), is_function(Fun) ->
+ F = #filter{name = Name, function = Fun},
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{filters = Filters ++ [F]}, CollectorOpt2);
+ true ->
+ {error, {bad_option, H}}
+ end;
+ {dict_insert, {subscriber, Pid}, _Val} ->
+ if
+ is_pid(Pid) ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ true ->
+ {error, {bad_option, H}}
+ end;
+ {dict_insert, _Key, _Val} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {dict_delete, {filter, Name}} ->
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{filters = Filters}, CollectorOpt2);
+ {dict_delete, _Key} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {max_events, _Max} ->
+ %% Kept for backward compatibility
+ parse_opt(T, S, CollectorOpt);
+ {max_actors, Max} when is_integer(Max), Max >= 0 ->
+ parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
+ {max_actors, Max} when Max =:= infinity ->
+ parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
+ {actors, ActorNames} when is_list(ActorNames) ->
+ ActorNames2 =
+ case lists:member(?unknown, ActorNames) of
+ false -> [?unknown | ActorNames];
+ true -> ActorNames
+ end,
+ Actors = [create_actor(Name) || Name <- ActorNames2],
+ parse_opt(T, S#state{actors = Actors}, CollectorOpt);
+ {include, ActorNames} when is_list(ActorNames) ->
+ Actors = [opt_create_actor(Name, include, S#state.actors) || Name <- ActorNames],
+ parse_opt(T, S#state{actors = Actors}, CollectorOpt);
+ {exclude, ActorNames} when is_list(ActorNames) ->
+ Actors = [opt_create_actor(Name, exclude, S#state.actors) || Name <- ActorNames],
+ parse_opt(T, S#state{actors = Actors}, CollectorOpt);
+ {first_event, _FirstKey} ->
+ %% NYI
+ parse_opt(T, S, CollectorOpt);
+ {hide_actors, Bool} when Bool =:= true; Bool =:= false ->
+ parse_opt(T, S#state{hide_actors = Bool}, CollectorOpt);
+ {hide_actions, Bool} when Bool =:= true; Bool =:= false ->
+ parse_opt(T, S#state{hide_actions = Bool}, CollectorOpt);
+ {hide_unknown, Bool} when Bool =:= true; Bool =:= false ->
+ %% Kept for backward compatibility
+ parse_opt(T, S, CollectorOpt);
+ {display_mode, _Mode} ->
+ %% Kept for backward compatibility
+ parse_opt(T, S, CollectorOpt);
+ Bad ->
+ {error, {bad_option, Bad}}
+ end;
+parse_opt(BadList, _S, _CollectorOpt) ->
+ {error, {bad_option_list, BadList}}.
+
+do_dict_insert({filter, Name}, Fun, S) when is_atom(Name), is_function(Fun) ->
+ F = #filter{name = Name, function = Fun},
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ Filters2 = lists:keysort(#filter.name, [F | Filters]),
+ S2 = create_filter_menu(S, S#state.active_filter, Filters2),
+ S2#state{filters = Filters2};
+do_dict_insert(_Key, _Val, S) ->
+ %%ok = error_logger:format("~p(~p): handle_info({et, {dict_insert, ~p, ~p}})~n",
+ %% [?MODULE, self(), Key, Val]),
+ S.
+
+do_dict_delete({filter, Name}, S) when is_atom(Name), Name =/= S#state.active_filter ->
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ S2 = create_filter_menu(S, S#state.active_filter, Filters),
+ S2#state{filters = Filters};
+do_dict_delete(_Key, S) ->
+ %% ok = error_logger:format("~p(~p): handle_info({et, {dict_delete, ~p}})~n",
+ %% [?MODULE, self(), Key]),
+ S.
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+
+init([S]) when is_record(S, state) ->
+ process_flag(trap_exit, S#state.trap_exit),
+ case S#state.parent_pid of
+ undefined -> ok;
+ ParentPid -> link(ParentPid)
+ end,
+ wx:new(),
+ wx:debug(S#state.wx_debug),
+ et_collector:dict_insert(S#state.collector_pid,
+ {subscriber, self()},
+ ?MODULE),
+ S2 = create_main_window(S),
+ EventsPerPage = events_per_page(S2, S2#state.height),
+ S3 = revert_main_window(S2#state{events_per_page = EventsPerPage}),
+ Timeout = timeout(S3),
+ {ok, S3, Timeout}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_call(get_collector_pid, _From, S) ->
+ Reply = S#state.collector_pid,
+ reply(Reply, S);
+handle_call(stop, _From, S) ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, ok, S};
+handle_call({open_event, N}, _From, S) when is_integer(N), N > 0->
+ Reply = do_open_event(S, N),
+ reply(Reply, S);
+handle_call(Request, From, S) ->
+ ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
+ [?MODULE, self(), Request, From, S]),
+ Reply = {error, {bad_request, Request}},
+ reply(Reply, S).
+
+%%----------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_cast(Msg, S) ->
+ ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
+ [?MODULE, self(), Msg, S]),
+ noreply(S).
+
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_info({et, {more_events, N}}, S) ->
+ %% io:format("more events: ~p \n", [N]),
+ S4 =
+ if
+ N =:= S#state.n_events ->
+ S;
+ true ->
+ Missing = S#state.events_per_page - queue_length(S#state.events),
+ if
+ Missing =:= 0 ->
+ update_scroll_bar(S#state{n_events = N});
+ Missing > 0 ->
+ OldEvents = queue_to_list(S#state.events),
+ {S2, NewEvents} =
+ collect_more_events(S#state{n_events = N},
+ S#state.last_event,
+ Missing),
+ S3 = replace_events(S2, OldEvents ++ NewEvents),
+ refresh_main_window(S3)
+ end
+ end,
+ noreply(S4);
+handle_info({et, {insert_actors, ActorNames}}, S) when is_list(ActorNames) ->
+ Fun = fun(N, Actors) ->
+ case lists:keymember(N, #actor.name, Actors) of
+ true -> Actors;
+ false -> Actors ++ [create_actor(N)]
+ end
+ end,
+ Actors = lists:foldl(Fun, S#state.actors, ActorNames),
+ S2 = refresh_main_window(S#state{actors = Actors}),
+ noreply(S2);
+handle_info({et, {delete_actors, ActorNames}}, S) when is_list(ActorNames)->
+ Fun = fun(N, Actors) when N =:= ?unknown ->
+ Actors;
+ (N, Actors) ->
+ lists:keydelete(N, #actor.name, Actors)
+ end,
+ Actors = lists:foldl(Fun, S#state.actors, ActorNames),
+ S2 = refresh_main_window(S#state{actors = Actors}),
+ noreply(S2);
+handle_info({et, {dict_insert, Key, Val}}, S) ->
+ S2 = do_dict_insert(Key, Val, S),
+ noreply(S2);
+handle_info({et, {dict_delete, Key}}, S) ->
+ S2 = do_dict_delete(Key, S),
+ noreply(S2);
+handle_info({et, first}, S) ->
+ S2 = scroll_first(S),
+ noreply(S2);
+handle_info({et, prev}, S) ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+handle_info({et, next}, S) ->
+ S2 = scroll_next(S),
+ noreply(S2);
+handle_info({et, last}, S) ->
+ S2 = scroll_last(S),
+ noreply(S2);
+handle_info({et, refresh}, S) ->
+ S2 = revert_main_window(S),
+ noreply(S2);
+handle_info({et, {display_mode, _Mode}}, S) ->
+ %% Kept for backward compatibility
+ noreply(S);
+handle_info({et, close}, S) ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+handle_info(#wx{id=?wxID_HELP}, S) ->
+ HelpString =
+ "Vertical scroll:\n"
+ "\tUse mouse wheel and up/down arrows to scroll little.\n"
+ "\tUse page up/down and home/end buttons to scroll more.\n\n"
+ "Display details of an event:\n"
+ "\tLeft mouse click on the event label or the arrow.\n\n"
+ "Highlight actor (toggle):\n"
+ "\tLeft mouse click on the actor name tag.\n"
+ "\tThe actor name will be enclosed in square brackets [].\n\n"
+ "Exclude actor (toggle):\n"
+ "\tRight mouse click on the actor name tag.\n"
+ "\tThe actor name will be enclosed in round brackets ().\n\n"
+ "Move actor:\n"
+ "\tLeft mouse button drag and drop on actor name tag.\n\n"
+ "Display all (reset settings for hidden and/or highlighted actors):\n"
+ "\tPress the 'a' button.",
+ Dialog =
+ wxMessageDialog:new(S#state.frame, HelpString,
+ [{style, 0
+ bor ?wxOK
+ bor ?wxICON_INFORMATION
+ bor ?wxSTAY_ON_TOP},
+ {caption, "Help"}]),
+ wxMessageDialog:showModal(Dialog),
+ noreply(S);
+handle_info(#wx{id=Id, event = #wxCommand{type = command_menu_selected}}, S=#state{filter_menu = {_,Data}}) ->
+ CollectorPid = S#state.collector_pid,
+ case get_value(Id, 3, S#state.menu_data) of
+ close ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+ up ->
+ S2 = scroll_up(S),
+ noreply(S2);
+ down ->
+ S2 = scroll_down(S),
+ noreply(S2);
+ first ->
+ S2 = scroll_first(S),
+ noreply(S2);
+ prev ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ next ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ last ->
+ S2 = scroll_last(S),
+ noreply(S2);
+ refresh ->
+ S2 = revert_main_window(S),
+ noreply(S2);
+ {display_mode, _Mode} ->
+ %% Kept for backward compatibility
+ noreply(S);
+ display_all ->
+ S2 = display_all(S),
+ noreply(S2);
+ close_all ->
+ close_all(S);
+ close_all_others ->
+ close_all_others(S);
+ first_all ->
+ et_collector:multicast(CollectorPid, first),
+ noreply(S);
+ prev_all ->
+ et_collector:multicast(CollectorPid, prev),
+ noreply(S);
+ next_all ->
+ et_collector:multicast(CollectorPid, next),
+ noreply(S);
+ last_all ->
+ et_collector:multicast(CollectorPid, last),
+ noreply(S);
+ refresh_all ->
+ et_collector:multicast(CollectorPid, refresh),
+ noreply(S);
+ clear_all ->
+ et_collector:clear_table(CollectorPid),
+ et_collector:multicast(CollectorPid, refresh),
+ noreply(S);
+ load_all ->
+ Style = ?wxFD_OPEN bor ?wxFD_OVERWRITE_PROMPT,
+ Msg = "Select a file to load events from",
+ S2 =
+ case select_file(S#state.frame, Msg, S#state.event_file, Style) of
+ {ok, NewFile} ->
+ et_collector:start_trace_client(CollectorPid, event_file, NewFile),
+ S#state{event_file = NewFile};
+ cancel ->
+ S
+ end,
+ noreply(S2);
+ save_all ->
+ Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT,
+ Msg = "Select a file to save events to",
+ S2 =
+ case select_file(S#state.frame, Msg, S#state.event_file, Style) of
+ {ok, NewFile} ->
+ et_collector:save_event_file(CollectorPid, NewFile, [existing, write, keep]),
+ S#state{event_file = NewFile};
+ cancel ->
+ S
+ end,
+ noreply(S2);
+ print_setup ->
+ S2 = print_setup(S),
+ noreply(S2);
+ print_one_page = Scope ->
+ S2 = print(S, Scope),
+ noreply(S2);
+ print_all_pages = Scope ->
+ S2 = print(S, Scope),
+ noreply(S2);
+ {open_viewer, Scale} ->
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+
+ _ ->
+ case get_value(Id, 3, Data) of
+ {data, F=#filter{}, Scale} ->
+ open_viewer(S#state.scale+Scale, F#filter.name, [?unknown], S);
+ {data, F=#filter{}} ->
+ open_viewer(S#state.scale, F#filter.name, [?unknown], S);
+ false ->
+ ok
+ end,
+ noreply(S)
+ end;
+handle_info(#wx{event = #wxCommand{type = command_slider_updated, commandInt = Level}}, S) ->
+ if
+ Level >= ?detail_level_min,
+ Level =< ?detail_level_max ->
+ S2 = S#state{detail_level = Level},
+ S3 = revert_main_window(S2),
+ noreply(S3);
+
+ true ->
+ noreply(S)
+ end;
+handle_info(#wx{id = Id, event = #wxCommand{type = command_checkbox_clicked, commandInt = Int}}, S) ->
+ case get_value(Id, 2, S#state.checkbox_data) of
+ hide_actions ->
+ case Int of
+ 1 ->
+ S2 = S#state{hide_actions = true},
+ S3 = revert_main_window(S2),
+ noreply(S3);
+ 0 ->
+ S2 = S#state{hide_actions = false},
+ S3 = revert_main_window(S2),
+ noreply(S3)
+ end;
+ hide_actors ->
+ case Int of
+ 1 ->
+ S2 = S#state{hide_actors = true},
+ S3 = revert_main_window(S2),
+ noreply(S3);
+ 0 ->
+ S2 = S#state{hide_actors = false},
+ S3 = revert_main_window(S2),
+ noreply(S3)
+ end;
+ false ->
+ noreply(S)
+ end;
+handle_info(#wx{event = #wxMouse{type = left_down, x = X, y = Y}}, S) ->
+ S3 =
+ case y_to_n(Y, S) of
+ actor ->
+ %% Actor click
+ case S#state.actors of
+ [] ->
+ S;
+ Actors ->
+ N = x_to_n(X, S),
+ A = lists:nth(N, Actors),
+ S#state{pending_actor = A}
+ end;
+ {event, N} ->
+ %% Event click
+ do_open_event(S, N),
+ S
+ end,
+ noreply(S3);
+handle_info(#wx{event = #wxMouse{type = left_up}}, S) when S#state.pending_actor =:= undefined ->
+ noreply(S);
+handle_info(#wx{event = #wxMouse{type = left_up, x = X, y = Y}}, S) ->
+ S3 =
+ case y_to_n(Y, S) of
+ actor ->
+ %% Actor click
+ case S#state.actors of
+ [] ->
+ S;
+ Actors ->
+ N = x_to_n(X, S),
+ A = lists:nth(N, Actors),
+ Pending = S#state.pending_actor,
+ if
+ A#actor.name =:= Pending#actor.name ->
+ %% Toggle include actor
+ A2 = A#actor{include = not A#actor.include},
+ %% io:format("include ~p: ~p -> ~p\n",
+ %% [A#actor.name, A#actor.include, A2#actor.include]),
+ Actors2 = lists:keyreplace(A#actor.name, #actor.name, Actors, A2),
+ DisplayAll = not lists:keymember(true, #actor.include, Actors2),
+ S2 = S#state{actors = Actors2, display_all = DisplayAll},
+ revert_main_window(S2);
+ true ->
+ move_actor(Pending, A, Actors, S)
+ end
+ end;
+ {event, _N} ->
+ %% Event click ignored
+ S
+ end,
+ noreply(S3#state{pending_actor = undefined});
+handle_info(#wx{event = #wxMouse{type = right_up, x = X, y = Y}}, S) ->
+ S3 =
+ case y_to_n(Y, S) of
+ actor ->
+ %% Actor click
+ case S#state.actors of
+ [] ->
+ S;
+ Actors ->
+ %% Toggle exclude actor
+ N = x_to_n(X, S),
+ A = lists:nth(N, Actors),
+ A2 = A#actor{exclude = not A#actor.exclude},
+ Actors2 = lists:keyreplace(A#actor.name, #actor.name, Actors, A2),
+ S2 = S#state{actors = Actors2},
+ revert_main_window(S2)
+ end;
+ {event, _N} ->
+ %% Event click ignored
+ S
+ end,
+ noreply(S3#state{pending_actor = undefined});
+handle_info(#wx{event = #wxKey{keyCode = KeyCode, shiftDown = SD}}, S) ->
+ case KeyCode of
+ $C when SD =:= true ->
+ close_all(S);
+ $c ->
+ close_all_others(S);
+ ?WXK_HOME ->
+ S2 = scroll_first(S),
+ noreply(S2);
+ ?WXK_END ->
+ S2 = scroll_last(S),
+ noreply(S2);
+ ?WXK_UP ->
+ S2 = scroll_up(S),
+ noreply(S2);
+ ?WXK_DOWN ->
+ S2 = scroll_down(S),
+ noreply(S2);
+ ?WXK_PAGEUP ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ ?WXK_PAGEDOWN ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ $F when SD =:= true ->
+ et_collector:multicast(S#state.collector_pid, first),
+ noreply(S);
+ $F ->
+ S2 = scroll_first(S),
+ noreply(S2);
+ $P when SD =:= true ->
+ et_collector:multicast(S#state.collector_pid, prev),
+ noreply(S);
+ $P ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ $N when SD =:= true ->
+ et_collector:multicast(S#state.collector_pid, next),
+ noreply(S);
+ $N ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ $L when SD =:= true ->
+ et_collector:multicast(S#state.collector_pid, last),
+ noreply(S);
+ $L ->
+ S2 = scroll_last(S),
+ noreply(S2);
+ $R when SD =:= true ->
+ et_collector:multicast(S#state.collector_pid, refresh),
+ noreply(S);
+ $R ->
+ S2 = revert_main_window(S),
+ noreply(S2);
+ $A ->
+ S2 = display_all(S),
+ noreply(S2);
+ $= ->
+ Scale = S#state.scale,
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+ Int when Int =:= $+; Int =:= ?WXK_NUMPAD_ADD ->
+ Scale = S#state.scale + 1,
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+ Int when Int =:= $-; Int =:= ?WXK_NUMPAD_SUBTRACT ->
+ case S#state.scale of
+ 1 ->
+ ignore;
+ Scale ->
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale - 1, S#state.active_filter, Actors, S)
+ end,
+ noreply(S);
+ $0 ->
+ case lists:keysearch(?DEFAULT_FILTER_NAME, #filter.name, S#state.filters) of
+ {value, F} when is_record(F, filter) ->
+ open_viewer(S#state.scale, F#filter.name, [?unknown], S);
+ false ->
+ ok
+ end,
+ noreply(S);
+ Int when is_integer(Int), Int > $0, Int =< $9 ->
+ case catch lists:nth(Int-$0, S#state.filters) of
+ F when is_record(F, filter) ->
+ open_viewer(S#state.scale, F#filter.name, [?unknown], S);
+ {'EXIT', _} ->
+ ok
+ end,
+ noreply(S);
+
+ _ ->
+ noreply(S)
+ end;
+handle_info(#wx{event = #wxScroll{type = scroll_changed}} = Wx, S) ->
+ get_latest_scroll(Wx),
+ Pos = wxScrollBar:getThumbPosition(S#state.scroll_bar),
+ {_, LineTopY, LineBotY} = calc_y(S),
+ Range = LineBotY - LineTopY,
+ N = round(S#state.n_events * Pos / Range),
+ Diff =
+ case N - event_pos(S) of
+ D when D < 0 -> D - 1;
+ D -> D + 1
+ end,
+ S2 = scroll_changed(S, Diff),
+ noreply(S2);
+handle_info(timeout, S) ->
+ noreply(S);
+handle_info({'EXIT', Pid, Reason}, S) ->
+ if
+ Pid =:= S#state.collector_pid ->
+ io:format("collector died: ~p\n\n", [Reason]),
+ wxFrame:destroy(S#state.frame),
+ {stop, Reason, S};
+ Pid =:= S#state.parent_pid ->
+ wxFrame:destroy(S#state.frame),
+ {stop, Reason, S};
+ true ->
+ noreply(S)
+ end;
+handle_info(#wx{event = #wxClose{}}, S) ->
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+handle_info(#wx{event = #wxMouse{type = mousewheel, wheelRotation = Rot}}, S) when Rot > 0 ->
+ S2 = scroll_up(S),
+ noreply(S2);
+handle_info(#wx{event = #wxMouse{type = mousewheel, wheelRotation = Rot}}, S) when Rot < 0 ->
+ S2 = scroll_down(S),
+ noreply(S2);
+handle_info(#wx{event = #wxSize{size = {OldW, OldH}}} = Wx, S) ->
+ #wx{event = #wxSize{type = size, size = {W, H}}} = get_latest_resize(Wx),
+ S2 = S#state{width = W, height = H, canvas_width = W, canvas_height = H},
+ EventsPerPage = events_per_page(S, H),
+ Diff = EventsPerPage - S#state.events_per_page,
+ S6 =
+ if
+ OldW =:= W, OldH =:= H, S2#state.events_per_page =:= EventsPerPage ->
+ S2;
+ Diff =:= 0 ->
+ refresh_main_window(S2);
+ Diff > 0 ->
+ OldEvents = queue_to_list(S2#state.events),
+ {S3, NewEvents} = collect_more_events(S2, S2#state.last_event, Diff),
+ S4 = S3#state{events_per_page = EventsPerPage},
+ S5 = replace_events(S4, OldEvents ++ NewEvents),
+ refresh_main_window(S5);
+ Diff < 0 ->
+ OldEvents = queue_to_list(S2#state.events),
+ RevEvents = delete_n(lists:reverse(OldEvents), abs(Diff)),
+ S3 = S2#state{events_per_page = EventsPerPage},
+ S4 = replace_events(S3, lists:reverse(RevEvents)),
+ refresh_main_window(S4)
+ end,
+ noreply(S6);
+handle_info(#wx{event = #wxFocus{}}, S) ->
+ wxWindow:setFocus(S#state.canvas), % Get keyboard focus
+ noreply(S);
+handle_info(#wx{event = #wxMouse{type = enter_window}}, S) ->
+ wxWindow:setFocus(S#state.canvas), % Get keyboard focus
+ noreply(S);
+handle_info(#wx{event = #wxPaint{}}, S) ->
+ S2 = refresh_main_window(S),
+ noreply(S2);
+handle_info(#wx{event = #wxMouse{type = T, x=X,y=Y}}, S) ->
+ io:format("~p ~p\n", [T, {X,Y}]),
+ noreply(S);
+handle_info(Info, S) ->
+ ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
+ [?MODULE, self(), Info, S]),
+ noreply(S).
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%----------------------------------------------------------------------
+
+terminate(_Reason, _S) ->
+ ignore.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Convert process state when code is changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+
+code_change(_OldVsn, S, _Extra) ->
+ {ok, S}.
+
+%%%----------------------------------------------------------------------
+%%% Handle stuff
+%%%----------------------------------------------------------------------
+
+reply(Reply, S) ->
+ Timeout = timeout(S),
+ {reply, Reply, S, Timeout}.
+
+noreply(S) ->
+ Timeout = timeout(S),
+ {noreply, S, Timeout}.
+
+timeout(_S) ->
+ infinity.
+
+scroll_first(S) ->
+ EventsPerPage = S#state.events_per_page,
+ {S2, NewEvents} =
+ collect_more_events(S, first, EventsPerPage),
+ S3 =
+ case NewEvents of
+ [] ->
+ S2;
+ [FirstE | _] ->
+ S2#state{first_event = FirstE}
+ end,
+ S4 = replace_events(S3, NewEvents),
+ refresh_main_window(S4).
+
+scroll_last(S) ->
+ case collect_more_events(S, last, -1) of
+ {_, []} ->
+ scroll_first(S);
+ {S2, NewEvents} ->
+ [FirstE | _] = NewEvents,
+ S3 = replace_events(S2#state{first_event = FirstE}, NewEvents),
+ refresh_main_window(S3)
+ end.
+
+scroll_prev(S) ->
+ scroll_up(S, S#state.events_per_page).
+
+scroll_next(S) ->
+ scroll_down(S, S#state.events_per_page).
+
+scroll_up(S) ->
+ scroll_up(S, calc_scroll(S)).
+
+scroll_up(S, Expected) ->
+ N = queue_length(S#state.events),
+ EventsPerPage = S#state.events_per_page,
+ Expected2 = adjust_expected(Expected, N, EventsPerPage),
+ OldEvents = queue_to_list(S#state.events),
+ case collect_more_events(S, S#state.first_event, -Expected2) of
+ {_, []} ->
+ S;
+ {S2, NewEvents} ->
+ NewN = length(NewEvents),
+ if
+ N + NewN > EventsPerPage ->
+ RevAllEvents = lists:reverse(OldEvents, lists:reverse(NewEvents)),
+ TooMany = N + NewN - EventsPerPage,
+ case delete_n(RevAllEvents, TooMany) of
+ [] ->
+ S;
+ [LastE | _] = RevEvents ->
+ Events = lists:reverse(RevEvents),
+ S3 = replace_events(S2#state{last_event = LastE}, Events),
+ refresh_main_window(S3)
+ end;
+ true ->
+ Events = NewEvents ++ OldEvents,
+ LastE = lists:last(Events),
+ S3 = replace_events(S2#state{last_event = LastE}, Events),
+ refresh_main_window(S3)
+ end
+ end.
+
+scroll_down(S) ->
+ scroll_down(S, calc_scroll(S)).
+
+scroll_down(S, Expected) ->
+ N = queue_length(S#state.events),
+ EventsPerPage = S#state.events_per_page,
+ Expected2 = adjust_expected(Expected, N, EventsPerPage),
+ OldEvents = queue_to_list(S#state.events),
+ case collect_more_events(S, S#state.last_event, Expected2) of
+ {_, []} ->
+ case collect_more_events(S, S#state.first_event, N - EventsPerPage) of
+ {_, []} ->
+ S;
+ {S2, NewEvents} ->
+ Events = NewEvents ++ OldEvents,
+ [FirstE | _] = Events,
+ S3 = replace_events(S2#state{first_event = FirstE}, Events),
+ refresh_main_window(S3)
+ end;
+ {S2, NewEvents} ->
+ AllEvents = OldEvents ++ NewEvents,
+ case delete_n(AllEvents, length(NewEvents)) of
+ [] ->
+ scroll_first(S);
+ Events ->
+ [FirstE | _] = Events,
+ S3 = replace_events(S2#state{first_event = FirstE}, Events),
+ refresh_main_window(S3)
+ end
+ end.
+
+scroll_changed(S, Expected) ->
+ if
+ Expected =:= 0 ->
+ refresh_main_window(S);
+ Expected < 0 ->
+ %% Up
+ OldPos = event_pos(S),
+ NewPos = lists:max([OldPos + Expected, 0]),
+ case S#state.first_event of
+ #e{key = Key, pos = OldPos} ->
+ jump_up(S, Key, OldPos, NewPos);
+ first ->
+ scroll_first(S);
+ last ->
+ scroll_last(S)
+ end;
+ true ->
+ %% Down
+ OldPos = event_pos(S),
+ NewPos = lists:min([OldPos + Expected, S#state.n_events]),
+ case S#state.first_event of
+ #e{key = Key, pos = OldPos} ->
+ jump_down(S, Key, OldPos, NewPos);
+ first = Key ->
+ jump_down(S, Key, 0, NewPos);
+ last ->
+ scroll_last(S)
+ end
+ end.
+
+jump_up(S, OldKey, OldPos, NewPos) ->
+ Try = NewPos - OldPos,
+ Order = S#state.event_order,
+ Fun = fun(Event, #e{pos = P}) when P >= NewPos ->
+ Key = et_collector:make_key(Order, Event),
+ #e{event = Event, key = Key, pos = P - 1};
+ (_, Acc) ->
+ Acc
+ end,
+ PrevE = et_collector:iterate(S#state.collector_pid,
+ OldKey,
+ Try,
+ Fun,
+ #e{key = OldKey, pos = OldPos}),
+ case collect_more_events(S, PrevE, S#state.events_per_page) of
+ {_, []} ->
+ S;
+ {S2, Events} ->
+ [FirstE | _] = Events,
+ S3 = replace_events(S2#state{first_event = FirstE}, Events),
+ refresh_main_window(S3)
+ end.
+
+jump_down(S, OldKey, OldPos, NewPos) ->
+ Try = NewPos - OldPos,
+ Order = S#state.event_order,
+ Fun = fun(Event, #e{pos = P}) when P < NewPos ->
+ Key = et_collector:make_key(Order, Event),
+ #e{event = Event, key = Key, pos = P + 1};
+ (_, Acc) ->
+ Acc
+ end,
+ PrevE = et_collector:iterate(S#state.collector_pid,
+ OldKey,
+ Try,
+ Fun,
+ #e{key = OldKey, pos = OldPos}),
+ case collect_more_events(S, PrevE, S#state.events_per_page) of
+ {_, []} ->
+ S;
+ {S2, Events} ->
+ [FirstE | _] = Events,
+ S3 = replace_events(S2#state{first_event = FirstE}, Events),
+ refresh_main_window(S3)
+ end.
+
+adjust_expected(Expected, N, EventsPerPage) ->
+ if
+ N < EventsPerPage ->
+ EventsPerPage - N;
+ Expected < EventsPerPage ->
+ Expected;
+ true ->
+ EventsPerPage
+ end.
+
+calc_scroll(S) ->
+ lists:max([S#state.events_per_page div 3, 1]).
+
+revert_main_window(S) ->
+ {S2, Events} = revert(S),
+ S3 = replace_events(S2, Events),
+ refresh_main_window(S3).
+
+revert(S) ->
+ EventsPerPage = S#state.events_per_page,
+ %% Find previous event
+ case collect_more_events(S, S#state.first_event, -1) of
+ {_, []} ->
+ collect_more_events(S, first, EventsPerPage);
+ {S2, [_PrevEvent]} ->
+ collect_more_events(S, S2#state.first_event, EventsPerPage)
+ end.
+
+delete_n(List, 0) ->
+ List;
+delete_n([], _) ->
+ [];
+delete_n([_ | Tail], N) when N > 0 ->
+ delete_n(Tail, N - 1).
+
+pick_n(Rest, 0, Acc) ->
+ {lists:reverse(Acc), Rest};
+pick_n([], _N, Acc) ->
+ {lists:reverse(Acc), []};
+pick_n([Head | Tail], N, Acc) when N > 0 ->
+ pick_n(Tail, N - 1, [Head | Acc]).
+
+close_all(S) ->
+ close_all_others(S),
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S}.
+
+close_all_others(S) ->
+ Fun =
+ fun({{subscriber, Pid}, _}) ->
+ if
+ Pid =:= self() ->
+ ignore;
+ true ->
+ unlink(Pid),
+ Pid ! {et, close}
+ end
+ end,
+ All = et_collector:dict_match(S#state.collector_pid,
+ {{subscriber, '_'}, '_'}),
+ lists:foreach(Fun, All),
+ noreply(S).
+
+opt_unlink(Pid) ->
+ if
+ Pid =:= undefined ->
+ ignore;
+ true ->
+ unlink(Pid)
+ end.
+
+%%%----------------------------------------------------------------------
+%%% Clone viewer
+%%%----------------------------------------------------------------------
+
+open_viewer(Scale, FilterName, Actors, S) ->
+ Filters = [{dict_insert, {filter, F#filter.name}, F#filter.function}
+ || F <- S#state.filters],
+ Options =
+ [{parent_pid, S#state.parent_pid},
+ {title, S#state.title},
+ {collector_pid, S#state.collector_pid},
+ {detail_level, S#state.detail_level},
+ {active_filter, FilterName},
+ {event_order, S#state.event_order},
+ {first_event, S#state.first_event},
+ {max_actors, S#state.max_actors},
+ {hide_actions, S#state.hide_actions},
+ {hide_actors, S#state.hide_actors},
+ {actors, Actors},
+ {scale, Scale},
+ {width, S#state.width},
+ {height, S#state.height} | Filters],
+ case start_link(Options) of
+ {ok, _ViewerPid} ->
+ %% unlink(ViewerPid),
+ ok;
+ {error, Reason} ->
+ ok = error_logger:format("~p: Failed to start a new window: ~p~n",
+ [?MODULE, Reason])
+ end.
+
+%%%----------------------------------------------------------------------
+%%% Handle graphics
+%%%----------------------------------------------------------------------
+
+create_main_window(S) ->
+ {NormalFont, BoldFont} = select_fonts(S#state.scale),
+ Name = name_to_string(S#state.active_filter),
+ Title = case S#state.title of
+ undefined -> atom_to_list(?MODULE);
+ Explicit -> name_to_string(Explicit)
+ end,
+ Frame = wxFrame:new(wx:null(),
+ ?wxID_ANY,
+ Title ++ " (filter: " ++ Name ++ ")",
+ [{size, {S#state.width, S#state.height}}]),
+ StatusBar = wxFrame:createStatusBar(Frame),
+
+ Panel = wxPanel:new(Frame, []),
+ Bar = wxMenuBar:new(),
+ wxFrame:setMenuBar(Frame,Bar),
+ MainSizer = wxBoxSizer:new(?wxVERTICAL),
+
+ MenuData = lists:flatten([create_file_menu(Bar),
+ create_viewer_menu(Bar),
+ create_collector_menu(Bar)]),
+ FilterMenu = wxMenu:new([]),
+ S2 = create_filter_menu(S#state{filter_menu = {FilterMenu,[]}},
+ S#state.active_filter,
+ S#state.filters),
+ wxMenuBar:append(Bar, FilterMenu, "Filters and scaling"),
+ create_help_menu(Bar),
+
+ OptSizer = wxBoxSizer:new(?wxHORIZONTAL),
+ CheckSizer = wxBoxSizer:new(?wxVERTICAL),
+ HideActions = wxCheckBox:new(Panel, ?wxID_ANY, "Hide From=To"),
+ wxCheckBox:setValue(HideActions, S#state.hide_actions),
+ HideActors = wxCheckBox:new(Panel, ?wxID_ANY, "Hide (excluded actors)"),
+ wxCheckBox:setValue(HideActors, S#state.hide_actors),
+ CheckBoxData = [{wxCheckBox:getId(HideActions), hide_actions},
+ {wxCheckBox:getId(HideActors), hide_actors}],
+ wxPanel:connect(Panel, command_checkbox_clicked),
+ wxSizer:add(CheckSizer, HideActions),
+ wxSizer:add(CheckSizer,HideActors),
+ wxSizer:add(OptSizer, CheckSizer, [{border, 10}, {flag, ?wxALL}]),
+ DetailLevelBox = wxStaticBoxSizer:new(?wxHORIZONTAL,
+ Panel,
+ [{label, "Detail level"}]),
+ DetailLevel = wxSlider:new(Panel, ?wxID_ANY,
+ S#state.detail_level,
+ ?detail_level_min,
+ ?detail_level_max,
+ [{style, ?wxSL_LABELS},
+ {size, {200,-1}}]),
+ wxStatusBar:setStatusText(StatusBar, where_text(S)),
+ wxFrame:connect(Frame, command_slider_updated),
+ wxSizer:add(DetailLevelBox, DetailLevel),
+ wxSizer:add(OptSizer, DetailLevelBox, [{border, 10}, {flag, ?wxALL}]),
+ wxSizer:addStretchSpacer(OptSizer),
+ wxSizer:add(MainSizer, OptSizer),
+ wxSizer:add(MainSizer,
+ wxStaticLine:new(Panel, [{style, ?wxLI_HORIZONTAL}]),
+ [{flag, ?wxEXPAND}]),
+
+ CanvasSizer = wxBoxSizer:new(?wxHORIZONTAL),
+ Canvas = wxPanel:new(Panel, []),
+ {CanvasW,CanvasH} = wxPanel:getSize(Canvas),
+ ScrollBar = wxScrollBar:new(Panel, ?wxID_ANY, [{style, ?wxSB_VERTICAL}]),
+
+ wxSizer:add(CanvasSizer, Canvas, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ wxSizer:add(CanvasSizer, ScrollBar, [{flag, ?wxEXPAND}]),
+ wxSizer:add(MainSizer, CanvasSizer, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ wxPanel:connect(Canvas, left_down),
+ wxPanel:connect(Canvas, left_up),
+ wxPanel:connect(Canvas, right_up),
+ wxPanel:connect(Canvas, size),
+ wxPanel:connect(Canvas, paint),
+ wxPanel:connect(Canvas, key_down),
+ wxPanel:connect(Canvas, kill_focus),
+ wxPanel:connect(Canvas, enter_window, [{skip, true}]),
+ wxFrame:connect(Frame, command_menu_selected),
+ wxFrame:connect(Frame, close_window),
+ wxFrame:connect(ScrollBar, scroll_changed),
+ wxPanel:setSize(Panel, {S#state.width, S#state.height}),
+ wxPanel:setSizer(Panel, MainSizer),
+ wxFrame:show(Frame),
+ wxPanel:setFocus(Canvas),
+ wxPanel:connect(Canvas, mousewheel),
+
+ S3 = S2#state{title = Title,
+ frame = Frame, packer = Panel,
+ normal_font = NormalFont, bold_font = BoldFont,
+ canvas_width = CanvasW, canvas_height = CanvasH,
+ canvas = Canvas,
+ canvas_sizer = CanvasSizer,
+ scroll_bar = ScrollBar,
+ y_pos = ?initial_y * S#state.scale,
+ pen = wxPen:new(),
+ brush = wxBrush:new(),
+ print_d = undefined,
+ print_psdd = undefined,
+ menu_data = MenuData,
+ checkbox_data = CheckBoxData,
+ hide_actions_box = HideActions,
+ hide_actors_box = HideActors,
+ status_bar = StatusBar},
+ DC = wxClientDC:new(Canvas),
+ S4 = draw_all_actors(S3, DC),
+ wxClientDC:destroy(DC),
+ S4.
+
+where_text(#state{n_events = N} = S) ->
+ Pos = event_pos(S),
+ lists:concat([Pos, " (", N, ")"]).
+
+event_pos(#state{first_event = E, events = Events, n_events = Last}) ->
+ case E of
+ #e{pos = Pos} ->
+ Pos;
+ first ->
+ case queue_length(Events) of
+ 0 ->
+ 0;
+ _ ->
+ 1
+ end;
+ last ->
+ Last
+ end.
+
+init_printers(#state{print_d = undefined, print_psdd = undefined} = S) ->
+ PD = wxPrintData:new(),
+ PSDD = wxPageSetupDialogData:new(PD),
+ wxPrintData:setPaperId(PD, ?wxPAPER_A4),
+ wxPageSetupDialogData:setMarginTopLeft(PSDD, {15,15}),
+ wxPageSetupDialogData:setMarginBottomRight(PSDD, {15,15}),
+ S#state{print_d = PD, print_psdd = PSDD};
+init_printers(#state{} = S) ->
+ S.
+
+select_fonts(Scale) when is_integer(Scale) ->
+ Size =
+ case Scale of
+ 1 -> 5;
+ 2 -> 10;
+ 3 -> 14;
+ 4 -> 20;
+ S -> S*6
+ end,
+ {wxFont:new(Size, ?wxFONTFAMILY_TELETYPE, ?wxNORMAL, ?wxNORMAL,[]),
+ wxFont:new(Size, ?wxFONTFAMILY_TELETYPE, ?wxNORMAL, ?wxBOLD,[])}.
+
+get_value(Key, Pos, TupleList) when is_list(TupleList)->
+ case lists:keysearch(Key, 1, TupleList) of
+ {value, Tuple} when is_tuple(Tuple)->
+ element(Pos, Tuple);
+ false ->
+ false
+ end.
+
+menuitem(Menu, Id, Text, UserData) ->
+ Item = wxMenu:append(Menu, Id, Text),
+ {wxMenuItem:getId(Item), Item, UserData}.
+
+create_file_menu(Bar) ->
+ Menu = wxMenu:new([]),
+ Data = [
+ menuitem(Menu, ?wxID_ANY, "Clear all events in the Collector", clear_all),
+ menuitem(Menu, ?wxID_ANY, "Load events to the Collector from file", load_all),
+ menuitem(Menu, ?wxID_ANY, "Save all events in the Collector to file", save_all),
+
+ menuitem(Menu, ?wxID_PRINT_SETUP, "Print setup", print_setup),
+ menuitem(Menu, ?wxID_ANY, "Print current page", print_one_page),
+ menuitem(Menu, ?wxID_PRINT, "Print all pages", print_all_pages),
+
+ menuitem(Menu, ?wxID_ANY, "Close this Viewer", close),
+ menuitem(Menu, ?wxID_ANY, "Close all other Viewers, but this (c)", close_all_others),
+ menuitem(Menu, ?wxID_ANY, "Close all Viewers and the Collector) (C) ", close_all)
+ ],
+ wxMenu:insertSeparator(Menu, 3),
+ wxMenu:insertSeparator(Menu, 7),
+ wxMenuBar:append(Bar, Menu, "File"),
+ Data.
+
+create_viewer_menu(Bar) ->
+ Menu = wxMenu:new([]),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Scroll this Viewer"),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ D1 = [
+ menuitem(Menu, ?wxID_ANY, "First (f)", first),
+ menuitem(Menu, ?wxID_ANY, "Last (l)", last),
+ menuitem(Menu, ?wxID_ANY, "Prev (p)", prev),
+ menuitem(Menu, ?wxID_ANY, "Next (n)", next),
+ menuitem(Menu, ?wxID_ANY, "Refresh (r)", refresh)
+ ],
+ wxMenu:appendSeparator(Menu),
+ D2 = [
+ menuitem(Menu, ?wxID_ANY, "Up 5 (Up)", up),
+ menuitem(Menu, ?wxID_ANY, "Down 5 (Down)", down)
+ ],
+ wxMenu:appendSeparator(Menu),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Actor visibility in this Viewer"),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ D3 = [menuitem(Menu, ?wxID_ANY, "Display all actors (a)", display_all)],
+ wxMenuBar:append(Bar, Menu, "Viewer"),
+ [D1,D2,D3].
+
+create_collector_menu(Bar) ->
+ Menu = wxMenu:new([]),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Scroll all Viewers"),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Data = [
+ menuitem(Menu, ?wxID_ANY, "First (F)", first_all),
+ menuitem(Menu, ?wxID_ANY, "Last (L)", last_all),
+ menuitem(Menu, ?wxID_ANY, "Prev (P)", prev_all),
+ menuitem(Menu, ?wxID_ANY, "Next (N)", next_all),
+ menuitem(Menu, ?wxID_ANY, "Refresh (R)", refresh_all)
+ ],
+ wxMenuBar:append(Bar, Menu, "Collector"),
+ Data.
+
+create_filter_menu(S=#state{filter_menu = {Menu,Data}}, ActiveFilterName, Filters) ->
+ wx:foreach(fun({_,I,_}) ->
+ wxMenu:delete(Menu,I);
+ (I) ->
+ try
+ wxMenu:delete(Menu,I)
+ catch
+ _:Reason ->
+ io:format("Could not delete item: ~p, because ~p.\n", [I, Reason])
+ end
+ end,
+ Data),
+ Item = fun(F, {N, Acc}) when F#filter.name =:= all ->
+ Label = lists:concat([pad_string(F#filter.name, 20), "(0)"]),
+ {N+1, [menuitem(Menu, ?wxID_ANY, Label, {data, F})|Acc]};
+ (F, {N, Acc}) ->
+ Label = lists:concat([pad_string(F#filter.name, 20), "(", N, ")"]),
+ {N+1, [menuitem(Menu, ?wxID_ANY, Label, {data, F})|Acc]}
+ end,
+ D1 = [I1 = wxMenu:append(Menu, ?wxID_ANY, "Same Filter New Scale"),
+ wxMenu:appendSeparator(Menu)],
+ wxMenuItem:enable(I1, [{enable,false}]),
+ {value, Filter} = lists:keysearch(ActiveFilterName, #filter.name, Filters),
+ Same = lists:concat([pad_string(ActiveFilterName, 20), "(=) same scale"]),
+ Larger = lists:concat([pad_string(ActiveFilterName, 20), "(+) bigger scale"]),
+ Smaller = lists:concat([pad_string(ActiveFilterName, 20), "(-) smaller scale"]),
+ D2 = [
+ menuitem(Menu, ?wxID_ANY, Same, {data, Filter, 0}),
+ menuitem(Menu, ?wxID_ANY, Smaller, {data, Filter, -1}),
+ menuitem(Menu, ?wxID_ANY, Larger, {data, Filter, 1}),
+ wxMenu:appendSeparator(Menu),
+ I2 = wxMenu:append(Menu, ?wxID_ANY, "New Filter Same Scale"),
+ wxMenu:appendSeparator(Menu)
+ ],
+ wxMenuItem:enable(I2, [{enable,false}]),
+ {_,D3} = lists:foldl(Item, {1,[]}, Filters),
+ S#state{filter_menu = {Menu, lists:flatten([D1,D2,D3])}}.
+
+create_help_menu(Bar) ->
+ Menu = wxMenu:new([]),
+ menuitem(Menu, ?wxID_HELP, "Info", help),
+ wxMenuBar:append(Bar, Menu, "Help").
+
+clear_canvas(S) ->
+ DC = wxClientDC:new(S#state.canvas),
+ wxDC:clear(DC),
+ {CanvasW, CanvasH} = wxPanel:getSize(S#state.canvas),
+ wxSizer:recalcSizes(S#state.canvas_sizer),
+ S2 = S#state{refresh_needed = false,
+ y_pos = ?initial_y * S#state.scale,
+ canvas_width = CanvasW,
+ canvas_height = CanvasH,
+ events = queue_new()},
+ S3 = draw_all_actors(S2, DC),
+ wxClientDC:destroy(DC),
+ S3.
+
+replace_events(S, []) ->
+ S#state{first_event = first,
+ last_event = first,
+ events = queue_new()};
+replace_events(S, Events) ->
+ Queue = lists:foldl(fun(E, Q) -> queue_in(E, Q) end, queue_new(), Events),
+ S#state{events = Queue}.
+
+refresh_main_window(S) ->
+ wx:batch(fun() ->
+ S2 = clear_canvas(S),
+ S3 = update_scroll_bar(S2),
+ display_events(S3, queue_to_list(S#state.events))
+ end).
+
+display_events(S, []) ->
+ S;
+display_events(S, Events) ->
+ DC = wxClientDC:new(S#state.canvas),
+ S2 = lists:foldl(fun(E, State) -> display_event(E, State, DC) end, S, Events),
+ wxClientDC:destroy(DC),
+ S2.
+
+collect_more_events(S, PrevKey = first, Try) ->
+ PrevE = #e{event = undefined, key = PrevKey, pos = 0},
+ S2 = S#state{first_event = PrevE, last_event = PrevE},
+ do_collect_more_events(S2, Try, PrevE, []);
+collect_more_events(S, PrevKey = last, Try) ->
+ PrevE = #e{event = undefined, key = PrevKey, pos = S#state.n_events},
+ S2 = S#state{first_event = PrevE, last_event = PrevE},
+ do_collect_more_events(S2, Try, PrevE, []);
+collect_more_events(S, #e{} = PrevE, Try) ->
+ do_collect_more_events(S, Try, PrevE, []).
+
+do_collect_more_events(#state{collector_pid = Collector,
+ event_order = Order,
+ active_filter = Active,
+ filters = Filters} = S,
+ Try,
+ PrevE,
+ Acc) ->
+ Incr =
+ if
+ Try < 0 -> -1;
+ true -> 1
+ end,
+ PrevKey = PrevE#e.key,
+ {value, #filter{function = FilterFun}} =
+ lists:keysearch(Active, #filter.name, Filters),
+ {_S, _Incr, _Order, _Active, _FilterFun, LastE, NewEvents} =
+ et_collector:iterate(Collector,
+ PrevKey,
+ Try,
+ fun collect_event/2,
+ {S, Incr, Order, Active, FilterFun, PrevE, []}),
+ Expected = abs(Try),
+ Actual = length(NewEvents),
+ Missing = Expected - Actual,
+ {S2, Acc2, Try2} =
+ if
+ Try < 0 ->
+ {S#state{first_event = LastE}, NewEvents ++ Acc, -Missing};
+ true ->
+ TmpEvents = lists:reverse(NewEvents),
+ {S#state{last_event = LastE}, Acc ++ TmpEvents, Missing}
+ end,
+ if
+ Missing =/= 0, PrevKey =/= LastE#e.key ->
+ do_collect_more_events(S2, Try2, LastE, Acc2);
+ true ->
+ {S2, Acc2}
+ end.
+
+collect_event(Event, {S, Incr, Order, Active, FilterFun, #e{pos = PrevPos}, Events}) ->
+ Key = et_collector:make_key(Order, Event),
+ E = #e{event = Event, key = Key, pos = PrevPos + Incr},
+ {LastE, Events2} =
+ case catch FilterFun(Event) of
+ true ->
+ case is_hidden(Event#event.from, Event#event.to, S) of
+ true ->
+ {E, Events};
+ false ->
+ {E, [E | Events]}
+ end;
+ {true, Event2} ->
+ Key2 = et_collector:make_key(Order, Event2),
+ E2 = E#e{event = Event2, key = Key2},
+ case is_hidden(Event2#event.from, Event2#event.to, S) of
+ true ->
+ {E2, Events};
+ false ->
+ {E2, [E2 | Events]}
+ end;
+ false ->
+ {E, Events};
+ Bad ->
+ Contents = {bad_filter, S#state.active_filter, Bad, Event},
+ Event2 = Event#event{contents = Contents,
+ from = bad_filter,
+ to = bad_filter},
+ E2 = E#e{event = Event2},
+ {E2, [E2 | Events]}
+ end,
+ {S, Incr, Order, Active, FilterFun, LastE, Events2}.
+
+display_event(#e{event = Event} = E, S, DC)
+ when Event#event.detail_level < S#state.detail_level ->
+ {FromRefresh, From} = ensure_actor(Event#event.from, S, DC),
+ {FromName, FromPos, S2} = From,
+ {ToRefresh, To} = ensure_actor(Event#event.to, S2, DC),
+ {ToName, ToPos, S3} = To,
+ S4 =
+ if
+ FromRefresh =/= false, ToRefresh =/= false ->
+ S3#state{refresh_needed = true,
+ events = queue_in(E, S3#state.events)};
+ FromName =:= ToName ->
+ case S#state.hide_actions of
+ true ->
+ S3;
+ false ->
+ Label = name_to_string(Event#event.label),
+ draw_named_arrow(Label, FromName, ToName, FromPos, ToPos, E, S3, DC)
+ end;
+ true ->
+ Label = name_to_string(Event#event.label),
+ draw_named_arrow(Label, FromName, ToName, FromPos, ToPos, E, S3, DC)
+ end,
+ S4;
+display_event(#e{}, S, _DC) ->
+ S.
+
+draw_named_arrow(Label, FromName, ToName, FromPos, ToPos, E, S, DC) ->
+ case S#state.y_pos + (?incr_y * S#state.scale) of
+ _ when S#state.hide_actors =:= true, FromName =:= ?unknown ->
+ S;
+ _ when S#state.hide_actors =:= true, ToName =:= ?unknown ->
+ S;
+ Y when Y > S#state.canvas_height ->
+ S#state{refresh_needed = true,
+ events = queue_in(E, S#state.events)};
+ Y ->
+ S2 = S#state{y_pos = Y, events = queue_in(E, S#state.events)},
+ S3 = draw_arrow(FromPos, ToPos, S2, DC),
+ draw_label(Label, FromName, ToName, FromPos, ToPos, S3, DC)
+ end.
+
+draw_arrow(Pos, Pos, S, _DC) ->
+ S;
+draw_arrow(FromPos, ToPos, S, DC) ->
+ Y = S#state.y_pos,
+ wxPen:setColour(S#state.pen, ?wxBLACK),
+ wxDC:setPen(DC, S#state.pen),
+ wxDC:drawLine(DC, {FromPos , Y}, {ToPos, Y}),
+
+ %% Draw arrow head
+ Radians = calc_angle({FromPos, Y}, {ToPos, Y}),
+ Len = 5,
+ Radians2 = Radians + 3.665191429188092,
+ Radians3 = Radians + 2.617993877991494,
+ {X3, Y3} = calc_point({ToPos, Y}, Len, Radians2),
+ {X4, Y4} = calc_point({ToPos, Y}, Len, Radians3),
+ Points = [{round(ToPos), round(Y)},
+ {round(X3), round(Y3)},
+ {round(X4), round(Y4)}],
+ wxBrush:setColour(S#state.brush, ?wxBLACK),
+ wxDC:setBrush(DC, S#state.brush),
+ wxDC:drawPolygon(DC, Points, []),
+ S.
+
+ %% Calclulate angle in radians for a line between two points
+calc_angle({X1, Y1}, {X2, Y2}) ->
+ math:atan2((Y2 - Y1), (X2 - X1)).
+
+ %% Calc new point at a given distance and angle from another point
+calc_point({X, Y}, Length, Radians) ->
+ X2 = round(X + Length * math:cos(Radians)),
+ Y2 = round(Y + Length * math:sin(Radians)),
+ {X2, Y2}.
+
+draw_label(Label, FromName, ToName, FromPos, ToPos, S, DC) ->
+ Color =
+ if
+ FromName =:= ?unknown,
+ ToName =:= ?unknown -> {2, 71, 254};% blue
+ FromName =:= ?unknown -> {255,126,0}; % orange
+ ToName =:= ?unknown -> {255,126,0}; % orange
+ FromPos =:= ToPos -> {2, 71, 254};% blue
+ true -> {227,38, 54} % red
+ end,
+ Scale = S#state.scale,
+ X = lists:min([FromPos, ToPos]) + (6 * Scale),
+ Y = S#state.y_pos,
+ write_text(Label, X, Y, Color, S#state.normal_font, S, DC),
+ S.
+
+draw_all_actors(S, DC) ->
+ Scale = S#state.scale,
+ Fun = fun(A, X) ->
+ case draw_actor(A, X, S, DC) of
+ true ->
+ X + (?incr_x * Scale);
+ false ->
+ X
+ end
+ end,
+ lists:foldl(Fun, ?initial_x * Scale, S#state.actors),
+ S.
+
+%% Returns: {NeedsRefreshBool, {ActorPos, NewsS, NewActors}}
+ensure_actor(Name, S, DC) ->
+ do_ensure_actor(Name, S, S#state.actors, 0, DC).
+
+do_ensure_actor(Name, S, [H | _], N, _DC) when H#actor.name =:= Name ->
+ Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
+ {false, {Name, Pos, S}};
+do_ensure_actor(Name, S, [H | T], N, DC) ->
+ if
+ S#state.hide_actors, H#actor.exclude ->
+ do_ensure_actor(Name, S, T, N, DC);
+ true ->
+ do_ensure_actor(Name, S, T, N + 1, DC)
+ end;
+do_ensure_actor(Name, S, [], N, DC) ->
+ %% A brand new actor, let's see if it does fit
+ Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
+ MaxActors = S#state.max_actors,
+ if
+ is_integer(MaxActors), N > MaxActors ->
+ %% Failed on max_actors limit, put into unknown
+ %% Assume that unknown always is in actor list
+ ensure_actor(?unknown, S, DC);
+ Pos > (S#state.canvas_width - ((?initial_x - 15) * S#state.scale)) ->
+ %% New actor does not fit in canvas, refresh needed
+ A = create_actor(Name),
+ draw_actor(A, Pos, S, DC),
+ {true, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}};
+ true ->
+ %% New actor fits in canvas. Draw the new actor.
+ A = create_actor(Name),
+ draw_actor(A, Pos, S, DC),
+ {false, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}}
+ end.
+
+draw_actor(A, LineX, S, DC) ->
+ if
+ S#state.hide_actors, A#actor.exclude ->
+ false;
+ true ->
+ Scale = S#state.scale,
+ TextX = LineX - (5 * Scale),
+ {TextY, LineTopY, LineBotY} = calc_y(S),
+ Color =
+ case A#actor.name of
+ ?unknown -> {255,126,0};% orange
+ _ -> {227,38,54} % red
+ end,
+ {String, Font} =
+ if
+ S#state.context =:= display, A#actor.exclude ->
+ {"(" ++ A#actor.string ++ ")", S#state.normal_font};
+ S#state.context =:= display, A#actor.include ->
+ {"[" ++ A#actor.string ++ "]", S#state.bold_font};
+ true ->
+ {A#actor.string, S#state.normal_font}
+ end,
+ write_text(String, TextX, TextY, Color, Font, S, DC),
+ wxPen:setColour(S#state.pen, Color),
+ wxDC:setPen(DC, S#state.pen),
+ wxDC:drawLines(DC, [{LineX, LineTopY}, {LineX, LineBotY}]),
+ true
+ end.
+
+calc_y(#state{canvas_height = Height, scale = Scale}) ->
+ TextY = ?initial_y * Scale,
+ LineTopY = round(TextY + ((?incr_y / 2) * Scale)),
+ LineBotY = Height,
+ %% LineBotY = round(Height - ((?incr_y / 2) * Scale)),
+ {TextY, LineTopY, LineBotY}.
+
+display_all(S) ->
+ Actors = S#state.actors,
+ Actors2 = [A#actor{include = false, exclude = false} || A <- Actors],
+ S2 = S#state{actors = Actors2,
+ display_all = true,
+ hide_actions = false,
+ hide_actors = false},
+ wxCheckBox:setValue(S2#state.hide_actions_box, S2#state.hide_actions),
+ wxCheckBox:setValue(S2#state.hide_actors_box, S2#state.hide_actors),
+ revert_main_window(S2).
+
+is_hidden(A, S) ->
+ case S#state.display_all of
+ true ->
+ A#actor.exclude;
+ false ->
+ A#actor.exclude orelse not A#actor.include
+ end.
+
+is_hidden(From, To, S) ->
+ Actors = S#state.actors,
+ DisplayAll = S#state.display_all,
+ FromMatch = lists:keysearch(From, #actor.name, Actors),
+ ToMatch = lists:keysearch(To, #actor.name, Actors),
+ case {FromMatch, ToMatch} of
+ {false, false} ->
+ not DisplayAll;
+ {false, {value, T}} ->
+ is_hidden(T, S);
+ {{value, F}, false} ->
+ is_hidden(F, S);
+ {{value, F}, {value, T}} when DisplayAll ->
+ is_hidden(F, S) orelse is_hidden(T, S);
+ {{value, F}, {value, T}} when F#actor.include; T#actor.include ->
+ F#actor.exclude orelse T#actor.exclude;
+ {{value, _F}, {value, _T}}->
+ true
+ end.
+
+move_actor(From, To, Actors, S) ->
+ Pos = #actor.name,
+ ToName = To#actor.name,
+ FromName = From#actor.name,
+ ToIx = actor_index(ToName, Pos, Actors),
+ FromIx = actor_index(FromName, Pos, Actors),
+ if
+ FromIx =/= 0, ToIx =/= 0, ToIx > FromIx ->
+ Actors2 = lists:keydelete(FromName, Pos, Actors),
+ Actors3 = insert_actor_after(From, To, Actors2),
+ S2 = S#state{actors = Actors3},
+ refresh_main_window(S2);
+ FromIx =/= 0, ToIx =/= 0 ->
+ Actors2 = lists:keydelete(FromName, Pos, Actors),
+ Actors3 = insert_actor_before(From, To, Actors2),
+ S2 = S#state{actors = Actors3},
+ refresh_main_window(S2);
+ true ->
+ %% Ignore
+ S
+ end.
+
+insert_actor_after(From, To, [H | T]) ->
+ case To#actor.name =:= H#actor.name of
+ true -> [H, From | T];
+ false -> [H | insert_actor_after(From, To, T)]
+ end;
+insert_actor_after(_From, _To, []) ->
+ [].
+
+insert_actor_before(From, To, [H | T]) ->
+ case To#actor.name =:= H#actor.name of
+ true -> [From, H | T];
+ false -> [H | insert_actor_before(From, To, T)]
+ end;
+insert_actor_before(_From, _To, []) ->
+ [].
+
+actor_index(_Key, _Pos, []) ->
+ 0;
+actor_index(Key, Pos, [H | T]) ->
+ case Key =:= element(Pos, H) of
+ false -> actor_index(Key, Pos, T) + 1;
+ true -> 1
+ end.
+
+y_to_n(Y, S) ->
+ Y2 = ((Y / S#state.scale) - ?initial_y + (?incr_y / 2)),
+ N = round(Y2 / ?incr_y - 0.2),
+ MaxN = queue_length(S#state.events),
+ if
+ N =< 0 -> actor;
+ N > MaxN -> actor;
+ true -> {event, N}
+ end.
+
+x_to_n(X, S) ->
+ Scale = S#state.scale,
+ Len = length(S#state.actors),
+ X2 = X - (?initial_x * Scale),
+ N = X2 / (?incr_x * Scale),
+ N2 = trunc(N + 1.5),
+ if
+ N2 > Len -> Len;
+ N2 < 1 -> 1;
+ true -> N2
+ end.
+
+write_text(Text, X, Y, Color, Font, S, DC) ->
+ wxDC:setFont(DC, Font),
+ wxDC:setTextForeground(DC, Color),
+ wxDC:drawText(DC, Text, {X, round(Y - (?incr_y * S#state.scale / 2))-3}).
+
+do_open_event(S, N) ->
+ Events = queue_to_list(S#state.events),
+ S2 = S#state{events = list_to_queue(Events)},
+ case catch lists:nth(N, Events) of
+ {'EXIT', _} ->
+ {error, {no_such_event, N}};
+ #e{key = Key} ->
+ Pid = S#state.collector_pid,
+ Fun = fun create_contents_window/2,
+ Prev = et_collector:iterate(Pid, Key, -1),
+ {S2, Res} =
+ if
+ Prev =:= Key ->
+ et_collector:iterate(Pid, first, 1, Fun, {S2, []});
+ true ->
+ et_collector:iterate(Pid, Prev, 1, Fun, {S2, []})
+ end,
+ case Res of
+ [] ->
+ {error, no_contents_viewer_started};
+ [Single] ->
+ Single;
+ Multi ->
+ {error, {too_many, Multi}}
+ end
+ end.
+
+create_contents_window(Event, {S, Res}) ->
+ Options = [{viewer_pid, self()},
+ {event, Event},
+ {event_order, S#state.event_order},
+ {active_filter, S#state.active_filter},
+ {wx_debug, S#state.wx_debug}
+ | S#state.filters],
+ case catch et_wx_contents_viewer:start_link(Options) of
+ {ok, Pid} ->
+ {S, [{ok, Pid} | Res]};
+ {error, Reason} ->
+ ok = error_logger:format("~p(~p): create_contents_window(~p) ->~n ~p~n",
+ [?MODULE, self(), Options, Reason]),
+ {S, [{error, Reason} | Res]};
+ Stuff ->
+ {S, [{error, {stuff, Stuff}} | Res]}
+ end.
+
+print_setup(S) ->
+ S2 = #state{print_psdd = PSDD0, print_d = PD0} = init_printers(S),
+
+ wxPageSetupDialogData:setPrintData(PSDD0, PD0),
+ PSD = wxPageSetupDialog:new(S#state.frame, [{data,PSDD0}]),
+ wxPageSetupDialog:showModal(PSD),
+
+ PSDD1 = wxPageSetupDialog:getPageSetupData(PSD),
+ PD1 = wxPageSetupDialogData:getPrintData(PSDD1),
+
+ %% Create new objects using copy constructor
+ PD = wxPrintData:new(PD1),
+ PsDD = wxPageSetupDialogData:new(PSDD1),
+ wxPageSetupDialog:destroy(PSD),
+ wxPageSetupDialogData:destroy(PSDD0),
+ wxPrintData:destroy(PD0),
+ S2#state{print_psdd=PsDD, print_d=PD}.
+
+print(#state{print_d = undefined, print_psdd = undefined} = S, Scope) ->
+ S2 = print_setup(S),
+ print(S2, Scope);
+print(#state{print_psdd = PSDD, print_d = PD} = S, Scope) ->
+ PDD = wxPrintDialogData:new(PD),
+ wxPrintDialogData:enablePrintToFile(PDD, true),
+ wxPrintDialogData:enablePageNumbers(PDD, true),
+ wxPrintDialogData:enableSelection(PDD, true),
+ Tab = ets:new(?MODULE, [public]),
+ GetPageInfo =
+ fun(This) ->
+ {_, _, PW, PH} = wxPrintout:getPaperRectPixels(This),
+ PrinterS = S#state{context = printer,
+ canvas_width = PW,
+ canvas_height = PH},
+ EventsPerPage = events_per_page(PrinterS, PH),
+ PagedEvents = paged_events(PrinterS, Scope, EventsPerPage),
+ [ets:insert(Tab, PE) || PE <- PagedEvents],
+ ets:insert(Tab, PrinterS),
+ NumPages = length(PagedEvents),
+ {1, NumPages, 1, NumPages}
+ end,
+ HasPage =
+ fun(_This, Page) ->
+ Size = ets:info(Tab, size),
+ NumPages = Size - 1,
+ (Page >= 1) andalso (Page =< NumPages)
+ end,
+ OnPrintPage =
+ fun(This, Page) ->
+ wxPrintout:mapScreenSizeToPageMargins(This, PSDD),
+ [PrinterS] = ets:lookup(Tab, state),
+ Events = ets:lookup_element(Tab, Page, 2),
+ DC = wxPrintout:getDC(This),
+ PrinterS2 = draw_all_actors(PrinterS, DC),
+ PrinterS3 = PrinterS2#state{y_pos = ?initial_y * PrinterS2#state.scale},
+ lists:foldl(fun(E, State) -> display_event(E, State, DC) end,
+ PrinterS3,
+ Events),
+ true
+ end,
+ Printout1 = wxPrintout:new("Print", OnPrintPage,
+ [{getPageInfo, GetPageInfo}, {hasPage, HasPage}]),
+ Printout2 = wxPrintout:new("Print", OnPrintPage,
+ [{getPageInfo, GetPageInfo}, {hasPage, HasPage}]),
+ Preview = wxPrintPreview:new(Printout1, [{printoutForPrinting, Printout2}, {data,PDD}]),
+ case wxPrintPreview:isOk(Preview) of
+ true ->
+ PF = wxPreviewFrame:new(Preview, S#state.frame, []),
+ wxPreviewFrame:centre(PF, [{dir, ?wxBOTH}]),
+ wxPreviewFrame:initialize(PF),
+ wxPreviewFrame:centre(PF),
+ wxPreviewFrame:show(PF),
+ OnClose = fun(_Wx, EventRef) -> ets:delete(Tab), wxEvent:skip(EventRef) end,
+ wxPreviewFrame:connect(PF, close_window, [{callback, OnClose}]);
+ false ->
+ io:format("Could not create preview window.\n"
+ "Perhaps your current printer is not set correctly?~n", []),
+ wxPrintPreview:destroy(Preview),
+ ets:delete(Tab)
+ end,
+ S.
+
+paged_events(S, Scope, EventsPerPage) ->
+ {_, Events} =
+ case Scope of
+ print_one_page ->
+ revert(S#state{events_per_page = EventsPerPage});
+ print_all_pages ->
+ collect_more_events(S, first, S#state.n_events)
+ end,
+ split_list(Events, EventsPerPage).
+
+split_list(List, N) when is_integer(N), N > 0 ->
+ do_split_list(List, N, 1, []).
+
+do_split_list([], _N, _Page, Acc) ->
+ lists:reverse(Acc);
+do_split_list(List, N, Page, Acc) ->
+ {Items, Rest} = pick_n(List, N, []),
+ do_split_list(Rest, N, Page + 1, [{Page, Items} | Acc]).
+
+get_latest_resize(#wx{obj = ObjRef, event = #wxSize{}} = Wx) ->
+ receive
+ #wx{obj = ObjRef, event = #wxSize{}} = Wx2 ->
+ get_latest_resize(Wx2)
+ after 100 ->
+ Wx
+ end.
+
+get_latest_scroll(#wx{obj = ObjRef, event = #wxScroll{type = scroll_changed}} = Wx) ->
+ receive
+ #wx{obj = ObjRef, event = #wxScroll{type = scroll_changed}} = Wx2 ->
+ get_latest_scroll(Wx2)
+ after 100 ->
+ Wx
+ end.
+
+update_scroll_bar(#state{scroll_bar = ScrollBar,
+ status_bar = StatusBar,
+ events_per_page = EventsPerPage,
+ n_events = N} = S) ->
+ Opts = [{refresh, true}],
+ {_, LineTopY, LineBotY} = calc_y(S),
+ Range = LineBotY - LineTopY,
+ EventPos =
+ case event_pos(S) of
+ 1 -> 0;
+ P -> P
+ end,
+ if
+ N =/= 0,
+ EventsPerPage =/= 0 ->
+ PixelsPerEvent = Range / EventsPerPage,
+ Share = EventsPerPage / N,
+ wxScrollBar:setScrollbar(ScrollBar,
+ trunc(EventPos * Share * PixelsPerEvent),
+ round(Share * Range),
+ Range,
+ round(Share * Range),
+ Opts);
+ true ->
+ wxScrollBar:setScrollbar(ScrollBar,
+ 0,
+ Range,
+ Range,
+ Range,
+ Opts)
+ end,
+ wxStatusBar:setStatusText(StatusBar, where_text(S)),
+ S.
+
+events_per_page(S, PageHeight) ->
+ EventsPerPage = ((PageHeight - (?initial_y * S#state.scale)) div (?incr_y * S#state.scale)),
+ lists:max([1, EventsPerPage]).
+
+select_file(Frame, Message, DefaultFile, Style) ->
+ Dialog = wxFileDialog:new(Frame,
+ [{message, Message},
+ {defaultDir, filename:dirname(DefaultFile)},
+ {defaultFile, filename:basename(DefaultFile)},
+ {style, Style}]),
+ Choice =
+ case wxMessageDialog:showModal(Dialog) of
+ ?wxID_CANCEL -> cancel;
+ ?wxID_OK -> {ok, wxFileDialog:getPath(Dialog)}
+ end,
+ wxFileDialog:destroy(Dialog),
+ Choice.
+
+%%%----------------------------------------------------------------------
+%%% String padding of actors
+%%%----------------------------------------------------------------------
+
+opt_create_actor(Name, Tag, S) ->
+ Actors = S#state.actors,
+ New =
+ case lists:keysearch(Name, #actor.name, Actors) of
+ {value, Old} -> Old;
+ false -> create_actor(Name)
+ end,
+ case Tag of
+ include -> New#actor{include = true};
+ exclude -> New#actor{exclude = true}
+ end.
+
+create_actor(Name) ->
+ String = name_to_string(Name),
+ %% PaddedString = pad_string(String, 8),
+ #actor{name = Name, string = String, include = false, exclude = false}.
+
+name_to_string(Name) ->
+ case catch io_lib:format("~s", [Name]) of
+ {'EXIT', _} -> lists:flatten(io_lib:format("~w", [Name]));
+ GoodString -> lists:flatten(GoodString)
+ end.
+
+pad_string(Atom, MinLen) when is_atom(Atom) ->
+ pad_string(atom_to_list(Atom), MinLen);
+pad_string(String, MinLen) when is_integer(MinLen), MinLen >= 0 ->
+ Len = length(String),
+ case Len >= MinLen of
+ true ->
+ String;
+ false ->
+ String ++ lists:duplicate(MinLen - Len, $ )
+ end.
+
+%%%----------------------------------------------------------------------
+%%% Queue management
+%%%----------------------------------------------------------------------
+
+queue_new() ->
+ {0, [], []}.
+
+queue_in(X, {Size, In, Out}) ->
+ {Size + 1, [X | In], Out}.
+
+%% queue_out(Q) ->
+%% case Q of
+%% {Size, In, [H | Out]} -> {{value, H}, {Size - 1, In, Out}};
+%% {Size, [], []} -> {empty, {Size, [], []}};
+%% {Size, In, _} -> queue_out({Size, [], lists:reverse(In)})
+%% end.
+
+queue_to_list({_Size, [], Out}) ->
+ Out;
+queue_to_list({_Size, In, Out}) ->
+ Out ++ lists:reverse(In).
+
+queue_length({Size, _In, _Out}) ->
+ Size.
+
+list_to_queue(List) when is_list(List) ->
+ {length(List), [], List}.
diff --git a/lib/et/src/modules.mk b/lib/et/src/modules.mk
index 8e9dd1a386..8d6c0902fb 100644
--- a/lib/et/src/modules.mk
+++ b/lib/et/src/modules.mk
@@ -1,27 +1,30 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
MODULES = \
et \
et_collector \
- et_contents_viewer \
+ et_gs_contents_viewer \
+ et_gs_viewer \
et_selector \
- et_viewer
+ et_viewer \
+ et_wx_contents_viewer \
+ et_wx_viewer
HRL_FILES = \
../include/et.hrl
diff --git a/lib/et/doc/src/make.dep b/lib/et/test/Makefile
index fae2cd02b3..9aedf96ce9 100644
--- a/lib/et/doc/src/make.dep
+++ b/lib/et/test/Makefile
@@ -1,53 +1,81 @@
-#-*-makefile-*- ; force emacs to enter makefile-mode
+#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2009-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
# ----------------------------------------------------
-# >>>> Do not edit this file <<<<
-# This file was automaticly generated by
-# /home/otp/bin/docdepend
+# Target Specs
# ----------------------------------------------------
+MODULES= \
+ ett \
+ et_wx_SUITE \
+ et_test_lib
+
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+HRL_FILES= et_test_lib.hrl
+
+TARGET_FILES= \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INSTALL_PROGS= $(TARGET_FILES)
# ----------------------------------------------------
-# TeX files that the DVI file depend on
+# Release directory specification
# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/et_test
-book.dvi: book.tex et.tex et_architecture.tex et_collector.tex \
- et_examples.tex et_intro.tex et_selector.tex \
- et_viewer.tex part.tex ref_man.tex
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+#ERL_COMPILE_FLAGS +=
+
+EBIN = .
# ----------------------------------------------------
-# Source inlined when transforming from source to LaTeX
+# Targets
# ----------------------------------------------------
-book.tex: ref_man.xml
+tests debug opt: $(TARGET_FILES)
-et_architecture.tex: ../../examples/et_demo.erl
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f core
-et_examples.tex: ../../examples/et_demo.erl
+docs:
# ----------------------------------------------------
-# Pictures that the DVI file depend on
-# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) et.spec $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_PROGRAM) ett $(INSTALL_PROGS) $(RELSYSDIR)
+# chmod -f -R u+w $(RELSYSDIR)
+# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
-book.dvi: sim_trans.ps sim_trans_contents_viewer_collector.ps \
- sim_trans_contents_viewer_mgr_actors.ps sim_trans_mgr_actors.ps \
- sim_trans_move_actor.ps sim_trans_write_lock.ps
+release_docs_spec:
-book.dvi: live_trans.ps megaco_collector.ps megaco_filter.ps \
- megaco_tracer.ps sim_trans.ps
diff --git a/lib/et/test/README b/lib/et/test/README
new file mode 100644
index 0000000000..4269186c93
--- /dev/null
+++ b/lib/et/test/README
@@ -0,0 +1,30 @@
+
+Testing and running et tests.
+
+Testing gui api/applications can be hard, but we can at least
+test that wxerlang behaves as we expected, i.e. that the api
+is consistent and that it don't crash.
+
+The tests are structured as they are because we want you to
+be able to run them in three different ways.
+ - direct via an erlang shell
+ - via common_test application
+ - via erlang/OTP inhouse ts tool.
+
+To run all the tests compile them and on unix
+run ./ett to create an erlang terminal.
+
+Invoke ett:t(). in the erlang shell to run all regression tests.
+If you want to specific tests invoke ett:t(Module)
+or ett:t(Module, TestCase).
+
+To run all tests including the ones that require manual intervention run.
+ett:t(all, [{user,true}]).
+
+To see every test_case window use
+ett:t(all, [{user,step}]).
+This requires that you manually close each window to step to the
+next test_case.
+
+If you want to run specific test_cases use:
+ett:t({Module,TestCase}, [{user,step}]).
diff --git a/lib/et/test/et.spec b/lib/et/test/et.spec
new file mode 100644
index 0000000000..69cd8d7582
--- /dev/null
+++ b/lib/et/test/et.spec
@@ -0,0 +1,2 @@
+{topcase, {dir, "../et_test"}}.
+
diff --git a/lib/et/test/et_test_lib.erl b/lib/et/test/et_test_lib.erl
new file mode 100644
index 0000000000..b91b63786c
--- /dev/null
+++ b/lib/et/test/et_test_lib.erl
@@ -0,0 +1,329 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-module(et_test_lib).
+-compile(export_all).
+
+-include("et_test_lib.hrl").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_suite(Config) when is_list(Config)->
+ incr_timetrap(Config, 5).
+
+end_per_suite(Config) when is_list(Config)->
+ ok.
+
+incr_timetrap(Config, Times) ->
+ Key = tc_timeout,
+ KeyPos = 1,
+ NewTime =
+ case lists:keysearch(Key, KeyPos, Config) of
+ {value, {Key, OldTime}} ->
+ (timer:minutes(1) + OldTime) * Times;
+ false ->
+ timer:minutes(1) * Times
+ end,
+ lists:keystore(Key, KeyPos, Config, {Key, NewTime}).
+
+set_kill_timer(Config) ->
+ case init:get_argument(et_test_timeout) of
+ {ok, _} ->
+ Config;
+ _ ->
+ Time =
+ case lookup_config(tc_timeout, Config) of
+ [] ->
+ timer:minutes(5);
+ ConfigTime when is_integer(ConfigTime) ->
+ ConfigTime
+ end,
+ WatchDog = test_server:timetrap(Time),
+ [{kill_timer, WatchDog} | Config]
+ end.
+
+reset_kill_timer(Config) ->
+ DogKiller =
+ case get(et_test_server) of
+ true ->
+ fun(P) when is_pid(P) -> P ! stop;
+ (_) -> ok
+ end;
+ _ ->
+ fun(Ref) -> test_server:timetrap_cancel(Ref) end
+ end,
+ case lists:keysearch(kill_timer, 1, Config) of
+ {value, {kill_timer, WatchDog}} ->
+ DogKiller(WatchDog),
+ lists:keydelete(kill_timer, 1, Config);
+ _ ->
+ Config
+ end.
+
+lookup_config(Key,Config) ->
+ case lists:keysearch(Key, 1, Config) of
+ {value,{Key,Val}} ->
+ Val;
+ _ ->
+ []
+ end.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+wx_init_per_suite(Config) ->
+ {_Pid, Ref} =
+ spawn_monitor(fun() ->
+ %% Avoid test case crash if wx master process dies
+ process_flag(trap_exit, true),
+ try
+ case os:type() of
+ {unix,darwin} ->
+ exit({skipped, "Can not test on MacOSX"});
+ {unix, _} ->
+ io:format("DISPLAY ~s~n", [os:getenv("DISPLAY")]),
+ case proplists:get_value(xserver, Config, none) of
+ none -> ignore;
+ Server -> os:putenv("DISPLAY", Server)
+ end;
+ _ ->
+ ignore
+ end,
+ wx:new(),
+ wx:destroy()
+ catch
+ error:undef ->
+ exit({skipped, "No wx compiled for this platform"});
+ _:Reason ->
+ exit({skipped, lists:flatten(io_lib:format("Start wx failed: ~p", [Reason]))})
+ end,
+ exit(normal)
+ end),
+ receive
+ {'DOWN', Ref, _, _, normal} ->
+ init_per_suite(Config);
+ {'DOWN', Ref, _, _, {skipped, _} = Skipped} ->
+ Skipped;
+ {'DOWN', Ref, _, _, Reason} ->
+ exit({wx_init_per_suite, Reason})
+ after timer:minutes(1) ->
+ exit({wx_init_per_suite, timeout})
+ end.
+
+wx_end_per_suite(Config) ->
+ end_per_suite(Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_testcase(_Func, Config) when is_list(Config) ->
+ set_kill_timer(Config),
+ global:register_name(et_global_logger, group_leader()),
+ Config.
+
+end_per_testcase(_Func, Config) when is_list(Config) ->
+ global:unregister_name(et_global_logger),
+ reset_kill_timer(Config),
+ Config.
+
+%% Backwards compatible with test_server
+tc_info(suite) -> [];
+tc_info(doc) -> "".
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Use ?log(Format, Args) as wrapper
+log(Format, Args, LongFile, Line) ->
+ File = filename:basename(LongFile),
+ Format2 = lists:concat([File, "(", Line, ")", ": ", Format]),
+ log(Format2, Args).
+
+log(Format, Args) ->
+ case global:whereis_name(et_global_logger) of
+ undefined ->
+ io:format(user, Format, Args);
+ Pid ->
+ io:format(Pid, Format, Args)
+ end.
+
+verbose(Format, Args, File, Line) ->
+ Arg = et_test_verbose,
+ case get(Arg) of
+ false ->
+ ok;
+ true ->
+ log(Format, Args, File, Line);
+ undefined ->
+ case init:get_argument(Arg) of
+ {ok, List} when is_list(List) ->
+ case lists:last(List) of
+ ["true"] ->
+ put(Arg, true),
+ log(Format, Args, File, Line);
+ _ ->
+ put(Arg, false),
+ ok
+ end;
+ _ ->
+ put(Arg, false),
+ ok
+ end
+ end.
+
+error(Format, Args, File, Line) ->
+ global:send(et_global_logger, {failed, File, Line}),
+ Fail = {filename:basename(File),Line,Args},
+ case global:whereis_name(et_test_case_sup) of
+ undefined -> ignore;
+ Pid -> Pid ! Fail
+ %% global:send(et_test_case_sup, Fail),
+ end,
+ log("<ERROR>~n" ++ Format, Args, File, Line).
+
+
+pick_msg() ->
+ receive
+ Message -> Message
+ after 4000 -> timeout
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Utility functions
+
+user_available(Config) ->
+ false /= proplists:get_value(user, Config, false).
+
+
+wx_destroy(Frame, Config) ->
+ case proplists:get_value(user, Config, false) of
+ false ->
+ timer:sleep(100),
+ ?m(ok, wxFrame:destroy(Frame)),
+ ?m(ok, wx:destroy());
+ true ->
+ timer:sleep(500),
+ ?m(ok, wxFrame:destroy(Frame)),
+ ?m(ok, wx:destroy());
+ step -> %% Wait for user to close window
+ ?m(ok, wxEvtHandler:connect(Frame, close_window, [{skip,true}])),
+ wait_for_close()
+ end.
+
+wait_for_close() ->
+ receive
+ #wx{event=#wxClose{}} ->
+ ?log("Got close~n",[]),
+ ?m(ok, wx:destroy());
+ #wx{obj=Obj, event=Event} ->
+ try
+ Name = wxTopLevelWindow:getTitle(Obj),
+ ?log("~p Event: ~p~n", [Name, Event])
+ catch _:_ ->
+ ?log("Event: ~p~n", [Event])
+ end,
+ wait_for_close();
+ Other ->
+ ?log("Unexpected: ~p~n", [Other]),
+ wait_for_close()
+ end.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% A small test server, which can be run standalone in a shell
+
+run_test(Test = {_,_},Config) ->
+ run_test([Test],Config);
+run_test([{Module, TC} | Rest], Config) ->
+ log("\n\n=== Eval test suite: ~w ===~n", [Module]),
+ case catch Module:init_per_suite(Config) of
+ {skipped, Reason} ->
+ log("Test suite skipped: ~s~n", [Reason]),
+ [{skipped, Reason}];
+ NewConfig when is_list(NewConfig) ->
+ Res =
+ if
+ TC =:= all ->
+ [do_run_test(Module, Test, NewConfig) || Test <- Module:all()];
+ is_list(TC) ->
+ [do_run_test(Module, Test, NewConfig) || Test <- TC];
+ true ->
+ [do_run_test(Module, TC, NewConfig)]
+ end,
+ Module:end_per_suite(NewConfig),
+ Res ++ run_test(Rest, NewConfig);
+ Error ->
+ ?error("Test suite skipped: ~w~n", [Error]),
+ [{skipped, Error}]
+ end;
+run_test([], _Config) ->
+ [].
+
+do_run_test(Module, all, Config) ->
+ All = [{Module, Test} || Test <- Module:all()],
+ run_test(All, Config);
+do_run_test(Module, TestCase, Config) ->
+ log("Eval test case: ~w~n", [{Module, TestCase}]),
+ Sec = timer:seconds(1) * 1000,
+ {T, Res} =
+ timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]),
+ log("Tested ~w in ~w sec~n", [TestCase, T div Sec]),
+ {T div Sec, Res}.
+
+eval_test_case(Mod, Fun, Config) ->
+ flush(),
+ global:register_name(et_test_case_sup, self()),
+ Flag = process_flag(trap_exit, true),
+ Pid = spawn_link(?MODULE, test_case_evaluator, [Mod, Fun, [Config]]),
+ R = wait_for_evaluator(Pid, Mod, Fun, Config),
+ global:unregister_name(et_test_case_sup),
+ process_flag(trap_exit, Flag),
+ R.
+
+test_case_evaluator(Mod, Fun, [Config]) ->
+ NewConfig = Mod:init_per_testcase(Fun, Config),
+ R = apply(Mod, Fun, [NewConfig]),
+ Mod:fin_per_testcase(Fun, NewConfig),
+ exit({test_case_ok, R}).
+
+wait_for_evaluator(Pid, Mod, Fun, Config) ->
+ receive
+ {'EXIT', Pid, {test_case_ok, _PidRes}} ->
+ Errors = flush(),
+ Res =
+ case Errors of
+ [] -> ok;
+ Errors -> failed
+ end,
+ {Res, {Mod, Fun}, Errors};
+ {'EXIT', Pid, {skipped, Reason}} ->
+ log("<WARNING> Test case ~w skipped, because ~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {skip, {Mod, Fun}, Reason};
+ {'EXIT', Pid, Reason} ->
+ log("<ERROR> Eval process ~w exited, because\n\t~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {crash, {Mod, Fun}, Reason}
+ end.
+
+flush() ->
+ receive Msg -> [Msg | flush()]
+ after 0 -> []
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/et/test/et_test_lib.hrl b/lib/et/test/et_test_lib.hrl
new file mode 100644
index 0000000000..0d75318d99
--- /dev/null
+++ b/lib/et/test/et_test_lib.hrl
@@ -0,0 +1,90 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-include_lib("wx/include/wx.hrl").
+
+-define(log(Format,Args), et_test_lib:log(Format,Args,?FILE,?LINE)).
+-define(warning(Format,Args), ?log("<WARNING>\n " ++ Format,Args)).
+-define(error(Format,Args), et_test_lib:error(Format,Args,?FILE,?LINE)).
+-define(verbose(Format,Args), et_test_lib:verbose(Format,Args,?FILE,?LINE)).
+
+-define(fatal(Format,Args),
+ ?error(Format, Args),
+ exit({test_case_fatal, Format, Args, ?FILE, ?LINE})).
+
+-define(skip(Format,Args),
+ ?warning(Format, Args),
+ exit({skipped, ?flat_format(Format, Args)})).
+
+-define(ignore(Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ ?verbose("ok: ~p\n",[AcTuAlReS])
+ end()).
+
+-define(msym(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ et_test_lib:error("Not matching actual result was:\n ~p \nExpected ~s\n",
+ [AcTuAlReS, ??ExpectedRes],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
+
+-define(m(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ et_test_lib:error("Not matching actual result was:\n\t~p \nExpected:\n\t~p\n",
+ [AcTuAlReS, ExpectedRes],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
+
+-define(m_receive(ExpectedMsg),
+ ?m(ExpectedMsg,et_test_lib:pick_msg())).
+
+-define(m_multi_receive(ExpectedMsgs),
+ fun() ->
+ TmPeXpCtEdMsGs = lists:sort(ExpectedMsgs),
+ AcTuAlReS =
+ lists:sort(lists:map(fun(_) ->
+ et_test_lib:pick_msg()
+ end, TmPeXpCtEdMsGs)),
+ case AcTuAlReS of
+ TmPeXpCtEdMsGs ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ et_test_lib:error("Not matching actual result was:\n ~p \nExpected ~p\n",
+ [AcTuAlReS, ExpectedMsgs],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
diff --git a/lib/et/test/et_wx_SUITE.erl b/lib/et/test/et_wx_SUITE.erl
new file mode 100644
index 0000000000..1a16ca69a3
--- /dev/null
+++ b/lib/et/test/et_wx_SUITE.erl
@@ -0,0 +1,100 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-module(et_wx_SUITE).
+
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("et_test_lib.hrl").
+
+%% Initialization functions.
+init_per_suite(Config) ->
+ et_test_lib:wx_init_per_suite(Config).
+
+end_per_suite(Config) ->
+ et_test_lib:wx_end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ et_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ et_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ et_test_lib:end_per_testcase(Func,Config).
+
+%% SUITE specification
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ start_all_windows
+ ].
+
+%% The test cases
+
+%% Display all windows and see if something crashes
+start_all_windows(TestInfo) when is_atom(TestInfo) ->
+ et_test_lib:tc_info(TestInfo);
+start_all_windows(_Config) ->
+ process_flag(trap_exit, true),
+ {ok, ViewerPid} = ?msym({ok, _}, et_viewer:start_link([])),
+ CollectorPid = et_viewer:get_collector_pid(ViewerPid),
+ ?msym({ok, _}, et_collector:report_event(CollectorPid,
+ 60,
+ some_from_actor,
+ some_to_actor,
+ some_label,
+ "Some details")),
+ timer:sleep(timer:seconds(1)),
+
+ {ok, EventPid1} = ?msym({ok, _}, et_viewer:open_event(ViewerPid, 1)),
+ {ok, EventPid2} = ?msym({ok, _}, et_viewer:open_event(ViewerPid, 1)),
+ timer:sleep(timer:seconds(10)),
+
+ ?msym(alive, process_state(ViewerPid)),
+ ?msym(alive, process_state(CollectorPid)),
+ ?msym(alive, process_state(EventPid1)),
+ ?msym(alive, process_state(EventPid2)),
+
+ ?m(ok, et_wx_contents_viewer:stop(EventPid1)),
+ timer:sleep(timer:seconds(1)),
+
+ ?msym(alive, process_state(ViewerPid)),
+ ?msym(alive, process_state(CollectorPid)),
+ ?msym(dead, process_state(EventPid1)),
+ ?msym(alive, process_state(EventPid2)),
+
+ ?m(ok, et_viewer:stop(ViewerPid)),
+ timer:sleep(timer:seconds(1)),
+
+ ?msym(dead, process_state(ViewerPid)),
+ ?msym(dead, process_state(CollectorPid)),
+ ?msym(dead, process_state(EventPid1)),
+ ?msym(dead, process_state(EventPid2)),
+
+ ?m([], et_test_lib:flush()),
+
+ ok.
+
+process_state(Pid) ->
+ case process_info(Pid, group_leader) of
+ {group_leader, _} -> alive;
+ undefined -> dead
+ end.
diff --git a/lib/et/test/ett b/lib/et/test/ett
new file mode 100755
index 0000000000..da2443df61
--- /dev/null
+++ b/lib/et/test/ett
@@ -0,0 +1,55 @@
+#! /bin/sh -f
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2009-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+# Usage: ett [-cerl] <args to erlang startup script>
+
+emu=erl
+while [ $# -gt 0 ]; do
+ case "$1" in
+ "-cerl")
+ shift
+ emu=cerl
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+log=test_log_$$
+latest=test_log_latest
+args=${1+"$@"}
+
+erlcmd="$emu -sname test_server -smp -pa ../../et/ebin $p $args -et_test_verbose true -et_test_timeout"
+
+echo "Give the following command in order to see the outcome:"
+echo ""
+echo " less $log"
+
+rm "$latest" 2>/dev/null
+ln -s "$log" "$latest"
+touch "$log"
+
+ostype=`uname -s`
+if [ "$ostype" = "SunOS" ] ; then
+ /usr/openwin/bin/xterm -T "Testing et" -l -lf "$log" -e $erlcmd &
+else
+ xterm -T "Testing et" -e script -f -c "$erlcmd" "$log" &
+fi
+
+tail -f "$log" | egrep 'Eval|<ERROR>|NYI'
diff --git a/lib/et/test/ett.erl b/lib/et/test/ett.erl
new file mode 100644
index 0000000000..1896e65842
--- /dev/null
+++ b/lib/et/test/ett.erl
@@ -0,0 +1,154 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-module(ett).
+-compile(export_all).
+
+%% Modules or suites can be shortcuts, for example wx expands to et_wx_SUITE.
+%%
+%% t(Tests) run et testcases.
+%% Tests can be module, {module, test_case} or [module|{module,test_case}]
+
+t() ->
+ t(read_test_case()).
+t(Test) ->
+ t(Test, []).
+
+t(Mod, TC) when is_atom(Mod), is_atom(TC) ->
+ t({Mod,TC}, []);
+t(all, Config) when is_list(Config) ->
+ Fs = filelib:wildcard("et_*_SUITE.erl"),
+ t([list_to_atom(filename:rootname(File)) || File <- Fs], Config);
+t(Test,Config) when is_list(Config) ->
+ Tests = resolve(Test),
+ write_test_case(Test),
+ Res = et_test_lib:run_test(Tests, Config),
+ append_test_case_info(Test, Res).
+
+user() ->
+ user(read_test_case()).
+user(Mod) ->
+ t(Mod, [{user,step}]).
+user(Mod,Tc) when is_atom(Tc) ->
+ t({Mod,Tc}, [{user,step}]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Resolves the name of test suites and test cases
+%% according to the alias definitions. Single atoms
+%% are assumed to be the name of a test suite.
+
+resolve(Suite0) when is_atom(Suite0) ->
+ case alias(Suite0) of
+ Suite when is_atom(Suite) ->
+ {Suite, all};
+ {Suite, Case} ->
+ {Suite, Case}
+ end;
+resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) ->
+ case alias(Suite0) of
+ Suite when is_atom(Suite) ->
+ {Suite, Case};
+ {Suite, Case2} ->
+ {Suite, Case2}
+ end;
+resolve(List) when is_list(List) ->
+ [resolve(Case) || Case <- List].
+
+alias(Suite) when is_atom(Suite) ->
+ Str = atom_to_list(Suite),
+ case {Str, lists:reverse(Str)} of
+ {"et" ++ _, "ETIUS" ++ _} ->
+ Suite;
+ _ ->
+ list_to_atom("et_" ++ Str ++ "_SUITE")
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+config_fname() ->
+ "et_test_case_config".
+
+%% Read default config file
+read_config() ->
+ Fname = config_fname(),
+ et_test_lib:log("Consulting file ~s...~n", [Fname]),
+ case file:consult(Fname) of
+ {ok, Config} ->
+ et_test_lib:log("Read config ~w~n", [Config]),
+ Config;
+ _Error ->
+ Config = et_test_lib:default_config(),
+ et_test_lib:log("<>WARNING<> Using default config: ~w~n", [Config]),
+ Config
+ end.
+
+%% Write new default config file
+write_config(Config) when is_list(Config) ->
+ Fname = config_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ write_list(Fd, Config),
+ file:close(Fd).
+
+write_list(Fd, [H | T]) ->
+ ok = io:format(Fd, "~p.~n",[H]),
+ write_list(Fd, T);
+write_list(_, []) ->
+ ok.
+
+test_case_fname() ->
+ "et_test_case_info".
+
+%% Read name of test case
+read_test_case() ->
+ Fname = test_case_fname(),
+ case file:open(Fname, [read]) of
+ {ok, Fd} ->
+ Res = io:read(Fd, []),
+ file:close(Fd),
+ case Res of
+ {ok, TestCase} ->
+ et_test_lib:log("Using test case ~w from file ~s~n",
+ [TestCase, Fname]),
+ TestCase;
+ {error, _} ->
+ default_test_case(Fname)
+ end;
+ {error, _} ->
+ default_test_case(Fname)
+ end.
+
+default_test_case(Fname) ->
+ TestCase = all,
+ et_test_lib:log("<>WARNING<> Cannot read file ~s, "
+ "using default test case: ~w~n",
+ [Fname, TestCase]),
+ TestCase.
+
+write_test_case(TestCase) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ file:close(Fd).
+
+append_test_case_info(TestCase, TestCaseInfo) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, [read, write]),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ ok = io:format(Fd, "~p.~n",[TestCaseInfo]),
+ file:close(Fd),
+ TestCaseInfo.
diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk
index c6d58e2055..b7d65b12a2 100644
--- a/lib/et/vsn.mk
+++ b/lib/et/vsn.mk
@@ -1,23 +1,24 @@
# This is an -*-makefile-*- file.
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
-ET_VSN = 1.3.3
+ET_VSN = 1.4
+TICKETS = OTP-8058
-TICKETS = OTP-8201
+TICKETS_1_3_3 = OTP-8201
TICKETS_1_3_2 = OTP-8078
TICKETS_1_3_1 = OTP-7830
diff --git a/lib/eunit/doc/src/Makefile b/lib/eunit/doc/src/Makefile
index faf2f9a847..19be96d763 100644
--- a/lib/eunit/doc/src/Makefile
+++ b/lib/eunit/doc/src/Makefile
@@ -123,11 +123,10 @@ man: $(MAN3_FILES)
gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
$(XML_REF3_FILES):
- docb_gen -def vsn $(EUNIT_VSN) -includes $(EUNIT_INC_DIR) $(EUNIT_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EUNIT_VSN) -i $(EUNIT_INC_DIR) $(EUNIT_DIR)/$(@:%.xml=%.erl)
$(XML_CHAPTER_FILES):
- docb_gen -chapter -def vsn $(EUNIT_VSN) ../overview.edoc
-
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EUNIT_VSN) -chapter ../overview.edoc
info:
@echo "XML_PART_FILES: $(XML_PART_FILES)"
diff --git a/lib/eunit/test/Makefile b/lib/eunit/test/Makefile
index 83fca0ade4..74d485d1cc 100644
--- a/lib/eunit/test/Makefile
+++ b/lib/eunit/test/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2009-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
@@ -50,7 +50,7 @@ EBIN = .
make_emakefile:
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) \
- $(MODULES) >> $(EMAKEFILE)
+ $(MODULES) > $(EMAKEFILE)
tests debug opt: make_emakefile
erl $(ERL_MAKE_FLAGS) -make
diff --git a/lib/hipe/Makefile b/lib/hipe/Makefile
index be3a618e34..10bf82b2d7 100644
--- a/lib/hipe/Makefile
+++ b/lib/hipe/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
SHELL=/bin/sh
@@ -42,15 +42,13 @@ endif
#
include $(ERL_TOP)/make/otp_subdir.mk
-# This overrides the default recursive-make edocs target in otp_subdir.mk
-# It is not pretty, but it will have to do for now.
-docs:
+# The overriding docs target have been removed so the default make rules work properly.
+
+edocs:
@if [ -d $(ERL_TOP)/lib/edoc/ebin ]; then \
erl -noshell -pa $(ERL_TOP)/lib/edoc/ebin $(ERL_TOP)/lib/syntax_tools/ebin $(ERL_TOP)/lib/xmerl/ebin -run edoc_run application 'hipe' '"."' '[new,no_packages]' -s init stop ; \
fi
-edocs: docs
-
all-subdirs:
-for dir in $(SUB_DIRECTORIES); do \
(cd $$dir; $(MAKE) $(MAKETARGET) EBIN=../ebin; cd ..); \
diff --git a/lib/hipe/amd64/Makefile b/lib/hipe/amd64/Makefile
index 93e5f086d9..58377e5349 100644
--- a/lib/hipe/amd64/Makefile
+++ b/lib/hipe/amd64/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -80,7 +80,10 @@ ERL_COMPILE_FLAGS += -DHIPE_AMD64 +warn_exported_vars
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/arm/Makefile b/lib/hipe/arm/Makefile
index 571a1da0fc..3f60cd77cc 100644
--- a/lib/hipe/arm/Makefile
+++ b/lib/hipe/arm/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -81,7 +81,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/cerl/Makefile b/lib/hipe/cerl/Makefile
index fb7ca1153b..7fcc44d27d 100644
--- a/lib/hipe/cerl/Makefile
+++ b/lib/hipe/cerl/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2003-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2003-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -73,7 +73,10 @@ ERL_COMPILE_FLAGS += +inline +warn_exported_vars +warn_unused_import +warn_missi
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/flow/Makefile b/lib/hipe/flow/Makefile
index 5b9d0b7582..91dcfda6f5 100644
--- a/lib/hipe/flow/Makefile
+++ b/lib/hipe/flow/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -73,7 +73,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/icode/Makefile b/lib/hipe/icode/Makefile
index de37c4e4c4..eced90b0ec 100644
--- a/lib/hipe/icode/Makefile
+++ b/lib/hipe/icode/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -91,7 +91,10 @@ ERL_COMPILE_FLAGS += +warn_unused_import +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/main/Makefile b/lib/hipe/main/Makefile
index 0ac522b1b2..a14c9c3ca4 100644
--- a/lib/hipe/main/Makefile
+++ b/lib/hipe/main/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -83,7 +83,11 @@ $(EBIN)/hipe_main.beam: hipe.hrl ../icode/hipe_icode.hrl #../rtl/hipe_rtl.hrl
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES) $(DOC_FILES) $(HRL_FILES)
diff --git a/lib/hipe/misc/Makefile b/lib/hipe/misc/Makefile
index d5c395855a..98a69d62c7 100644
--- a/lib/hipe/misc/Makefile
+++ b/lib/hipe/misc/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -76,7 +76,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/opt/Makefile b/lib/hipe/opt/Makefile
index 972cf63944..74fde26c0b 100644
--- a/lib/hipe/opt/Makefile
+++ b/lib/hipe/opt/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -71,7 +71,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/ppc/Makefile b/lib/hipe/ppc/Makefile
index 0857043527..f24139e34b 100644
--- a/lib/hipe/ppc/Makefile
+++ b/lib/hipe/ppc/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -83,7 +83,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/regalloc/Makefile b/lib/hipe/regalloc/Makefile
index 5ab70d1837..386f3589c6 100644
--- a/lib/hipe/regalloc/Makefile
+++ b/lib/hipe/regalloc/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -84,7 +84,11 @@ ERL_COMPILE_FLAGS += +warn_exported_vars# +warn_missing_spec +warn_untyped_recor
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/sparc/Makefile b/lib/hipe/sparc/Makefile
index efd4996046..f25212a89b 100644
--- a/lib/hipe/sparc/Makefile
+++ b/lib/hipe/sparc/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -83,7 +83,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/tools/Makefile b/lib/hipe/tools/Makefile
index 6ce5cb1b8b..0eaa3a7b05 100644
--- a/lib/hipe/tools/Makefile
+++ b/lib/hipe/tools/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -72,7 +72,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/util/Makefile b/lib/hipe/util/Makefile
index 27cacedf11..85719ec3d6 100644
--- a/lib/hipe/util/Makefile
+++ b/lib/hipe/util/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -76,7 +76,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/x86/Makefile b/lib/hipe/x86/Makefile
index 065b56fce3..d7d0c7bf5a 100644
--- a/lib/hipe/x86/Makefile
+++ b/lib/hipe/x86/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -91,7 +91,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/inets/Makefile b/lib/inets/Makefile
index 9a54bfb8e2..ec05efa461 100644
--- a/lib/inets/Makefile
+++ b/lib/inets/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -24,7 +24,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
# Macros
# ----------------------------------------------------
-SUB_DIRECTORIES = src examples priv doc/src
+SUB_DIRECTORIES = src examples priv doc/src
include vsn.mk
VSN = $(INETS_VSN)
@@ -36,3 +36,11 @@ SPECIAL_TARGETS =
# ----------------------------------------------------
include $(ERL_TOP)/make/otp_subdir.mk
+info:
+ @echo "OS: $(OS)"
+ @echo "DOCB: $(DOCB)"
+ @echo ""
+ @echo "INETS_VSN: $(INETS_VSN)"
+ @echo "APP_VSN: $(APP_VSN)"
+ @echo ""
+
diff --git a/lib/inets/doc/src/Makefile b/lib/inets/doc/src/Makefile
index 5b5a818db8..e4cb0c4e48 100644
--- a/lib/inets/doc/src/Makefile
+++ b/lib/inets/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -25,7 +25,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
# ----------------------------------------------------
include ../../vsn.mk
VSN=$(INETS_VSN)
-APPLICATION=inets
+
# ----------------------------------------------------
# Include dependency
@@ -35,11 +35,13 @@ ifndef DOCSUPPORT
include make.dep
endif
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
@@ -56,7 +58,7 @@ XML_REF3_FILES = \
inets.xml \
ftp.xml \
tftp.xml \
- http.xml\
+ httpc.xml\
httpd.xml \
httpd_conf.xml \
httpd_socket.xml \
@@ -67,41 +69,29 @@ XML_REF3_FILES = \
mod_security.xml
XML_PART_FILES = \
- part.xml \
- part_notes.xml \
- part_notes_history.xml
-XML_HTML_FILES = \
- notes_history.xml
+ part.xml
BOOK_FILES = book.xml
-XML_FILES = $(BOOK_FILES) \
- $(XML_CHAPTER_FILES) \
- $(XML_PART_FILES) \
- $(XML_REF6_FILES) \
- $(XML_REF3_FILES) \
- $(XML_APPLICATION_FILES)
+XML_FILES = \
+ $(BOOK_FILES) \
+ $(XML_CHAPTER_FILES) \
+ $(XML_PART_FILES) \
+ $(XML_REF6_FILES) \
+ $(XML_REF3_FILES) \
+ $(XML_APPLICATION_FILES)
-GIF_FILES = \
- inets.gif \
- notes.gif \
- ref_man.gif \
- book.gif \
- warning.gif \
- note.gif
+# GIF_FILES = inets.gif
# ----------------------------------------------------
HTML_FILES = \
$(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
- $(XML_HTML_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
INFO_FILE = ../../info
EXTRA_FILES = summary.html.src \
- $(DEFAULT_GIF_FILES) \
- $(DEFAULT_HTML_FILES) \
$(XML_REF3_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_REF6_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html)
@@ -208,6 +198,7 @@ clean_html:
clean_man:
rm -f $(MAN3_FILES)
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -216,11 +207,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk
ifdef DOCSUPPORT
release_docs_spec: docs
+ @echo "release_docs_spec(docs) when DOCSUPPORT=$DOCSUPPORT"
$(INSTALL_DIR) $(RELSYSDIR)/doc/pdf
$(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf
$(INSTALL_DIR) $(RELSYSDIR)/doc/html
- $(INSTALL_DATA) $(HTMLDIR)/* \
- $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(HTMLDIR)/* $(RELSYSDIR)/doc/html
$(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
$(INSTALL_DIR) $(RELEASE_PATH)/man/man3
$(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3
@@ -228,15 +219,18 @@ else
ifeq ($(DOCTYPE),pdf)
release_docs_spec: pdf
+ @echo "release_docs_spec(pdf)"
$(INSTALL_DIR) $(RELEASE_PATH)/pdf
$(INSTALL_DATA) $(TOP_PDF_FILE) $(RELEASE_PATH)/pdf
else
ifeq ($(DOCTYPE),ps)
release_docs_spec: ps
+ @echo "release_docs_spec(ps)"
$(INSTALL_DIR) $(RELEASE_PATH)/ps
$(INSTALL_DATA) $(TOP_PS_FILE) $(RELEASE_PATH)/ps
else
release_docs_spec: docs
+ @echo "release_docs_spec(docs)"
$(INSTALL_DIR) $(RELSYSDIR)/doc/html
$(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \
$(RELSYSDIR)/doc/html
@@ -260,10 +254,6 @@ info:
@echo ""
@echo "TOP_HTML_FILES:\n$(TOP_HTML_FILES)"
@echo ""
- @echo "DEFAULT_GIF_FILES:\n$(DEFAULT_GIF_FILES)"
- @echo ""
- @echo "DEFAULT_HTML_FILES:\n$(DEFAULT_HTML_FILES)"
- @echo ""
@echo "XML_REF3_FILES:\n$(XML_REF3_FILES)"
@echo ""
@echo "XML_REF6_FILES:\n$(XML_REF6_FILES)"
diff --git a/lib/inets/doc/src/ftp.xml b/lib/inets/doc/src/ftp.xml
index 9ecca3dde1..25dfe716fc 100644
--- a/lib/inets/doc/src/ftp.xml
+++ b/lib/inets/doc/src/ftp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>ftp</title>
@@ -534,12 +534,14 @@
<fsummary>Start an standalone ftp client.</fsummary>
<type>
<v>Host = string() | ip_address()</v>
- <v>Opts = start_options() | open_options()</v>
- <v>start_options() = [start_option()]</v>
+ <v>Opts = options()</v>
+ <v>options() = [option()]</v>
+ <v>option() = start_option() | open_option()</v>
+ <!-- <v>start_options() = [start_option()]</v> -->
<v>start_option() = {verbose, verbose()} | {debug, debug()}</v>
<v>verbose() = boolean() (defaults to false)</v>
<v>debug() = disable | debug | trace (defaults to disable)</v>
- <v>open_options() = [open_option()]</v>
+ <!-- <v>open_options() = [open_option()]</v> -->
<v>open_option() = {ipfamily, ipfamily()} | {port, port()} | {mode, mode()} | {timeout, timeout()} | {progress, progress()}</v>
<v>ipfamily() = inet | inet6 | inet6fb4 (defaults to inet)</v>
<v>port() = integer() > 0 (defaults to 21)</v>
@@ -845,7 +847,7 @@
<type>
<v>Pid = pid()</v>
<v>Command = string()</v>
- <v>FTPLine = string() - Note the telnet end of line characters, from the ftp protocol definition, CRLF e.g. "\\r\ " has been removed.</v>
+ <v>FTPLine = string() - Note the telnet end of line characters, from the ftp protocol definition, CRLF e.g. "\\r\\n" has been removed.</v>
</type>
<desc>
<p>Sends an arbitrary FTP command and returns verbatimly a list
diff --git a/lib/inets/doc/src/http_server.xml b/lib/inets/doc/src/http_server.xml
index 56317d647c..547617e2e3 100644
--- a/lib/inets/doc/src/http_server.xml
+++ b/lib/inets/doc/src/http_server.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>HTTP server </title>
@@ -82,7 +82,7 @@
<p>The server is configured using an erlang property list.
For the available properties see
- <seealso marker="inets:inets">httpd(3)</seealso>
+ <seealso marker="httpd">httpd(3)</seealso>
For backwards compatibility also apache-like config files
are supported.
</p>
@@ -246,7 +246,7 @@
every row contains the name of the group and the members
of the group separated by a space, for example:</p>
<pre>
-\011 GroupName: Member1 Member2 .... MemberN
+GroupName: Member1 Member2 .... MemberN
</pre>
</item>
<item>
@@ -278,8 +278,8 @@
and every row contains User Name and Password separated by a
colon, for example:</p>
<pre>
-\011 UserName:Password
-\011 UserName:Password
+UserName:Password
+UserName:Password
</pre>
</item>
<item>
@@ -299,11 +299,11 @@
the specified methods. If no request method is specified
all request methods are verified against the restrictions.</p>
<pre>
-\011 &lt;Limit POST GET HEAD&gt;
-\011 order allow deny
-\011 require group group1
-\011 allow from 123.145.244.5
-\011 &lt;/Limit&gt;
+&lt;Limit POST GET HEAD&gt;
+ order allow deny
+ require group group1
+ allow from 123.145.244.5
+&lt;/Limit&gt;
</pre>
</item>
<item>
@@ -363,12 +363,10 @@
message-body, separated by a blank line. The message-header
contains one or more header fields. The body may be
empty. Example: </p>
- <code type="none">
-"Content-Type:text/plain\
-Accept-Ranges:none\
-\
-some very
-\011plain text" </code>
+
+ <code>"Content-Type:text/plain\nAccept-Ranges:none\n\nsome very
+ plain text" </code>
+
<p>The server will interpret the cgi-headers and most of them
will be transformed into HTTP headers and sent back to the
client together with the body.</p>
@@ -387,7 +385,7 @@ some very
the extra overhead. An URL which calls an Erlang erl function
has the following syntax (regular expression): </p>
<code type="none">
-\011 http://your.server.org/***/Module[:/]Function(?QueryString|/PathInfo)
+http://your.server.org/***/Module[:/]Function(?QueryString|/PathInfo)
</code>
<p>*** above depends on how the ErlScriptAlias config
directive has been used</p>
@@ -428,7 +426,7 @@ http://your.server.org/***/Mod:Func(Arg1,...,ArgN)
http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[])))
</code>
<p>which effectively will close down the Erlang node,
- that is use the erl scheme instead, until this
+ therefor, use the erl scheme instead, until this
security breach has been fixed.</p>
<p>Today there are no good way of solving this problem
and therefore Eval Scheme may be removed in future
@@ -498,14 +496,14 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
for parsed files, for example:
</p>
<pre>
-\011text/x-server-parsed-html shtml shtm
+ text/x-server-parsed-html shtml shtm
</pre>
<p>This makes files ending with <c>.shtml</c> and <c>.shtm</c>
into parsed files. Alternatively, if the performance hit is not a
problem, <em>all</em> HTML pages can be marked as parsed:
</p>
<pre>
-\011text/x-server-parsed-html html htm
+ text/x-server-parsed-html html htm
</pre>
</section>
@@ -518,7 +516,7 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
unparsed. Each directive has the following format:
</p>
<pre>
-\011&lt;!--#command tag1="value1" tag2="value2" --&gt;
+ &lt;!--#command tag1="value1" tag2="value2" --&gt;
</pre>
<p>Each command takes different arguments, most only accept one
tag at a time. Here is a breakdown of the commands and their
@@ -612,7 +610,7 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
<item>
<p>The unescaped version of any search query the client
sent, with all shell-special characters escaped with
- <c>\\</c>.</p>
+ <c>\</c>.</p>
</item>
<tag><c>DATE_LOCAL</c></tag>
<item>
@@ -753,24 +751,28 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
schema and the tables already is created. </p>
<code>
- -module(mnesia_test).
- -export([start/0,load_data/0]).
- -include("mod_auth.hrl").
-
- first_start()->
- mnesia:create_schema([node()]),
- mnesia:start(),
- mnesia:create_table(httpd_user,
- [{type,bag},{disc_copies,[node()]},
- {attributes,record_info(fields,httpd_user)}]),
- mnesia:create_table(httpd_group,
- [{type,bag},{disc_copies,[node()]},
- {attributes,record_info(fields,httpd_group)}]),
- mnesia:wait_for_tables([httpd_user,httpd_group],60000).
-
- start()->
- mnesia:start(),
- mnesia:wait_for_tables([httpd_user,httpd_group],60000).
+-module(mnesia_test).
+-export([start/0,load_data/0]).
+-include("mod_auth.hrl").
+
+first_start() ->
+ mnesia:create_schema([node()]),
+ mnesia:start(),
+ mnesia:create_table(httpd_user,
+ [{type, bag},
+ {disc_copies, [node()]},
+ {attributes, record_info(fields,
+ httpd_user)}]),
+ mnesia:create_table(httpd_group,
+ [{type, bag},
+ {disc_copies, [node()]},
+ {attributes, record_info(fields,
+ httpd_group)}]),
+ mnesia:wait_for_tables([httpd_user, httpd_group], 60000).
+
+start() ->
+ mnesia:start(),
+ mnesia:wait_for_tables([httpd_user, httpd_group], 60000).
</code>
<p>To create the Mnesia tables we use two records defined in
diff --git a/lib/inets/doc/src/http.xml b/lib/inets/doc/src/httpc.xml
index f6f8338113..e143ba2c1a 100644
--- a/lib/inets/doc/src/http.xml
+++ b/lib/inets/doc/src/httpc.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,26 +13,26 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
- <title>http</title>
+ <title>httpc</title>
<prepared>Ingela Anderton Andin</prepared>
<responsible></responsible>
<docno></docno>
<date></date>
<rev></rev>
</header>
- <module>http</module>
+ <module>httpc</module>
<modulesummary>An HTTP/1.1 client </modulesummary>
<description>
- <p>This module provides the API to a HTTP/1.1 client according to
- RFC 2616, caching is currently not supported.</p>
+ <p>This module provides the API to a HTTP/1.1 compatible client according
+ to RFC 2616, caching is currently not supported.</p>
<note>
<p>When starting the Inets application a manager process for the
default profile will be started. The functions in this API
@@ -64,6 +64,8 @@ request_id() = ref()
profile() = atom()
path() = string() representing a file path or directory path
ip_address() = See inet(3)
+socket_opt() = See the Options used by gen_tcp(3) and
+ ssl(3) connect(s)
]]></code>
</section>
@@ -130,38 +132,23 @@ ssl_options() = {verify, code()} |
<p>The client can be stopped using inets:stop(httpc, Pid) or
inets:stop(httpc, Profile).</p>
- <marker id="cancel_request"></marker>
+ <marker id="request1"></marker>
</section>
<funcs>
<func>
- <name>cancel_request(RequestId) -> </name>
- <name>cancel_request(RequestId, Profile) -> ok</name>
- <fsummary>Cancels an asynchronous HTTP-request.</fsummary>
- <type>
- <v>RequestId = request_id() - A unique identifier as returned
- by request/4</v>
- <v>Profile = profile()</v>
- </type>
- <desc>
- <p>Cancels an asynchronous HTTP-request. </p>
-
- <marker id="request1"></marker>
- </desc>
- </func>
-
- <func>
<name>request(Url) -> </name>
<name>request(Url, Profile) -> {ok, Result} | {error, Reason}</name>
<fsummary>Sends a get HTTP-request</fsummary>
<type>
- <v>Url = url() </v> <v>Result = {status_line(), headers(),
- body()} | {status_code(), body()} | request_id() </v>
+ <v>Url = url() </v>
+ <v>Result = {status_line(), headers(), body()} |
+ {status_code(), body()} | request_id() </v>
<v>Profile = profile()</v>
<v>Reason = term() </v>
</type>
<desc>
- <p>Equivalent to http:request(get, {Url, []}, [], []).</p>
+ <p>Equivalent to httpc:request(get, {Url, []}, [], []).</p>
<marker id="request2"></marker>
</desc>
@@ -177,23 +164,30 @@ ssl_options() = {verify, code()} |
<v>Request = request()</v>
<v>HTTPOptions = http_options()</v>
<v>http_options() = [http_option()]</v>
- <v>http_option() = {timeout, timeout()} |
+ <v>http_option() = {timeout, timeout()} |
{connect_timeout, timeout()} |
- {ssl, ssl_options()} |
- {autoredirect, boolean()} |
+ {ssl, ssl_options()} |
+ {autoredirect, boolean()} |
{proxy_auth, {userstring(), passwordstring()}} |
- {version, http_version()} |
- {relaxed, boolean()}</v>
+ {version, http_version()} |
+ {relaxed, boolean()}</v>
<v>timeout() = integer() >= 0 | infinity</v>
<v>Options = options()</v>
<v>options() = [option()]</v>
- <v>option() = {sync, boolean()} |
- {stream, stream_to()} |
- {body_format, body_format()} |
- {full_result, boolean()} |
- {headers_as_is, boolean()}</v>
- <v>stream_to() = self | {self, once} | filename() </v>
- <v>body_format() = string() | binary() </v>
+ <v>option() = {sync, boolean()} |
+ {stream, stream_to()} |
+ {body_format, body_format()} |
+ {full_result, boolean()} |
+ {headers_as_is, boolean() |
+ {socket_opts, socket_opts()} |
+ {receiver, receiver()}}</v>
+ <v>stream_to() = none | self | {self, once} | filename() </v>
+ <v>socket_opts() = [socket_opt()]</v>
+ <v>receiver() = pid() | function()/1 | {Module, Function, Args} </v>
+ <v>Module = atom() </v>
+ <v>Function = atom() </v>
+ <v>Args = list() </v>
+ <v>body_format() = string | binary </v>
<v>Result = {status_line(), headers(), body()} |
{status_code(), body()} | request_id() </v>
<v>Profile = profile() </v>
@@ -203,29 +197,25 @@ ssl_options() = {verify, code()} |
<desc>
<p>Sends a HTTP-request. The function can be both synchronous
and asynchronous. In the later case the function will return
- {ok, RequestId} and later on message(s) will be sent to the
- calling process on the format: </p>
-<pre>
- {http, {RequestId, Result}}
- {http, {RequestId, {error, Reason}}}
- {http, {RequestId, stream_start, Headers}
- {http, {RequestId, stream, BinBodyPart}
- {http, {RequestId, stream_end, Headers}
- {http, {RequestId, saved_to_file}}.
-</pre>
+ {ok, RequestId} and later on the information will be delivered
+ to the <c>receiver</c> depending on that value. </p>
<p>Http option (<c>http_option()</c>) details: </p>
<taglist>
<tag><c><![CDATA[timeout]]></c></tag>
<item>
<p>Timeout time for the request. </p>
+ <p>The clock start ticking as soon as the request has been
+ sent. </p>
+ <p>Time is in milliseconds. </p>
<p>Defaults to <c>infinity</c>. </p>
</item>
<tag><c><![CDATA[connect_timeout]]></c></tag>
<item>
<p>Connection timeout time, used during the initial request,
- when the client is connecting to the server. </p>
+ when the client is <em>connecting</em> to the server. </p>
+ <p>Time is in milliseconds. </p>
<p>Defaults to the value of the <c>timeout</c> option. </p>
</item>
@@ -329,8 +319,92 @@ ssl_options() = {verify, code()} |
<p>Defaults to <c>false</c>. </p>
</item>
+ <tag><c><![CDATA[socket_opts]]></c></tag>
+ <item>
+ <p>Socket options to be used for this and subsequent
+ request(s). </p>
+ <p>Overrides any value set by the
+ <seealso marker="set_options">set_options</seealso>
+ function. </p>
+ <p>Note that the validity of the options are <em>not</em>
+ checked in any way. </p>
+ <p>Note that this may change the socket behaviour
+ (see <seealso marker="inet#setopts">inet:setopts/2</seealso>)
+ for an already existing, and therefor already connected
+ request handler. </p>
+ <p>By defaults the socket options set by the
+ <seealso marker="#set_options">set_options/1,2</seealso>
+ function is used when establishing connection. </p>
+ </item>
+
+ <tag><c><![CDATA[receiver]]></c></tag>
+ <item>
+ <p>Defines how the client will deliver the result for a
+ asynchroneous request (<c>sync</c> has the value
+ <c>false</c>). </p>
+
+ <taglist>
+ <tag><c><![CDATA[pid()]]></c></tag>
+ <item>
+ <p>Message(s) will be sent to this process in the format: </p>
+<pre>
+{http, ReplyInfo}
+</pre>
+ </item>
+
+ <tag><c><![CDATA[function/1]]></c></tag>
+ <item>
+ <p>Information will be delivered to the receiver via calls
+ to the provided fun: </p>
+<pre>
+Receiver(ReplyInfo)
+</pre>
+ </item>
+
+ <tag><c><![CDATA[{Module, Funcion, Args}]]></c></tag>
+ <item>
+ <p>Information will be delivered to the receiver via calls
+ to the callback function: </p>
+<pre>
+apply(Module, Function, [ReplyInfo | Args])
+</pre>
+ </item>
+
+ </taglist>
+ <p>In all cases above, <c>ReplyInfo</c> has the following
+ structure: </p>
+
+<pre>
+{RequestId, saved_to_file}
+{RequestId, {error, Reason}}
+{RequestId, Result}
+{RequestId, stream_start, Headers}
+{RequestId, stream_start, Headers, HandlerPid}
+{RequestId, stream, BinBodyPart}
+{RequestId, stream_end, Headers}
+</pre>
+
+ <p>Defaults to the <c>pid()</c> of the process calling the request
+ function (<c>self()</c>). </p>
+ </item>
</taglist>
+ <marker id="cancel_request"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>cancel_request(RequestId) -> </name>
+ <name>cancel_request(RequestId, Profile) -> ok</name>
+ <fsummary>Cancels an asynchronous HTTP-request.</fsummary>
+ <type>
+ <v>RequestId = request_id() - A unique identifier as returned
+ by request/4</v>
+ <v>Profile = profile()</v>
+ </type>
+ <desc>
+ <p>Cancels an asynchronous HTTP-request. </p>
+
<marker id="set_options"></marker>
</desc>
</func>
@@ -341,17 +415,30 @@ ssl_options() = {verify, code()} |
<fsummary>Sets options to be used for subsequent requests.</fsummary>
<type>
<v>Options = [Option]</v>
- <v>Option = {proxy, {Proxy, NoProxy}} | {max_sessions, MaxSessions} |
- {max_keep_alive_length, MaxKeepAlive} | {keep_alive_timeout, KeepAliveTimeout} |
- {max_pipeline_length, MaxPipeline} | {pipeline_timeout, PipelineTimeout} |
- {cookies | CookieMode} |
- {ipfamily, IpFamily} | {ip, IpAddress} | {port, Port} |
- {verbose, VerboseMode} </v>
+ <v>Option = {proxy, {Proxy, NoProxy}} |
+ {max_sessions, MaxSessions} |
+ {max_keep_alive_length, MaxKeepAlive} |
+ {keep_alive_timeout, KeepAliveTimeout} |
+ {max_pipeline_length, MaxPipeline} |
+ {pipeline_timeout, PipelineTimeout} |
+ {cookies, CookieMode} |
+ {ipfamily, IpFamily} |
+ {ip, IpAddress} |
+ {port, Port} |
+ {socket_opts, socket_opts()} |
+ {verbose, VerboseMode} </v>
<v>Proxy = {Hostname, Port}</v>
<v>Hostname = string() </v>
<d>ex: "localhost" or "foo.bar.se"</d>
<v>Port = integer()</v>
<d>ex: 8080 </d>
+ <v>socket_opts() = [socket_opt()]</v>
+ <d>The options are appended to the socket options used by the
+ client. </d>
+ <d>These are the default values when a new request handler
+ is started (for the initial connect). They are passed directly
+ to the underlying transport (gen_tcp or ssl) <em>without</em>
+ verification! </d>
<v>NoProxy = [NoProxyDesc]</v>
<v>NoProxyDesc = DomainDesc | HostName | IPDesc</v>
<v>DomainDesc = "*.Domain"</v>
@@ -439,12 +526,13 @@ ssl_options() = {verify, code()} |
same behavior as active once for sockets.</p>
<marker id="verify_cookie"></marker>
+ <marker id="store_cookie"></marker>
</desc>
</func>
<func>
- <name>verify_cookie(SetCookieHeaders, Url) -> </name>
- <name>verify_cookie(SetCookieHeaders, Url, Profile) -> ok | {error, Reason}</name>
+ <name>store_cookie(SetCookieHeaders, Url) -> </name>
+ <name>store_cookie(SetCookieHeaders, Url, Profile) -> ok | {error, Reason}</name>
<fsummary>Saves the cookies defined in SetCookieHeaders in the client profile's cookie database.</fsummary>
<type>
<v>SetCookieHeaders = headers() - where field = "set-cookie"</v>
@@ -454,7 +542,7 @@ ssl_options() = {verify, code()} |
<desc>
<p>Saves the cookies defined in SetCookieHeaders
in the client profile's cookie database. You need to
- call this function if you set the option cookies to verify.
+ call this function if you set the option cookies to <c>verify</c>.
If no profile is specified the default profile will be used.
</p>
@@ -476,6 +564,43 @@ ssl_options() = {verify, code()} |
when making a request to Url using the profile Profile.
If no profile is specified the default profile will be used.
</p>
+
+ <marker id="reset_cookies"></marker>
+ </desc>
+ </func>
+
+
+ <func>
+ <name>reset_cookies() -> void()</name>
+ <name>reset_cookies(Profile) -> void()</name>
+ <fsummary>Reset the cookie database.</fsummary>
+ <type>
+ <v>Profile = profile()</v>
+ </type>
+ <desc>
+ <p>Resets (clears) the cookie database for the specified Profile.
+ If no profile is specified the default profile will be used.
+ </p>
+ </desc>
+ </func>
+
+
+ <func>
+ <name>which_cookies() -> cookies()</name>
+ <name>which_cookies(Profile) -> cookies()</name>
+ <fsummary>Dumps out the entire cookie database.</fsummary>
+ <type>
+ <v>Profile = profile()</v>
+ <v>cookies() = [cooie_stores()]</v>
+ <v>cookie_stores() = {cookies, icookies()} | {session_cookies, icookies()}</v>
+ <v>icookies() = [icookie()]</v>
+ <v>cookie() = term()</v>
+ </type>
+ <desc>
+ <p>This function produces a list of the entire cookie database.
+ It is intended for debugging/testing purposes.
+ If no profile is specified the default profile will be used.
+ </p>
</desc>
</func>
</funcs>
@@ -483,6 +608,7 @@ ssl_options() = {verify, code()} |
<section>
<title>SEE ALSO</title>
<p>RFC 2616, <seealso marker="inets">inets(3)</seealso>,
+ <seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso>,
<seealso marker="ssl:ssl">ssl(3)</seealso>
</p>
</section>
diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml
index 60afcc6cfe..7dabeb33e9 100644
--- a/lib/inets/doc/src/httpd.xml
+++ b/lib/inets/doc/src/httpd.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>httpd</title>
@@ -93,7 +93,7 @@
followed by the value followed by a new line. Ex:
<code>
- {server_root, "/urs/local/www"} -> ServerRoot /usr/local/www
+{server_root, "/urs/local/www"} -> ServerRoot /usr/local/www
</code>
<p>With a few exceptions, that are documented
@@ -103,9 +103,9 @@
as:</p>
<pre>
<![CDATA[
- <Directory Dir>
- <Properties handled as described above>
- </Directory>
+<Directory Dir>
+ <Properties handled as described above>
+</Directory>
]]>
</pre>
</item>
@@ -239,9 +239,9 @@
as an Apache like file as well as directly in the property list. Such
a file may look like:</p>
<pre>
- \011 # MIME type\011\011\011Extension
- \011 text/html\011\011\011html htm
- \011 text/plain\011\011\011asc txt
+# MIME type Extension
+text/html html htm
+text/plain asc txt
</pre>
<p>Defaults to [{"html","text/html"},{"htm","text/html"}]</p>
@@ -869,19 +869,19 @@ bytes
ModData = #mod{}
-record(mod, {
-\011\011data = [],
-\011\011socket_type = ip_comm,
-\011\011socket,
-\011\011config_db,
-\011\011method,
-\011\011absolute_uri,
-\011\011request_uri,
-\011\011http_version,
-\011\011request_line,
-\011\011parsed_header = [],
-\011\011entity_body,
-\011\011connection
-\011 }).
+ data = [],
+ socket_type = ip_comm,
+ socket,
+ config_db,
+ method,
+ absolute_uri,
+ request_uri,
+ http_version,
+ request_line,
+ parsed_header = [],
+ entity_body,
+ connection
+ }).
</code>
<p>The fields of the <c>mod</c> record has the following meaning:
</p>
diff --git a/lib/inets/doc/src/httpd_util.xml b/lib/inets/doc/src/httpd_util.xml
index 1566ee29d1..642e5213b0 100644
--- a/lib/inets/doc/src/httpd_util.xml
+++ b/lib/inets/doc/src/httpd_util.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>httpd_util</title>
@@ -218,7 +218,8 @@
<marker id="lookup_mime"></marker>
<p><c>lookup_mime</c> returns the mime type associated with a
specific file suffix as specified in the <c>mime.types</c>
- file (located in the <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\\\\conf\\\\mime.types">config directory</path>).</p>
+ file (located in the
+ <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\conf\mime.types">config directory</path>).</p>
<marker id="lookup_mime_default"></marker>
</desc>
@@ -239,7 +240,7 @@
<p><c>lookup_mime_default</c> returns the mime type associated
with a specific file suffix as specified in the
<c>mime.types</c> file (located in the
- <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\\\\conf\\\\mime.types">config directory</path>).
+ <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\conf\mime.types">config directory</path>).
If no appropriate association can be found
the value of DefaultType is
returned.</p>
diff --git a/lib/inets/doc/src/inets.xml b/lib/inets/doc/src/inets.xml
index e5fe32f32f..81dfe7e944 100644
--- a/lib/inets/doc/src/inets.xml
+++ b/lib/inets/doc/src/inets.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>inets</title>
@@ -129,7 +129,7 @@
</type>
<desc>
<p>Dynamically starts an inets service after the inets
- application has been started.\011</p>
+ application has been started. </p>
<note>
<p>Dynamically started services will not be handled by
application takeover and failover behavior when inets is
diff --git a/lib/inets/doc/src/make.dep b/lib/inets/doc/src/make.dep
index d96c6dc5b8..8deb7e7a5a 100644
--- a/lib/inets/doc/src/make.dep
+++ b/lib/inets/doc/src/make.dep
@@ -1,3 +1,23 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1999-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+
# ----------------------------------------------------
# >>>> Do not edit this file <<<<
# This file was automaticly generated by
@@ -9,7 +29,7 @@
# TeX files that the DVI file depend on
# ----------------------------------------------------
-book.dvi: book.tex ftp.tex ftp_client.tex http.tex http_client.tex \
+book.dvi: book.tex ftp.tex ftp_client.tex httpc.tex http_client.tex \
http_server.tex httpd.tex httpd_conf.tex httpd_socket.tex \
httpd_util.tex inets.tex inets_services.tex \
mod_alias.tex mod_auth.tex mod_esi.tex mod_security.tex \
diff --git a/lib/inets/doc/src/mod_esi.xml b/lib/inets/doc/src/mod_esi.xml
index d4541a1d15..6bad77dc0a 100644
--- a/lib/inets/doc/src/mod_esi.xml
+++ b/lib/inets/doc/src/mod_esi.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>mod_esi</title>
@@ -94,7 +94,7 @@
that the first chunk of data sent to the client must at
least contain all HTTP header fields that the response
will generate. If the first chunk not contains
- <em>End of HTTP header</em> that is <c>"\\r\ \\r\ "</c>
+ <em>End of HTTP header</em> that is <c>"\r\n\r\n"</c>
the server will
assume that no HTTP header fields will be generated.</p>
</desc>
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 687e127d0b..e95c8d6e97 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Inets Release Notes</title>
@@ -32,21 +32,108 @@
<file>notes.xml</file>
</header>
- <section><title>Inets 5.2.0.1</title>
+ <section><title>Inets 5.3</title>
<section><title>Improvements and New Features</title>
- <p>-</p>
<!--
+ <p>-</p>
+-->
+
<list>
<item>
- <p>The documentation is now built with open source tools
- (<em>xsltproc</em> and <em>fop</em>) that exists on most
- platforms. One visible change is that the frames are removed.</p>
- <p>Own Id: OTP-8249</p>
+ <p>[httpc] - Allow users to pass socket options to the transport
+ module when making requests. </p>
+ <p>See the <c>socket_opts</c> option in the
+ <seealso marker="httpc#request2">request/4</seealso> or
+ <seealso marker="httpc#set_options">set_options/1,2</seealso>
+ for more info, </p>
+ <p>Own Id: OTP-8352</p>
</item>
- </list>
+ <item>
+ <p>[httpc] Fix bug crafting Host header when port is not 80. </p>
+ <p>The host header should include the port number as well as the
+ host name when making a request to a server listening on a port
+ other than the HTTP default of 80. Currently, only the host
+ name is included. This is important to make the http client
+ more compliant with the HTTP specification. </p>
+ <p>Own Id: OTP-8371</p>
+ <p>Kelly McLaughlin</p>
+ </item>
+
+ <item>
+ <p>[httpc|httpd] http_chunk data handling/passing improvement. </p>
+ <p>This is a modification to the http_chunk module to forward any
+ full chunk received, regardless of whether the size field for the
+ following chunk has been received yet. This allows http_chunk to
+ be used in situations where a long term HTTP connection is used to
+ send periodic status updates as individual chunks. Previously a
+ given chunk would not be forwarded to the client process until the
+ size for the next chunk had been read which rendered the module
+ difficult to use for the scenario described. </p>
+ <p>Bernard Duggan</p>
+ <p>Own Id: OTP-8351</p>
+ </item>
+
+ <item>
+ <p>Include the inets test suite in the release of the
+ application. </p>
+ <p>Own Id: OTP-8349</p>
+ </item>
+
+ <item>
+ <p>[httpc] - It is now possible to configure the client to
+ deliver an async reply to more receivers then the calling
+ process. </p>
+ <p>See the
+ <seealso marker="httpc#request2">receiver</seealso>
+ option for more info, </p>
+ <p>Own Id: OTP-8106</p>
+ </item>
+
+ <item>
+ <p>[httpd] - Methods "PUT" and "DELETE" now allowed. </p>
+ <p>Own Id: OTP-8103</p>
+ </item>
+
+ <item>
+ <p>[httpc] Several more or less critical fixes:</p>
+ <p>
+ <list type="bulleted">
+ <item>
+ <p>Initial call between the httpc manager and request
+ handler was synchronous. </p>
+ <p>When the manager starts a new request handler,
+ this is no longer a synchronous operation. Previously,
+ the new request handler made the connection to the
+ server and issuing of the first request (the reason
+ for starting it) in the gen_server init function.
+ If the connection for some reason "took some time",
+ the manager hanged, leaving all other activities by
+ that manager also hanging. </p>
+ </item>
+<!--
+ <item>
+ <p>Copying of data between processes</p>
+ <p>TBD</p>
+ </item>
+ <item>
+ <p>Reading of requests</p>
+ <p>TBD</p>
+ </item>
-->
+ </list>
+ </p>
+ <p>As a side-effect of these changes, some modules was also
+ renamed, and a new api module,
+ <seealso marker="httpc">httpc</seealso>, has been introduced
+ (the old module <c>http</c> is <em>not</em> removed, but is
+ now just wrapper for <c>httpc</c>). </p>
+ <p>Own Id: OTP-8016</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ </item>
+ </list>
</section>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -57,13 +144,32 @@
<list>
<item>
- <p>Fixing minor Dialyzer and copyright problem.</p>
+ <p>[httpd] The server did not fully support the documented module
+ callback api. Specifically, the load function should be able to
+ return the atom <c>ok</c>, but this was not accepted. </p>
+ <p>Own Id: OTP-8359</p>
</item>
+ <item>
+ <p>Fixing various documentation-related bugs (bad quotes).</p>
+ <p>Own Id: OTP-8327</p>
+ </item>
+
+ <item>
+ <p>Fixing minor Dialyzer and copyright problem(s). </p>
+ <p>Own Id: OTP-8315</p>
+ </item>
+
+ <item>
+ <p>[httpc] - Added basic sanity check of option value
+ combinations.</p>
+ <p>Own Id: OTP-8056</p>
+ </item>
</list>
</section>
- </section> <!-- 5.2.0.1 -->
+ </section> <!-- 5.3 -->
<section><title>Inets 5.2</title>
@@ -173,7 +279,7 @@
<p>Timeout out requests are retried. </p>
</item>
</list>
- <p>Jean-S�bastien P�dron</p>
+ <p>Jean-S&#233;bastien P&#233;dron</p>
<p>Own Id: OTP-8248</p>
</item>
diff --git a/lib/inets/doc/src/notes_history.xml b/lib/inets/doc/src/notes_history.xml
index 53375c9aa7..6480bad758 100644
--- a/lib/inets/doc/src/notes_history.xml
+++ b/lib/inets/doc/src/notes_history.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Inets Release Notes History</title>
@@ -385,8 +385,7 @@
</item>
<item>
<p>[httpc, httpd] - In some cases if a body contained the
- sequence "\\r\
- 0" and was chunked encoded this sequence
+ sequence "\r\n0" and was chunked encoded this sequence
was incorrectly interpreted as the last chunk.</p>
<p>Own Id: OTP-6264 Aux Id: OTP-6005 </p>
</item>
@@ -968,8 +967,7 @@
design was changed to use gen_tcp active once semantics.
The API is not effected except for the function
ftp:quote/2 which now returns a list of strings (ftp
- result lines) where the line endings "\\r\
- " has been
+ result lines) where the line endings "\r\n" has been
removed. This was the original intention for the return
value of ftp:quote/2 but it was non trivial to make a
good such solution with the old design and a compromise
@@ -1055,13 +1053,11 @@
<p>Own Id: OTP-5551 Aux Id: seq9854 </p>
</item>
<item>
- <p>The HTTP server now handles "GET /\\r\
- \\r\
- " as well as
- "GET / \\r\
- \\r\
- ". According to the RFC the whitespace is
- not needed.</p>
+ <p>The HTTP server now handles
+ "GET /\r\n\r\n"
+ as well as
+ "GET / \r\n\r\n".
+ According to the RFC the whitespace is not needed.</p>
<p>Own Id: OTP-5552 Aux Id: seq8426 </p>
</item>
</list>
diff --git a/lib/inets/doc/src/ref_man.xml b/lib/inets/doc/src/ref_man.xml
index 7ec2c041c8..45d5dfcd0e 100644
--- a/lib/inets/doc/src/ref_man.xml
+++ b/lib/inets/doc/src/ref_man.xml
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Inets Reference Manual</title>
@@ -36,7 +36,7 @@
<xi:include href="inets.xml"/>
<xi:include href="ftp.xml"/>
<xi:include href="tftp.xml"/>
- <xi:include href="http.xml"/>
+ <xi:include href="httpc.xml"/>
<xi:include href="httpd.xml"/>
<xi:include href="httpd_conf.xml"/>
<xi:include href="httpd_socket.xml"/>
diff --git a/lib/inets/src/ftp/Makefile b/lib/inets/src/ftp/Makefile
index 70d51115e6..0c15277a18 100644
--- a/lib/inets/src/ftp/Makefile
+++ b/lib/inets/src/ftp/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -32,7 +32,8 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
@@ -49,15 +50,17 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"'
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
ifeq ($(FTP_DEBUG),true)
INETS_FLAGS += -Dftp_debug
endif
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
@@ -94,6 +97,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/http_client/Makefile b/lib/inets/src/http_client/Makefile
index 23170f439f..628c91421f 100644
--- a/lib/inets/src/http_client/Makefile
+++ b/lib/inets/src/http_client/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -22,6 +22,7 @@ include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
# ----------------------------------------------------
# Application version
# ----------------------------------------------------
@@ -29,17 +30,20 @@ include ../../vsn.mk
VSN = $(INETS_VSN)
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
MODULES = \
http \
- http_cookie \
+ httpc \
+ httpc_cookie \
httpc_handler \
httpc_manager \
httpc_sup \
@@ -55,20 +59,24 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
INETS_ERL_FLAGS += -I ../http_lib -I ../inets_app -pa ../../ebin
-ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS)\
+ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS) \
$(INETS_FLAGS) \
+'{parse_transform,sys_pre_attributes}' \
+'{attribute,insert,app_vsn,$(APP_VSN)}'
+
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
@@ -94,6 +102,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/http_client/http.erl b/lib/inets/src/http_client/http.erl
index ce5d7723f0..7e1e90b50e 100644
--- a/lib/inets/src/http_client/http.erl
+++ b/lib/inets/src/http_client/http.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -24,7 +24,6 @@
%%% - RFC 2818 HTTP Over TLS
-module(http).
--behaviour(inets_service).
%% API
-export([request/1, request/2, request/4, request/5,
@@ -35,15 +34,6 @@
cookie_header/2, stream_next/1,
default_profile/0]).
-%% Behavior callbacks
--export([start_standalone/1, start_service/1,
- stop_service/1, services/0, service_info/1]).
-
--include("http_internal.hrl").
--include("httpc_internal.hrl").
-
--define(DEFAULT_PROFILE, default).
-
%%%=========================================================================
%%% API
@@ -51,751 +41,75 @@
%%--------------------------------------------------------------------------
%% request(Url [, Profile]) ->
-%% {ok, {StatusLine, Headers, Body}} | {error,Reason}
-%%
-%% Url - string()
-%% Description: Calls request/4 with default values.
+%% request(Method, Request, HTTPOptions, Options [, Profile])
%%--------------------------------------------------------------------------
-request(Url) ->
- request(Url, default_profile()).
-
-request(Url, Profile) ->
- request(get, {Url, []}, [], [], Profile).
-
-
-%%--------------------------------------------------------------------------
-%% request(Method, Request, HTTPOptions, Options [, Profile]) ->
-%% {ok, {StatusLine, Headers, Body}} | {ok, {Status, Body}} |
-%% {ok, RequestId} | {error,Reason} | {ok, {saved_as, FilePath}
-%%
-%% Method - atom() = head | get | put | post | trace | options| delete
-%% Request - {Url, Headers} | {Url, Headers, ContentType, Body}
-%% Url - string()
-%% HTTPOptions - [HttpOption]
-%% HTTPOption - {timeout, Time} | {connect_timeout, Time} |
-%% {ssl, SSLOptions} | {proxy_auth, {User, Password}}
-%% Ssloptions = [SSLOption]
-%% SSLOption = {verify, code()} | {depth, depth()} | {certfile, path()} |
-%% {keyfile, path()} | {password, string()} | {cacertfile, path()} |
-%% {ciphers, string()}
-%% Options - [Option]
-%% Option - {sync, Boolean} | {body_format, BodyFormat} |
-%% {full_result, Boolean} | {stream, To} |
-%% {headers_as_is, Boolean}
-%% StatusLine = {HTTPVersion, StatusCode, ReasonPhrase}</v>
-%% HTTPVersion = string()
-%% StatusCode = integer()
-%% ReasonPhrase = string()
-%% Headers = [Header]
-%% Header = {Field, Value}
-%% Field = string()
-%% Value = string()
-%% Body = string() | binary() - HTLM-code
-%%
-%% Description: Sends a HTTP-request. The function can be both
-%% syncronus and asynchronous in the later case the function will
-%% return {ok, RequestId} and later on a message will be sent to the
-%% calling process on the format {http, {RequestId, {StatusLine,
-%% Headers, Body}}} or {http, {RequestId, {error, Reason}}}
-%%--------------------------------------------------------------------------
+request(Url) -> httpc:request(Url).
+request(Url, Profile) -> httpc:request(Url, Profile).
request(Method, Request, HttpOptions, Options) ->
- request(Method, Request, HttpOptions, Options, default_profile()).
+ httpc:request(Method, Request, HttpOptions, Options).
+request(Method, Request, HttpOptions, Options, Profile) ->
+ httpc:request(Method, Request, HttpOptions, Options, Profile).
-request(Method, {Url, Headers}, HTTPOptions, Options, Profile)
- when (Method =:= options) orelse
- (Method =:= get) orelse
- (Method =:= head) orelse
- (Method =:= delete) orelse
- (Method =:= trace) ->
- case http_uri:parse(Url) of
- {error, Reason} ->
- {error, Reason};
- ParsedUrl ->
- handle_request(Method, Url, ParsedUrl, Headers, [], [],
- HTTPOptions, Options, Profile)
- end;
-
-request(Method, {Url,Headers,ContentType,Body}, HTTPOptions, Options, Profile)
- when (Method =:= post) orelse (Method =:= put) ->
- case http_uri:parse(Url) of
- {error, Reason} ->
- {error, Reason};
- ParsedUrl ->
- handle_request(Method, Url,
- ParsedUrl, Headers, ContentType, Body,
- HTTPOptions, Options, Profile)
- end.
%%--------------------------------------------------------------------------
-%% request(RequestId) -> ok
-%% RequestId - As returned by request/4
-%%
-%% Description: Cancels a HTTP-request.
+%% cancel_request(RequestId [, Profile])
%%-------------------------------------------------------------------------
-cancel_request(RequestId) ->
- cancel_request(RequestId, default_profile()).
+cancel_request(RequestId) ->
+ httpc:cancel_request(RequestId).
cancel_request(RequestId, Profile) ->
- ok = httpc_manager:cancel_request(RequestId, profile_name(Profile)),
- receive
- %% If the request was allready fullfilled throw away the
- %% answer as the request has been canceled.
- {http, {RequestId, _}} ->
- ok
- after 0 ->
- ok
- end.
-
-
-set_option(Key, Value) ->
- set_option(Key, Value, default_profile()).
-
-set_option(Key, Value, Profile) ->
- set_options([{Key, Value}], Profile).
+ httpc:cancel_request(RequestId, Profile).
%%--------------------------------------------------------------------------
-%% set_options(Options [, Profile]) -> ok | {error, Reason}
-%% Options - [Option]
-%% Profile - atom()
-%% Option - {proxy, {Proxy, NoProxy}} | {max_sessions, MaxSessions} |
-%% {max_pipeline_length, MaxPipeline} |
-%% {pipeline_timeout, PipelineTimeout} | {cookies, CookieMode} |
-%% {ipfamily, IpFamily}
-%% Proxy - {Host, Port}
-%% NoProxy - [Domain | HostName | IPAddress]
-%% MaxSessions, MaxPipeline, PipelineTimeout = integer()
-%% CookieMode - enabled | disabled | verify
-%% IpFamily - inet | inet6 | inet6fb4
-%% Description: Informs the httpc_manager of the new settings.
+%% set_options(Options [, Profile])
+%% set_option(Key, Value [, Profile])
%%-------------------------------------------------------------------------
+
set_options(Options) ->
- set_options(Options, default_profile()).
+ httpc:set_options(Options).
set_options(Options, Profile) ->
- case validate_options(Options) of
- {ok, Opts} ->
- try httpc_manager:set_options(Opts, profile_name(Profile)) of
- Result ->
- Result
- catch
- exit:{noproc, _} ->
- {error, inets_not_started}
- end;
- {error, Reason} ->
- {error, Reason}
- end.
+ httpc:set_options(Options, Profile).
+
+set_option(Key, Value) ->
+ httpc:set_option(Key, Value).
+set_option(Key, Value, Profile) ->
+ httpc:set_option(Key, Value, Profile).
%%--------------------------------------------------------------------------
-%% verify_cookies(SetCookieHeaders, Url [, Profile]) -> ok | {error, reason}
-%%
-%%
-%% Description: Store the cookies from <SetCookieHeaders>
-%% in the cookie database
-%% for the profile <Profile>. This function shall be used when the option
-%% cookie is set to verify.
+%% verify_cookies(SetCookieHeaders, Url [, Profile])
%%-------------------------------------------------------------------------
-verify_cookies(SetCookieHeaders, Url) ->
- verify_cookies(SetCookieHeaders, Url, default_profile()).
+verify_cookies(SetCookieHeaders, Url) ->
+ httpc:store_cookies(SetCookieHeaders, Url).
verify_cookies(SetCookieHeaders, Url, Profile) ->
- {_, _, Host, Port, Path, _} = http_uri:parse(Url),
- ProfileName = profile_name(Profile),
- Cookies = http_cookie:cookies(SetCookieHeaders, Path, Host),
- try httpc_manager:store_cookies(Cookies, {Host, Port}, ProfileName) of
- _ ->
- ok
- catch
- exit:{noproc, _} ->
- {error, {not_started, Profile}}
- end.
+ httpc:store_cookies(SetCookieHeaders, Url, Profile).
+
%%--------------------------------------------------------------------------
-%% cookie_header(Url [, Profile]) -> Header | {error, Reason}
-%%
-%% Description: Returns the cookie header that would be sent when making
-%% a request to <Url>.
+%% cookie_header(Url [, Profile])
%%-------------------------------------------------------------------------
-cookie_header(Url) ->
- cookie_header(Url, default_profile()).
+cookie_header(Url) ->
+ httpc:cookie_header(Url).
cookie_header(Url, Profile) ->
- try httpc_manager:cookies(Url, profile_name(Profile)) of
- Header ->
- Header
- catch
- exit:{noproc, _} ->
- {error, {not_started, Profile}}
- end.
-
-
-stream_next(Pid) ->
- httpc_handler:stream_next(Pid).
-
-%%%========================================================================
-%%% Behavior callbacks
-%%%========================================================================
-start_standalone(PropList) ->
- case proplists:get_value(profile, PropList) of
- undefined ->
- {error, no_profile};
- Profile ->
- Dir =
- proplists:get_value(data_dir, PropList, only_session_cookies),
- httpc_manager:start_link({Profile, Dir}, stand_alone)
- end.
-
-start_service(Config) ->
- httpc_profile_sup:start_child(Config).
-
-stop_service(Profile) when is_atom(Profile) ->
- httpc_profile_sup:stop_child(Profile);
-stop_service(Pid) when is_pid(Pid) ->
- case service_info(Pid) of
- {ok, [{profile, Profile}]} ->
- stop_service(Profile);
- Error ->
- Error
- end.
-
-services() ->
- [{httpc, Pid} || {_, Pid, _, _} <-
- supervisor:which_children(httpc_profile_sup)].
-service_info(Pid) ->
- try [{ChildName, ChildPid} ||
- {ChildName, ChildPid, _, _} <-
- supervisor:which_children(httpc_profile_sup)] of
- Children ->
- child_name2info(child_name(Pid, Children))
- catch
- exit:{noproc, _} ->
- {error, service_not_available}
- end.
-
-
-%%%========================================================================
-%%% Internal functions
-%%%========================================================================
-handle_request(Method, Url,
- {Scheme, UserInfo, Host, Port, Path, Query},
- Headers, ContentType, Body,
- HTTPOptions0, Options, Profile) ->
-
- HTTPOptions = http_options(HTTPOptions0),
- Sync = proplists:get_value(sync, Options, true),
- NewHeaders = lists:map(fun({Key, Val}) ->
- {http_util:to_lower(Key), Val} end,
- Headers),
- Stream = proplists:get_value(stream, Options, none),
- case {Sync, Stream} of
- {true, self} ->
- {error, streaming_error};
- _ ->
- RecordHeaders = header_record(NewHeaders,
- #http_request_h{},
- Host,
- HTTPOptions#http_options.version),
- Request = #request{from = self(),
- scheme = Scheme,
- address = {Host,Port},
- path = Path,
- pquery = Query,
- method = Method,
- headers = RecordHeaders,
- content = {ContentType,Body},
- settings = HTTPOptions,
- abs_uri = Url,
- userinfo = UserInfo,
- stream = Stream,
- headers_as_is = headers_as_is(Headers, Options)},
- try httpc_manager:request(Request, profile_name(Profile)) of
- {ok, RequestId} ->
- handle_answer(RequestId, Sync, Options);
- {error, Reason} ->
- {error, Reason}
- catch
- error:{noproc, _} ->
- {error, {not_started, Profile}}
- end
- end.
-
-
-handle_answer(RequestId, false, _) ->
- {ok, RequestId};
-handle_answer(RequestId, true, Options) ->
- receive
- {http, {RequestId, saved_to_file}} ->
- {ok, saved_to_file};
- {http, {RequestId, Result = {_,_,_}}} ->
- return_answer(Options, Result);
- {http, {RequestId, {error, Reason}}} ->
- {error, Reason}
- end.
-
-return_answer(Options, {{"HTTP/0.9",_,_}, _, BinBody}) ->
- Body = format_body(BinBody, Options),
- {ok, Body};
-
-return_answer(Options, {StatusLine, Headers, BinBody}) ->
-
- Body = format_body(BinBody, Options),
-
- case proplists:get_value(full_result, Options, true) of
- true ->
- {ok, {StatusLine, Headers, Body}};
- false ->
- {_, Status, _} = StatusLine,
- {ok, {Status, Body}}
- end.
-
-format_body(BinBody, Options) ->
- case proplists:get_value(body_format, Options, string) of
- string ->
- binary_to_list(BinBody);
- _ ->
- BinBody
- end.
+ httpc:cookie_header(Url, Profile).
-%% This options is a workaround for http servers that do not follow the
-%% http standard and have case sensative header parsing. Should only be
-%% used if there is no other way to communicate with the server or for
-%% testing purpose.
-headers_as_is(Headers, Options) ->
- case proplists:get_value(headers_as_is, Options, false) of
- false ->
- [];
- true ->
- Headers
- end.
+%%--------------------------------------------------------------------------
+%% stream_next(Pid)
+%%-------------------------------------------------------------------------
-http_options(HttpOptions) ->
- HttpOptionsDefault = http_options_default(),
- http_options(HttpOptionsDefault, HttpOptions, #http_options{}).
-
-http_options([], [], Acc) ->
- Acc;
-http_options([], HttpOptions, Acc) ->
- Fun = fun(BadOption) ->
- Report = io_lib:format("Invalid option ~p ignored ~n",
- [BadOption]),
- error_logger:info_report(Report)
- end,
- lists:foreach(Fun, HttpOptions),
- Acc;
-http_options([{Tag, Default, Idx, Post} | Defaults], HttpOptions, Acc) ->
- case lists:keysearch(Tag, 1, HttpOptions) of
- {value, {Tag, Val0}} ->
- case Post(Val0) of
- {ok, Val} ->
- Acc2 = setelement(Idx, Acc, Val),
- HttpOptions2 = lists:keydelete(Tag, 1, HttpOptions),
- http_options(Defaults, HttpOptions2, Acc2);
- error ->
- Report = io_lib:format("Invalid option ~p:~p ignored ~n",
- [Tag, Val0]),
- error_logger:info_report(Report),
- HttpOptions2 = lists:keydelete(Tag, 1, HttpOptions),
- http_options(Defaults, HttpOptions2, Acc)
- end;
- false ->
- DefaultVal =
- case Default of
- {value, Val} ->
- Val;
- {field, DefaultIdx} ->
- element(DefaultIdx, Acc)
- end,
- Acc2 = setelement(Idx, Acc, DefaultVal),
- http_options(Defaults, HttpOptions, Acc2)
- end.
-
-http_options_default() ->
- VersionPost =
- fun(Value) when is_atom(Value) ->
- {ok, http_util:to_upper(atom_to_list(Value))};
- (Value) when is_list(Value) ->
- {ok, http_util:to_upper(Value)};
- (_) ->
- error
- end,
- TimeoutPost = fun(Value) when is_integer(Value) andalso (Value >= 0) ->
- {ok, Value};
- (infinity = Value) ->
- {ok, Value};
- (_) ->
- error
- end,
- AutoRedirectPost = fun(Value) when (Value =:= true) orelse
- (Value =:= false) ->
- {ok, Value};
- (_) ->
- error
- end,
- SslPost = fun(Value) when is_list(Value) ->
- {ok, Value};
- (_) ->
- error
- end,
- ProxyAuthPost = fun({User, Passwd} = Value) when is_list(User) andalso
- is_list(Passwd) ->
- {ok, Value};
- (_) ->
- error
- end,
- RelaxedPost = fun(Value) when (Value =:= true) orelse
- (Value =:= false) ->
- {ok, Value};
- (_) ->
- error
- end,
- ConnTimeoutPost =
- fun(Value) when is_integer(Value) andalso (Value >= 0) ->
- {ok, Value};
- (infinity = Value) ->
- {ok, Value};
- (_) ->
- error
- end,
- [
- {version, {value, "HTTP/1.1"}, #http_options.version, VersionPost},
- {timeout, {value, ?HTTP_REQUEST_TIMEOUT}, #http_options.timeout, TimeoutPost},
- {autoredirect, {value, true}, #http_options.autoredirect, AutoRedirectPost},
- {ssl, {value, []}, #http_options.ssl, SslPost},
- {proxy_auth, {value, undefined}, #http_options.proxy_auth, ProxyAuthPost},
- {relaxed, {value, false}, #http_options.relaxed, RelaxedPost},
- %% this field has to be *after* the timeout field (as that field is used for the default value)
- {connect_timeout, {field, #http_options.timeout}, #http_options.connect_timeout, ConnTimeoutPost}
- ].
-
-validate_options(Options) ->
- (catch validate_options(Options, [])).
-
-validate_options([], ValidateOptions) ->
- {ok, lists:reverse(ValidateOptions)};
-
-validate_options([{proxy, Proxy} = Opt| Tail], Acc) ->
- validate_proxy(Proxy),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{max_sessions, Value} = Opt| Tail], Acc) ->
- validate_max_sessions(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{keep_alive_timeout, Value} = Opt| Tail], Acc) ->
- validate_keep_alive_timeout(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{max_keep_alive_length, Value} = Opt| Tail], Acc) ->
- validate_max_keep_alive_length(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{pipeline_timeout, Value} = Opt| Tail], Acc) ->
- validate_pipeline_timeout(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{max_pipeline_length, Value} = Opt| Tail], Acc) ->
- validate_max_pipeline_length(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{cookies, Value} = Opt| Tail], Acc) ->
- validate_cookies(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{ipfamily, Value} = Opt| Tail], Acc) ->
- validate_ipfamily(Value),
- validate_options(Tail, [Opt | Acc]);
-
-%% For backward compatibillity
-validate_options([{ipv6, Value}| Tail], Acc) ->
- NewValue = validate_ipv6(Value),
- Opt = {ipfamily, NewValue},
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{ip, Value} = Opt| Tail], Acc) ->
- validate_ip(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{port, Value} = Opt| Tail], Acc) ->
- validate_port(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{verbose, Value} = Opt| Tail], Acc) ->
- validate_verbose(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{_, _} = Opt| _], _Acc) ->
- {error, {not_an_option, Opt}}.
-
-
-validate_proxy({{ProxyHost, ProxyPort}, NoProxy} = Proxy)
- when is_list(ProxyHost) andalso
- is_integer(ProxyPort) andalso
- is_list(NoProxy) ->
- Proxy;
-validate_proxy(BadProxy) ->
- bad_option(proxy, BadProxy).
-
-validate_max_sessions(Value) when is_integer(Value) andalso (Value >= 0) ->
- Value;
-validate_max_sessions(BadValue) ->
- bad_option(max_sessions, BadValue).
-
-validate_keep_alive_timeout(Value) when is_integer(Value) andalso (Value >= 0) ->
- Value;
-validate_keep_alive_timeout(infinity = Value) ->
- Value;
-validate_keep_alive_timeout(BadValue) ->
- bad_option(keep_alive_timeout, BadValue).
-
-validate_max_keep_alive_length(Value) when is_integer(Value) andalso (Value >= 0) ->
- Value;
-validate_max_keep_alive_length(BadValue) ->
- bad_option(max_keep_alive_length, BadValue).
-
-validate_pipeline_timeout(Value) when is_integer(Value) ->
- Value;
-validate_pipeline_timeout(infinity = Value) ->
- Value;
-validate_pipeline_timeout(BadValue) ->
- bad_option(pipeline_timeout, BadValue).
-
-validate_max_pipeline_length(Value) when is_integer(Value) ->
- Value;
-validate_max_pipeline_length(BadValue) ->
- bad_option(max_pipeline_length, BadValue).
-
-validate_cookies(Value)
- when ((Value =:= enabled) orelse
- (Value =:= disabled) orelse
- (Value =:= verify)) ->
- Value;
-validate_cookies(BadValue) ->
- bad_option(cookies, BadValue).
-
-validate_ipv6(Value) when (Value =:= enabled) orelse (Value =:= disabled) ->
- case Value of
- enabled ->
- inet6fb4;
- disabled ->
- inet
- end;
-validate_ipv6(BadValue) ->
- bad_option(ipv6, BadValue).
-
-validate_ipfamily(Value)
- when (Value =:= inet) orelse (Value =:= inet6) orelse (Value =:= inet6fb4) ->
- Value;
-validate_ipfamily(BadValue) ->
- bad_option(ipfamily, BadValue).
-
-validate_ip(Value)
- when is_tuple(Value) andalso ((size(Value) =:= 4) orelse (size(Value) =:= 8)) ->
- Value;
-validate_ip(BadValue) ->
- bad_option(ip, BadValue).
-
-validate_port(Value) when is_integer(Value) ->
- Value;
-validate_port(BadValue) ->
- bad_option(port, BadValue).
-
-validate_verbose(Value)
- when ((Value =:= false) orelse
- (Value =:= verbose) orelse
- (Value =:= debug) orelse
- (Value =:= trace)) ->
- ok;
-validate_verbose(BadValue) ->
- bad_option(verbose, BadValue).
-
-bad_option(Option, BadValue) ->
- throw({error, {bad_option, Option, BadValue}}).
-
-
-
-header_record([], RequestHeaders, Host, Version) ->
- validate_headers(RequestHeaders, Host, Version);
-header_record([{"cache-control", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'cache-control' = Val},
- Host, Version);
-header_record([{"connection", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{connection = Val}, Host,
- Version);
-header_record([{"date", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{date = Val}, Host,
- Version);
-header_record([{"pragma", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{pragma = Val}, Host,
- Version);
-header_record([{"trailer", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{trailer = Val}, Host,
- Version);
-header_record([{"transfer-encoding", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'transfer-encoding' = Val},
- Host, Version);
-header_record([{"upgrade", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{upgrade = Val}, Host,
- Version);
-header_record([{"via", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{via = Val}, Host,
- Version);
-header_record([{"warning", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{warning = Val}, Host,
- Version);
-header_record([{"accept", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{accept = Val}, Host,
- Version);
-header_record([{"accept-charset", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'accept-charset' = Val},
- Host, Version);
-header_record([{"accept-encoding", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'accept-encoding' = Val},
- Host, Version);
-header_record([{"accept-language", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'accept-language' = Val},
- Host, Version);
-header_record([{"authorization", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{authorization = Val},
- Host, Version);
-header_record([{"expect", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{expect = Val}, Host,
- Version);
-header_record([{"from", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{from = Val}, Host,
- Version);
-header_record([{"host", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{host = Val}, Host,
- Version);
-header_record([{"if-match", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-match' = Val},
- Host, Version);
-header_record([{"if-modified-since", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'if-modified-since' = Val},
- Host, Version);
-header_record([{"if-none-match", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-none-match' = Val},
- Host, Version);
-header_record([{"if-range", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-range' = Val},
- Host, Version);
-
-header_record([{"if-unmodified-since", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-unmodified-since'
- = Val}, Host, Version);
-header_record([{"max-forwards", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'max-forwards' = Val},
- Host, Version);
-header_record([{"proxy-authorization", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'proxy-authorization'
- = Val}, Host, Version);
-header_record([{"range", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{range = Val}, Host,
- Version);
-header_record([{"referer", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{referer = Val}, Host,
- Version);
-header_record([{"te", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{te = Val}, Host,
- Version);
-header_record([{"user-agent", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'user-agent' = Val},
- Host, Version);
-header_record([{"allow", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{allow = Val}, Host,
- Version);
-header_record([{"content-encoding", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'content-encoding' = Val},
- Host, Version);
-header_record([{"content-language", Val} | Rest], RequestHeaders,
- Host, Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'content-language' = Val},
- Host, Version);
-header_record([{"content-length", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-length' = Val},
- Host, Version);
-header_record([{"content-location", Val} | Rest], RequestHeaders,
- Host, Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'content-location' = Val},
- Host, Version);
-header_record([{"content-md5", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-md5' = Val},
- Host, Version);
-header_record([{"content-range", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-range' = Val},
- Host, Version);
-header_record([{"content-type", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-type' = Val},
- Host, Version);
-header_record([{"expires", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{expires = Val}, Host,
- Version);
-header_record([{"last-modified", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'last-modified' = Val},
- Host, Version);
-header_record([{Key, Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{
- other = [{Key, Val} |
- RequestHeaders#http_request_h.other]},
- Host, Version).
+stream_next(Pid) ->
+ httpc:stream_next(Pid).
-validate_headers(RequestHeaders = #http_request_h{te = undefined}, Host,
- "HTTP/1.1" = Version) ->
- validate_headers(RequestHeaders#http_request_h{te = ""}, Host,
- "HTTP/1.1" = Version);
-validate_headers(RequestHeaders = #http_request_h{host = undefined},
- Host, "HTTP/1.1" = Version) ->
- validate_headers(RequestHeaders#http_request_h{host = Host}, Host, Version);
-validate_headers(RequestHeaders, _, _) ->
- RequestHeaders.
+%%--------------------------------------------------------------------------
+%% default_profile()
+%%-------------------------------------------------------------------------
default_profile() ->
- ?DEFAULT_PROFILE.
-
-profile_name(?DEFAULT_PROFILE) ->
- httpc_manager;
-profile_name(Pid) when is_pid(Pid) ->
- Pid;
-profile_name(Profile) ->
- list_to_atom("httpc_manager_" ++ atom_to_list(Profile)).
-
-child_name2info(undefined) ->
- {error, no_such_service};
-child_name2info(httpc_manager) ->
- {ok, [{profile, default}]};
-child_name2info({http, Profile}) ->
- {ok, [{profile, Profile}]}.
-
-child_name(_, []) ->
- undefined;
-child_name(Pid, [{Name, Pid} | _]) ->
- Name;
-child_name(Pid, [_ | Children]) ->
- child_name(Pid, Children).
-
-%% d(F) ->
-%% d(F, []).
-
-%% d(F, A) ->
-%% d(get(dbg), F, A).
-
-%% d(true, F, A) ->
-%% io:format(user, "~w:~w:" ++ F ++ "~n", [self(), ?MODULE | A]);
-%% d(_, _, _) ->
-%% ok.
-
+ httpc:default_profile().
diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl
new file mode 100644
index 0000000000..5205605e0a
--- /dev/null
+++ b/lib/inets/src/http_client/httpc.erl
@@ -0,0 +1,1079 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+%% Description:
+%%% This version of the HTTP/1.1 client supports:
+%%% - RFC 2616 HTTP 1.1 client part
+%%% - RFC 2818 HTTP Over TLS
+
+-module(httpc).
+
+-behaviour(inets_service).
+
+%% API
+-export([
+ request/1, request/2, request/4, request/5,
+ cancel_request/1, cancel_request/2,
+ set_option/2, set_option/3,
+ set_options/1, set_options/2,
+ store_cookies/2, store_cookies/3,
+ cookie_header/1, cookie_header/2,
+ which_cookies/0, which_cookies/1,
+ reset_cookies/0, reset_cookies/1,
+ stream_next/1,
+ default_profile/0,
+ profile_name/1, profile_name/2,
+ info/0, info/1
+ ]).
+
+%% Behavior callbacks
+-export([start_standalone/1, start_service/1,
+ stop_service/1,
+ services/0, service_info/1]).
+
+-include("http_internal.hrl").
+-include("httpc_internal.hrl").
+
+-define(DEFAULT_PROFILE, default).
+
+
+%%%=========================================================================
+%%% API
+%%%=========================================================================
+
+default_profile() ->
+ ?DEFAULT_PROFILE.
+
+
+profile_name(?DEFAULT_PROFILE) ->
+ httpc_manager;
+profile_name(Profile) ->
+ profile_name("httpc_manager_", Profile).
+
+profile_name(Prefix, Profile) when is_atom(Profile) ->
+ list_to_atom(Prefix ++ atom_to_list(Profile));
+profile_name(Prefix, Profile) when is_pid(Profile) ->
+ ProfileStr0 =
+ string:strip(string:strip(erlang:pid_to_list(Profile), left, $<), right, $>),
+ F = fun($.) -> $_; (X) -> X end,
+ ProfileStr = [F(C) || C <- ProfileStr0],
+ list_to_atom(Prefix ++ "pid_" ++ ProfileStr).
+
+
+%%--------------------------------------------------------------------------
+%% request(Url) -> {ok, {StatusLine, Headers, Body}} | {error,Reason}
+%% request(Url Profile) ->
+%% {ok, {StatusLine, Headers, Body}} | {error,Reason}
+%%
+%% Url - string()
+%% Description: Calls request/4 with default values.
+%%--------------------------------------------------------------------------
+
+request(Url) ->
+ request(Url, default_profile()).
+
+request(Url, Profile) ->
+ request(get, {Url, []}, [], [], Profile).
+
+
+%%--------------------------------------------------------------------------
+%% request(Method, Request, HTTPOptions, Options [, Profile]) ->
+%% {ok, {StatusLine, Headers, Body}} | {ok, {Status, Body}} |
+%% {ok, RequestId} | {error,Reason} | {ok, {saved_as, FilePath}
+%%
+%% Method - atom() = head | get | put | post | trace | options| delete
+%% Request - {Url, Headers} | {Url, Headers, ContentType, Body}
+%% Url - string()
+%% HTTPOptions - [HttpOption]
+%% HTTPOption - {timeout, Time} | {connect_timeout, Time} |
+%% {ssl, SSLOptions} | {proxy_auth, {User, Password}}
+%% Ssloptions = [SSLOption]
+%% SSLOption = {verify, code()} | {depth, depth()} | {certfile, path()} |
+%% {keyfile, path()} | {password, string()} | {cacertfile, path()} |
+%% {ciphers, string()}
+%% Options - [Option]
+%% Option - {sync, Boolean} | {body_format, BodyFormat} |
+%% {full_result, Boolean} | {stream, To} |
+%% {headers_as_is, Boolean}
+%% StatusLine = {HTTPVersion, StatusCode, ReasonPhrase}</v>
+%% HTTPVersion = string()
+%% StatusCode = integer()
+%% ReasonPhrase = string()
+%% Headers = [Header]
+%% Header = {Field, Value}
+%% Field = string()
+%% Value = string()
+%% Body = string() | binary() - HTLM-code
+%%
+%% Description: Sends a HTTP-request. The function can be both
+%% syncronus and asynchronous in the later case the function will
+%% return {ok, RequestId} and later on a message will be sent to the
+%% calling process on the format {http, {RequestId, {StatusLine,
+%% Headers, Body}}} or {http, {RequestId, {error, Reason}}}
+%%--------------------------------------------------------------------------
+
+request(Method, Request, HttpOptions, Options) ->
+ request(Method, Request, HttpOptions, Options, default_profile()).
+
+request(Method, {Url, Headers}, HTTPOptions, Options, Profile)
+ when (Method =:= options) orelse
+ (Method =:= get) orelse
+ (Method =:= head) orelse
+ (Method =:= delete) orelse
+ (Method =:= trace) andalso
+ (is_atom(Profile) orelse is_pid(Profile)) ->
+ ?hcrt("request", [{method, Method},
+ {url, Url},
+ {headers, Headers},
+ {http_options, HTTPOptions},
+ {options, Options},
+ {profile, Profile}]),
+ case http_uri:parse(Url) of
+ {error, Reason} ->
+ {error, Reason};
+ ParsedUrl ->
+ handle_request(Method, Url, ParsedUrl, Headers, [], [],
+ HTTPOptions, Options, Profile)
+ end;
+
+request(Method, {Url,Headers,ContentType,Body}, HTTPOptions, Options, Profile)
+ when ((Method =:= post) orelse (Method =:= put)) andalso
+ (is_atom(Profile) orelse is_pid(Profile)) ->
+ ?hcrt("request", [{method, Method},
+ {url, Url},
+ {headers, Headers},
+ {content_type, ContentType},
+ {body, Body},
+ {http_options, HTTPOptions},
+ {options, Options},
+ {profile, Profile}]),
+ case http_uri:parse(Url) of
+ {error, Reason} ->
+ {error, Reason};
+ ParsedUrl ->
+ handle_request(Method, Url,
+ ParsedUrl, Headers, ContentType, Body,
+ HTTPOptions, Options, Profile)
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% cancel_request(RequestId) -> ok
+%% cancel_request(RequestId, Profile) -> ok
+%% RequestId - As returned by request/4
+%%
+%% Description: Cancels a HTTP-request.
+%%-------------------------------------------------------------------------
+cancel_request(RequestId) ->
+ cancel_request(RequestId, default_profile()).
+
+cancel_request(RequestId, Profile)
+ when is_atom(Profile) orelse is_pid(Profile) ->
+ ?hcrt("cancel request", [{request_id, RequestId}, {profile, Profile}]),
+ ok = httpc_manager:cancel_request(RequestId, profile_name(Profile)),
+ receive
+ %% If the request was already fulfilled throw away the
+ %% answer as the request has been canceled.
+ {http, {RequestId, _}} ->
+ ok
+ after 0 ->
+ ok
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% set_options(Options) -> ok | {error, Reason}
+%% set_options(Options, Profile) -> ok | {error, Reason}
+%% Options - [Option]
+%% Profile - atom()
+%% Option - {proxy, {Proxy, NoProxy}} | {max_sessions, MaxSessions} |
+%% {max_pipeline_length, MaxPipeline} |
+%% {pipeline_timeout, PipelineTimeout} | {cookies, CookieMode} |
+%% {ipfamily, IpFamily}
+%% Proxy - {Host, Port}
+%% NoProxy - [Domain | HostName | IPAddress]
+%% MaxSessions, MaxPipeline, PipelineTimeout = integer()
+%% CookieMode - enabled | disabled | verify
+%% IpFamily - inet | inet6 | inet6fb4
+%% Description: Informs the httpc_manager of the new settings.
+%%-------------------------------------------------------------------------
+set_options(Options) ->
+ set_options(Options, default_profile()).
+set_options(Options, Profile) when is_atom(Profile) orelse is_pid(Profile) ->
+ ?hcrt("set cookies", [{options, Options}, {profile, Profile}]),
+ case validate_options(Options) of
+ {ok, Opts} ->
+ try
+ begin
+ httpc_manager:set_options(Opts, profile_name(Profile))
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, inets_not_started}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+set_option(Key, Value) ->
+ set_option(Key, Value, default_profile()).
+
+set_option(Key, Value, Profile) ->
+ set_options([{Key, Value}], Profile).
+
+
+%%--------------------------------------------------------------------------
+%% store_cookies(SetCookieHeaders, Url [, Profile]) -> ok | {error, reason}
+%%
+%%
+%% Description: Store the cookies from <SetCookieHeaders>
+%% in the cookie database
+%% for the profile <Profile>. This function shall be used when the option
+%% cookie is set to verify.
+%%-------------------------------------------------------------------------
+store_cookies(SetCookieHeaders, Url) ->
+ store_cookies(SetCookieHeaders, Url, default_profile()).
+
+store_cookies(SetCookieHeaders, Url, Profile)
+ when is_atom(Profile) orelse is_pid(Profile) ->
+ ?hcrt("store cookies", [{set_cookie_headers, SetCookieHeaders},
+ {url, Url},
+ {profile, Profile}]),
+ try
+ begin
+ {_, _, Host, Port, Path, _} = http_uri:parse(Url),
+ Address = {Host, Port},
+ ProfileName = profile_name(Profile),
+ Cookies = httpc_cookie:cookies(SetCookieHeaders, Path, Host),
+ httpc_manager:store_cookies(Cookies, Address, ProfileName),
+ ok
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, {not_started, Profile}};
+ error:{badmatch, Bad} ->
+ {error, {parse_failed, Bad}}
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% cookie_header(Url [, Profile]) -> Header | {error, Reason}
+%%
+%% Description: Returns the cookie header that would be sent when making
+%% a request to <Url>.
+%%-------------------------------------------------------------------------
+cookie_header(Url) ->
+ cookie_header(Url, default_profile()).
+
+cookie_header(Url, Profile) ->
+ ?hcrt("cookie header", [{url, Url},
+ {profile, Profile}]),
+ try
+ begin
+ httpc_manager:which_cookies(Url, profile_name(Profile))
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, {not_started, Profile}}
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% which_cookies() -> [cookie()]
+%% which_cookies(Profile) -> [cookie()]
+%%
+%% Description: Debug function, dumping the cookie database
+%%-------------------------------------------------------------------------
+which_cookies() ->
+ which_cookies(default_profile()).
+
+which_cookies(Profile) ->
+ ?hcrt("which cookies", [{profile, Profile}]),
+ try
+ begin
+ httpc_manager:which_cookies(profile_name(Profile))
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, {not_started, Profile}}
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% info() -> list()
+%% info(Profile) -> list()
+%%
+%% Description: Debug function, retreive info about the profile
+%%-------------------------------------------------------------------------
+info() ->
+ info(default_profile()).
+
+info(Profile) ->
+ ?hcrt("info", [{profile, Profile}]),
+ try
+ begin
+ httpc_manager:info(profile_name(Profile))
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, {not_started, Profile}}
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% reset_cookies() -> void()
+%% reset_cookies(Profile) -> void()
+%%
+%% Description: Debug function, reset the cookie database
+%%-------------------------------------------------------------------------
+reset_cookies() ->
+ reset_cookies(default_profile()).
+
+reset_cookies(Profile) ->
+ ?hcrt("reset cookies", [{profile, Profile}]),
+ try
+ begin
+ httpc_manager:reset_cookies(profile_name(Profile))
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, {not_started, Profile}}
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% stream_next(Pid) -> Header | {error, Reason}
+%%
+%% Description: Triggers the next message to be streamed, e.i.
+%% same behavior as active once for sockets.
+%%-------------------------------------------------------------------------
+stream_next(Pid) ->
+ ?hcrt("stream next", [{handler, Pid}]),
+ httpc_handler:stream_next(Pid).
+
+
+%%%========================================================================
+%%% Behaviour callbacks
+%%%========================================================================
+start_standalone(PropList) ->
+ ?hcrt("start standalone", [{proplist, PropList}]),
+ case proplists:get_value(profile, PropList) of
+ undefined ->
+ {error, no_profile};
+ Profile ->
+ Dir =
+ proplists:get_value(data_dir, PropList, only_session_cookies),
+ httpc_manager:start_link(Profile, Dir, stand_alone)
+ end.
+
+start_service(Config) ->
+ ?hcrt("start service", [{config, Config}]),
+ httpc_profile_sup:start_child(Config).
+
+stop_service(Profile) when is_atom(Profile) ->
+ ?hcrt("stop service", [{profile, Profile}]),
+ httpc_profile_sup:stop_child(Profile);
+stop_service(Pid) when is_pid(Pid) ->
+ ?hcrt("stop service", [{pid, Pid}]),
+ case service_info(Pid) of
+ {ok, [{profile, Profile}]} ->
+ stop_service(Profile);
+ Error ->
+ Error
+ end.
+
+services() ->
+ [{httpc, Pid} || {_, Pid, _, _} <-
+ supervisor:which_children(httpc_profile_sup)].
+service_info(Pid) ->
+ try [{ChildName, ChildPid} ||
+ {ChildName, ChildPid, _, _} <-
+ supervisor:which_children(httpc_profile_sup)] of
+ Children ->
+ child_name2info(child_name(Pid, Children))
+ catch
+ exit:{noproc, _} ->
+ {error, service_not_available}
+ end.
+
+
+%%%========================================================================
+%%% Internal functions
+%%%========================================================================
+
+handle_request(Method, Url,
+ {Scheme, UserInfo, Host, Port, Path, Query},
+ Headers, ContentType, Body,
+ HTTPOptions0, Options0, Profile) ->
+
+ Started = http_util:timestamp(),
+ NewHeaders = [{http_util:to_lower(Key), Val} || {Key, Val} <- Headers],
+
+ try
+ begin
+ HTTPOptions = http_options(HTTPOptions0),
+ Options = request_options(Options0),
+ Sync = proplists:get_value(sync, Options),
+ Stream = proplists:get_value(stream, Options),
+ Host2 = header_host(Host, Port),
+ HeadersRecord = header_record(NewHeaders, Host2, HTTPOptions),
+ Receiver = proplists:get_value(receiver, Options),
+ SocketOpts = proplists:get_value(socket_opts, Options),
+ Request = #request{from = Receiver,
+ scheme = Scheme,
+ address = {Host, Port},
+ path = Path,
+ pquery = Query,
+ method = Method,
+ headers = HeadersRecord,
+ content = {ContentType, Body},
+ settings = HTTPOptions,
+ abs_uri = Url,
+ userinfo = UserInfo,
+ stream = Stream,
+ headers_as_is = headers_as_is(Headers, Options),
+ socket_opts = SocketOpts,
+ started = Started},
+ case httpc_manager:request(Request, profile_name(Profile)) of
+ {ok, RequestId} ->
+ handle_answer(RequestId, Sync, Options);
+ {error, Reason} ->
+ {error, Reason}
+ end
+ end
+ catch
+ error:{noproc, _} ->
+ {error, {not_started, Profile}};
+ throw:Error ->
+ Error
+ end.
+
+
+handle_answer(RequestId, false, _) ->
+ {ok, RequestId};
+handle_answer(RequestId, true, Options) ->
+ receive
+ {http, {RequestId, saved_to_file}} ->
+ {ok, saved_to_file};
+ {http, {RequestId, {_,_,_} = Result}} ->
+ return_answer(Options, Result);
+ {http, {RequestId, {error, Reason}}} ->
+ {error, Reason}
+ end.
+
+return_answer(Options, {{"HTTP/0.9",_,_}, _, BinBody}) ->
+ Body = maybe_format_body(BinBody, Options),
+ {ok, Body};
+
+return_answer(Options, {StatusLine, Headers, BinBody}) ->
+
+ Body = maybe_format_body(BinBody, Options),
+
+ case proplists:get_value(full_result, Options, true) of
+ true ->
+ {ok, {StatusLine, Headers, Body}};
+ false ->
+ {_, Status, _} = StatusLine,
+ {ok, {Status, Body}}
+ end.
+
+maybe_format_body(BinBody, Options) ->
+ case proplists:get_value(body_format, Options, string) of
+ string ->
+ binary_to_list(BinBody);
+ _ ->
+ BinBody
+ end.
+
+%% This options is a workaround for http servers that do not follow the
+%% http standard and have case sensative header parsing. Should only be
+%% used if there is no other way to communicate with the server or for
+%% testing purpose.
+headers_as_is(Headers, Options) ->
+ case proplists:get_value(headers_as_is, Options, false) of
+ false ->
+ [];
+ true ->
+ Headers
+ end.
+
+
+http_options(HttpOptions) ->
+ HttpOptionsDefault = http_options_default(),
+ http_options(HttpOptionsDefault, HttpOptions, #http_options{}).
+
+http_options([], [], Acc) ->
+ Acc;
+http_options([], HttpOptions, Acc) ->
+ Fun = fun(BadOption) ->
+ Report = io_lib:format("Invalid option ~p ignored ~n",
+ [BadOption]),
+ error_logger:info_report(Report)
+ end,
+ lists:foreach(Fun, HttpOptions),
+ Acc;
+http_options([{Tag, Default, Idx, Post} | Defaults], HttpOptions, Acc) ->
+ case lists:keysearch(Tag, 1, HttpOptions) of
+ {value, {Tag, Val0}} ->
+ case Post(Val0) of
+ {ok, Val} ->
+ Acc2 = setelement(Idx, Acc, Val),
+ HttpOptions2 = lists:keydelete(Tag, 1, HttpOptions),
+ http_options(Defaults, HttpOptions2, Acc2);
+ error ->
+ Report = io_lib:format("Invalid option ~p:~p ignored ~n",
+ [Tag, Val0]),
+ error_logger:info_report(Report),
+ HttpOptions2 = lists:keydelete(Tag, 1, HttpOptions),
+ http_options(Defaults, HttpOptions2, Acc)
+ end;
+ false ->
+ DefaultVal =
+ case Default of
+ {value, Val} ->
+ Val;
+ {field, DefaultIdx} ->
+ element(DefaultIdx, Acc)
+ end,
+ Acc2 = setelement(Idx, Acc, DefaultVal),
+ http_options(Defaults, HttpOptions, Acc2)
+ end.
+
+http_options_default() ->
+ VersionPost =
+ fun(Value) when is_atom(Value) ->
+ {ok, http_util:to_upper(atom_to_list(Value))};
+ (Value) when is_list(Value) ->
+ {ok, http_util:to_upper(Value)};
+ (_) ->
+ error
+ end,
+ TimeoutPost = fun(Value) when is_integer(Value) andalso (Value >= 0) ->
+ {ok, Value};
+ (infinity = Value) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ AutoRedirectPost = fun(Value) when (Value =:= true) orelse
+ (Value =:= false) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ SslPost = fun(Value) when is_list(Value) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ ProxyAuthPost = fun({User, Passwd} = Value) when is_list(User) andalso
+ is_list(Passwd) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ RelaxedPost = fun(Value) when (Value =:= true) orelse
+ (Value =:= false) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ ConnTimeoutPost =
+ fun(Value) when is_integer(Value) andalso (Value >= 0) ->
+ {ok, Value};
+ (infinity = Value) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ [
+ {version, {value, "HTTP/1.1"}, #http_options.version, VersionPost},
+ {timeout, {value, ?HTTP_REQUEST_TIMEOUT}, #http_options.timeout, TimeoutPost},
+ {autoredirect, {value, true}, #http_options.autoredirect, AutoRedirectPost},
+ {ssl, {value, []}, #http_options.ssl, SslPost},
+ {proxy_auth, {value, undefined}, #http_options.proxy_auth, ProxyAuthPost},
+ {relaxed, {value, false}, #http_options.relaxed, RelaxedPost},
+ %% this field has to be *after* the timeout field (as that field is used for the default value)
+ {connect_timeout, {field, #http_options.timeout}, #http_options.connect_timeout, ConnTimeoutPost}
+ ].
+
+
+request_options_defaults() ->
+ VerifyBoolean =
+ fun(Value) when ((Value =:= true) orelse (Value =:= false)) ->
+ ok;
+ (_) ->
+ error
+ end,
+
+ VerifySync = VerifyBoolean,
+
+ VerifyStream =
+ fun(none = _Value) ->
+ ok;
+ (self = _Value) ->
+ ok;
+ ({self, once} = _Value) ->
+ ok;
+ (Value) when is_list(Value) ->
+ ok;
+ (_) ->
+ error
+ end,
+
+ VerifyBodyFormat =
+ fun(string = _Value) ->
+ ok;
+ (binary = _Value) ->
+ ok;
+ (_) ->
+ error
+ end,
+
+ VerifyFullResult = VerifyBoolean,
+
+ VerifyHeaderAsIs = VerifyBoolean,
+
+ VerifyReceiver =
+ fun(Value) when is_pid(Value) ->
+ ok;
+ ({M, F, A}) when (is_atom(M) andalso
+ is_atom(F) andalso
+ is_list(A)) ->
+ ok;
+ (Value) when is_function(Value, 1) ->
+ ok;
+ (_) ->
+ error
+ end,
+
+ VerifySocketOpts =
+ fun([]) ->
+ {ok, undefined};
+ (Value) when is_list(Value) ->
+ ok;
+ (_) ->
+ error
+ end,
+
+ [
+ {sync, true, VerifySync},
+ {stream, none, VerifyStream},
+ {body_format, string, VerifyBodyFormat},
+ {full_result, true, VerifyFullResult},
+ {headers_as_is, false, VerifyHeaderAsIs},
+ {receiver, self(), VerifyReceiver},
+ {socket_opts, undefined, VerifySocketOpts}
+ ].
+
+request_options(Options) ->
+ Defaults = request_options_defaults(),
+ request_options(Defaults, Options, []).
+
+request_options([], [], Acc) ->
+ request_options_sanity_check(Acc),
+ lists:reverse(Acc);
+request_options([], Options, Acc) ->
+ Fun = fun(BadOption) ->
+ Report = io_lib:format("Invalid option ~p ignored ~n",
+ [BadOption]),
+ error_logger:info_report(Report)
+ end,
+ lists:foreach(Fun, Options),
+ Acc;
+request_options([{Key, DefaultVal, Verify} | Defaults], Options, Acc) ->
+ case lists:keysearch(Key, 1, Options) of
+ {value, {Key, Value}} ->
+ case Verify(Value) of
+ ok ->
+ Options2 = lists:keydelete(Key, 1, Options),
+ request_options(Defaults, Options2, [{Key, Value} | Acc]);
+ {ok, Value2} ->
+ Options2 = lists:keydelete(Key, 1, Options),
+ request_options(Defaults, Options2, [{Key, Value2} | Acc]);
+ error ->
+ Report = io_lib:format("Invalid option ~p:~p ignored ~n",
+ [Key, Value]),
+ error_logger:info_report(Report),
+ Options2 = lists:keydelete(Key, 1, Options),
+ request_options(Defaults, Options2, Acc)
+ end;
+ false ->
+ request_options(Defaults, Options, [{Key, DefaultVal} | Acc])
+ end.
+
+request_options_sanity_check(Opts) ->
+ case proplists:get_value(sync, Opts) of
+ Sync when (Sync =:= true) ->
+ case proplists:get_value(receiver, Opts) of
+ Pid when is_pid(Pid) andalso (Pid =:= self()) ->
+ ok;
+ BadReceiver ->
+ throw({error, {bad_options_combo,
+ [{sync, true}, {receiver, BadReceiver}]}})
+ end,
+ case proplists:get_value(stream, Opts) of
+ Stream when (Stream =:= self) orelse
+ (Stream =:= {self, once}) ->
+ throw({error, streaming_error});
+ _ ->
+ ok
+ end;
+ _ ->
+ ok
+ end,
+ ok.
+
+validate_options(Options) ->
+ (catch validate_options(Options, [])).
+
+validate_options([], ValidateOptions) ->
+ {ok, lists:reverse(ValidateOptions)};
+
+validate_options([{proxy, Proxy} = Opt| Tail], Acc) ->
+ validate_proxy(Proxy),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{max_sessions, Value} = Opt| Tail], Acc) ->
+ validate_max_sessions(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{keep_alive_timeout, Value} = Opt| Tail], Acc) ->
+ validate_keep_alive_timeout(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{max_keep_alive_length, Value} = Opt| Tail], Acc) ->
+ validate_max_keep_alive_length(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{pipeline_timeout, Value} = Opt| Tail], Acc) ->
+ validate_pipeline_timeout(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{max_pipeline_length, Value} = Opt| Tail], Acc) ->
+ validate_max_pipeline_length(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{cookies, Value} = Opt| Tail], Acc) ->
+ validate_cookies(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{ipfamily, Value} = Opt| Tail], Acc) ->
+ validate_ipfamily(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+%% For backward compatibillity
+validate_options([{ipv6, Value}| Tail], Acc) ->
+ NewValue = validate_ipv6(Value),
+ Opt = {ipfamily, NewValue},
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{ip, Value} = Opt| Tail], Acc) ->
+ validate_ip(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{port, Value} = Opt| Tail], Acc) ->
+ validate_port(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{socket_opts, Value} = Opt| Tail], Acc) ->
+ validate_socket_opts(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{verbose, Value} = Opt| Tail], Acc) ->
+ validate_verbose(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{_, _} = Opt| _], _Acc) ->
+ {error, {not_an_option, Opt}}.
+
+
+validate_proxy({{ProxyHost, ProxyPort}, NoProxy} = Proxy)
+ when is_list(ProxyHost) andalso
+ is_integer(ProxyPort) andalso
+ is_list(NoProxy) ->
+ Proxy;
+validate_proxy(BadProxy) ->
+ bad_option(proxy, BadProxy).
+
+validate_max_sessions(Value) when is_integer(Value) andalso (Value >= 0) ->
+ Value;
+validate_max_sessions(BadValue) ->
+ bad_option(max_sessions, BadValue).
+
+validate_keep_alive_timeout(Value) when is_integer(Value) andalso (Value >= 0) ->
+ Value;
+validate_keep_alive_timeout(infinity = Value) ->
+ Value;
+validate_keep_alive_timeout(BadValue) ->
+ bad_option(keep_alive_timeout, BadValue).
+
+validate_max_keep_alive_length(Value) when is_integer(Value) andalso (Value >= 0) ->
+ Value;
+validate_max_keep_alive_length(BadValue) ->
+ bad_option(max_keep_alive_length, BadValue).
+
+validate_pipeline_timeout(Value) when is_integer(Value) ->
+ Value;
+validate_pipeline_timeout(infinity = Value) ->
+ Value;
+validate_pipeline_timeout(BadValue) ->
+ bad_option(pipeline_timeout, BadValue).
+
+validate_max_pipeline_length(Value) when is_integer(Value) ->
+ Value;
+validate_max_pipeline_length(BadValue) ->
+ bad_option(max_pipeline_length, BadValue).
+
+validate_cookies(Value)
+ when ((Value =:= enabled) orelse
+ (Value =:= disabled) orelse
+ (Value =:= verify)) ->
+ Value;
+validate_cookies(BadValue) ->
+ bad_option(cookies, BadValue).
+
+validate_ipv6(Value) when (Value =:= enabled) orelse (Value =:= disabled) ->
+ case Value of
+ enabled ->
+ inet6fb4;
+ disabled ->
+ inet
+ end;
+validate_ipv6(BadValue) ->
+ bad_option(ipv6, BadValue).
+
+validate_ipfamily(Value)
+ when (Value =:= inet) orelse (Value =:= inet6) orelse (Value =:= inet6fb4) ->
+ Value;
+validate_ipfamily(BadValue) ->
+ bad_option(ipfamily, BadValue).
+
+validate_ip(Value)
+ when is_tuple(Value) andalso ((size(Value) =:= 4) orelse (size(Value) =:= 8)) ->
+ Value;
+validate_ip(BadValue) ->
+ bad_option(ip, BadValue).
+
+validate_port(Value) when is_integer(Value) ->
+ Value;
+validate_port(BadValue) ->
+ bad_option(port, BadValue).
+
+validate_socket_opts(Value) when is_list(Value) ->
+ Value;
+validate_socket_opts(BadValue) ->
+ bad_option(socket_opts, BadValue).
+
+validate_verbose(Value)
+ when ((Value =:= false) orelse
+ (Value =:= verbose) orelse
+ (Value =:= debug) orelse
+ (Value =:= trace)) ->
+ ok;
+validate_verbose(BadValue) ->
+ bad_option(verbose, BadValue).
+
+bad_option(Option, BadValue) ->
+ throw({error, {bad_option, Option, BadValue}}).
+
+
+header_host(Host, 80 = _Port) ->
+ Host;
+header_host(Host, Port) ->
+ Host ++ ":" ++ integer_to_list(Port).
+
+
+header_record(NewHeaders, Host, #http_options{version = Version}) ->
+ header_record(NewHeaders, #http_request_h{}, Host, Version).
+
+header_record([], RequestHeaders, Host, Version) ->
+ validate_headers(RequestHeaders, Host, Version);
+header_record([{"cache-control", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'cache-control' = Val},
+ Host, Version);
+header_record([{"connection", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{connection = Val}, Host,
+ Version);
+header_record([{"date", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{date = Val}, Host,
+ Version);
+header_record([{"pragma", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{pragma = Val}, Host,
+ Version);
+header_record([{"trailer", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{trailer = Val}, Host,
+ Version);
+header_record([{"transfer-encoding", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest,
+ RequestHeaders#http_request_h{'transfer-encoding' = Val},
+ Host, Version);
+header_record([{"upgrade", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{upgrade = Val}, Host,
+ Version);
+header_record([{"via", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{via = Val}, Host,
+ Version);
+header_record([{"warning", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{warning = Val}, Host,
+ Version);
+header_record([{"accept", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{accept = Val}, Host,
+ Version);
+header_record([{"accept-charset", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'accept-charset' = Val},
+ Host, Version);
+header_record([{"accept-encoding", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'accept-encoding' = Val},
+ Host, Version);
+header_record([{"accept-language", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'accept-language' = Val},
+ Host, Version);
+header_record([{"authorization", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{authorization = Val},
+ Host, Version);
+header_record([{"expect", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{expect = Val}, Host,
+ Version);
+header_record([{"from", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{from = Val}, Host,
+ Version);
+header_record([{"host", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{host = Val}, Host,
+ Version);
+header_record([{"if-match", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'if-match' = Val},
+ Host, Version);
+header_record([{"if-modified-since", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest,
+ RequestHeaders#http_request_h{'if-modified-since' = Val},
+ Host, Version);
+header_record([{"if-none-match", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'if-none-match' = Val},
+ Host, Version);
+header_record([{"if-range", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'if-range' = Val},
+ Host, Version);
+
+header_record([{"if-unmodified-since", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'if-unmodified-since'
+ = Val}, Host, Version);
+header_record([{"max-forwards", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'max-forwards' = Val},
+ Host, Version);
+header_record([{"proxy-authorization", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'proxy-authorization'
+ = Val}, Host, Version);
+header_record([{"range", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{range = Val}, Host,
+ Version);
+header_record([{"referer", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{referer = Val}, Host,
+ Version);
+header_record([{"te", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{te = Val}, Host,
+ Version);
+header_record([{"user-agent", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'user-agent' = Val},
+ Host, Version);
+header_record([{"allow", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{allow = Val}, Host,
+ Version);
+header_record([{"content-encoding", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest,
+ RequestHeaders#http_request_h{'content-encoding' = Val},
+ Host, Version);
+header_record([{"content-language", Val} | Rest], RequestHeaders,
+ Host, Version) ->
+ header_record(Rest,
+ RequestHeaders#http_request_h{'content-language' = Val},
+ Host, Version);
+header_record([{"content-length", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'content-length' = Val},
+ Host, Version);
+header_record([{"content-location", Val} | Rest], RequestHeaders,
+ Host, Version) ->
+ header_record(Rest,
+ RequestHeaders#http_request_h{'content-location' = Val},
+ Host, Version);
+header_record([{"content-md5", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'content-md5' = Val},
+ Host, Version);
+header_record([{"content-range", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'content-range' = Val},
+ Host, Version);
+header_record([{"content-type", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'content-type' = Val},
+ Host, Version);
+header_record([{"expires", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{expires = Val}, Host,
+ Version);
+header_record([{"last-modified", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'last-modified' = Val},
+ Host, Version);
+header_record([{Key, Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{
+ other = [{Key, Val} |
+ RequestHeaders#http_request_h.other]},
+ Host, Version).
+
+validate_headers(RequestHeaders = #http_request_h{te = undefined}, Host,
+ "HTTP/1.1" = Version) ->
+ validate_headers(RequestHeaders#http_request_h{te = ""}, Host,
+ "HTTP/1.1" = Version);
+validate_headers(RequestHeaders = #http_request_h{host = undefined},
+ Host, "HTTP/1.1" = Version) ->
+ validate_headers(RequestHeaders#http_request_h{host = Host}, Host, Version);
+validate_headers(RequestHeaders, _, _) ->
+ RequestHeaders.
+
+
+child_name2info(undefined) ->
+ {error, no_such_service};
+child_name2info(httpc_manager) ->
+ {ok, [{profile, default}]};
+child_name2info({httpc, Profile}) ->
+ {ok, [{profile, Profile}]}.
+
+child_name(_, []) ->
+ undefined;
+child_name(Pid, [{Name, Pid} | _]) ->
+ Name;
+child_name(Pid, [_ | Children]) ->
+ child_name(Pid, Children).
+
+%% d(F) ->
+%% d(F, []).
+
+%% d(F, A) ->
+%% d(get(dbg), F, A).
+
+%% d(true, F, A) ->
+%% io:format(user, "~w:~w:" ++ F ++ "~n", [self(), ?MODULE | A]);
+%% d(_, _, _) ->
+%% ok.
+
diff --git a/lib/inets/src/http_client/http_cookie.erl b/lib/inets/src/http_client/httpc_cookie.erl
index e091070f72..586701b4a1 100644
--- a/lib/inets/src/http_client/http_cookie.erl
+++ b/lib/inets/src/http_client/httpc_cookie.erl
@@ -1,164 +1,260 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Description: Cookie handling according to RFC 2109
--module(http_cookie).
+-module(httpc_cookie).
-include("httpc_internal.hrl").
--export([header/4, cookies/3, open_cookie_db/1, close_cookie_db/1, insert/2]).
+-export([open_db/3, close_db/1, insert/2, header/4, cookies/3]).
+-export([reset_db/1, which_cookies/1]).
+
+-record(cookie_db, {db, session_db}).
+
%%%=========================================================================
%%% API
%%%=========================================================================
-header(Scheme, {Host, _}, Path, CookieDb) ->
- case lookup_cookies(Host, Path, CookieDb) of
- [] ->
- {"cookie", ""};
- Cookies ->
- {"cookie", cookies_to_string(Scheme, Cookies)}
+
+%%--------------------------------------------------------------------
+%% Func: open_db(DbName, DbDir, SessionDbName) -> #cookie_db{}
+%% Purpose: Create the cookie db
+%%--------------------------------------------------------------------
+
+open_db(_, only_session_cookies, SessionDbName) ->
+ ?hcrt("open (session cookies only) db",
+ [{session_db_name, SessionDbName}]),
+ SessionDb = ets:new(SessionDbName,
+ [protected, bag, {keypos, #http_cookie.domain}]),
+ #cookie_db{session_db = SessionDb};
+
+open_db(Name, Dir, SessionDbName) ->
+ ?hcrt("open db",
+ [{name, Name}, {dir, Dir}, {session_db_name, SessionDbName}]),
+ File = filename:join(Dir, atom_to_list(Name)),
+ case dets:open_file(Name, [{keypos, #http_cookie.domain},
+ {type, bag},
+ {file, File},
+ {ram_file, true}]) of
+ {ok, Db} ->
+ SessionDb = ets:new(SessionDbName,
+ [protected, bag,
+ {keypos, #http_cookie.domain}]),
+ #cookie_db{db = Db, session_db = SessionDb};
+ {error, Reason} ->
+ throw({error, {failed_open_file, Name, File, Reason}})
end.
-cookies(Headers, RequestPath, RequestHost) ->
- Cookies = parse_set_cookies(Headers, {RequestPath, RequestHost}),
- accept_cookies(Cookies, RequestPath, RequestHost).
-
-open_cookie_db({{_, only_session_cookies}, SessionDbName}) ->
- EtsDb = ets:new(SessionDbName, [protected, bag,
- {keypos, #http_cookie.domain}]),
- {undefined, EtsDb};
-
-open_cookie_db({{DbName, Dbdir}, SessionDbName}) ->
- File = filename:join(Dbdir, atom_to_list(DbName)),
- {ok, DetsDb} = dets:open_file(DbName, [{keypos, #http_cookie.domain},
- {type, bag},
- {file, File},
- {ram_file, true}]),
- EtsDb = ets:new(SessionDbName, [protected, bag,
- {keypos, #http_cookie.domain}]),
- {DetsDb, EtsDb}.
-
-close_cookie_db({undefined, EtsDb}) ->
- ets:delete(EtsDb);
-
-close_cookie_db({DetsDb, EtsDb}) ->
- dets:close(DetsDb),
- ets:delete(EtsDb).
+
+%%--------------------------------------------------------------------
+%% Func: reset_db(CookieDb) -> void()
+%% Purpose: Reset (empty) the cookie database
+%%
+%%--------------------------------------------------------------------
+
+reset_db(#cookie_db{db = undefined, session_db = SessionDb}) ->
+ ets:delete_all_objects(SessionDb),
+ ok;
+reset_db(#cookie_db{db = Db, session_db = SessionDb}) ->
+ dets:delete_all_objects(Db),
+ ets:delete_all_objects(SessionDb),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% Func: close_db(CookieDb) -> ok
+%% Purpose: Close the cookie db
+%%--------------------------------------------------------------------
+
+close_db(#cookie_db{db = Db, session_db = SessionDb}) ->
+ ?hcrt("close db", []),
+ maybe_dets_close(Db),
+ ets:delete(SessionDb),
+ ok.
+
+maybe_dets_close(undefined) ->
+ ok;
+maybe_dets_close(Db) ->
+ dets:close(Db).
+
+
+%%--------------------------------------------------------------------
+%% Func: insert(CookieDb) -> ok
+%% Purpose: Close the cookie db
+%%--------------------------------------------------------------------
%% If no persistent cookie database is defined we
%% treat all cookies as if they where session cookies.
-insert(Cookie = #http_cookie{max_age = Int},
- Dbs = {undefined, _}) when is_integer(Int) ->
- insert(Cookie#http_cookie{max_age = session}, Dbs);
-
-insert(Cookie = #http_cookie{domain = Key, name = Name,
- path = Path, max_age = session},
- Db = {_, CookieDb}) ->
- case ets:match_object(CookieDb, #http_cookie{domain = Key,
- name = Name,
- path = Path,
- _ = '_'}) of
+insert(#cookie_db{db = undefined} = CookieDb,
+ #http_cookie{max_age = Int} = Cookie) when is_integer(Int) ->
+ insert(CookieDb, Cookie#http_cookie{max_age = session});
+
+insert(#cookie_db{session_db = SessionDb} = CookieDb,
+ #http_cookie{domain = Key,
+ name = Name,
+ path = Path,
+ max_age = session} = Cookie) ->
+ ?hcrt("insert session cookie", [{cookie, Cookie}]),
+ Pattern = #http_cookie{domain = Key, name = Name, path = Path, _ = '_'},
+ case ets:match_object(SessionDb, Pattern) of
[] ->
- ets:insert(CookieDb, Cookie);
+ ets:insert(SessionDb, Cookie);
[NewCookie] ->
- delete(NewCookie, Db),
- ets:insert(CookieDb, Cookie)
+ delete(CookieDb, NewCookie),
+ ets:insert(SessionDb, Cookie)
end,
ok;
-insert(#http_cookie{domain = Key, name = Name,
- path = Path, max_age = 0},
- Db = {CookieDb, _}) ->
- case dets:match_object(CookieDb, #http_cookie{domain = Key,
- name = Name,
- path = Path,
- _ = '_'}) of
+insert(#cookie_db{db = Db} = CookieDb,
+ #http_cookie{domain = Key,
+ name = Name,
+ path = Path,
+ max_age = 0}) ->
+ ?hcrt("insert", [{domain, Key}, {name, Name}, {path, Path}]),
+ Pattern = #http_cookie{domain = Key, name = Name, path = Path, _ = '_'},
+ case dets:match_object(Db, Pattern) of
[] ->
ok;
[NewCookie] ->
- delete(NewCookie, Db)
+ delete(CookieDb, NewCookie)
end,
ok;
-insert(Cookie = #http_cookie{domain = Key, name = Name, path = Path},
- Db = {CookieDb, _}) ->
- case dets:match_object(CookieDb, #http_cookie{domain = Key,
- name = Name,
- path = Path,
- _ = '_'}) of
+insert(#cookie_db{db = Db} = CookieDb,
+ #http_cookie{domain = Key, name = Name, path = Path} = Cookie) ->
+ ?hcrt("insert", [{cookie, Cookie}]),
+ Pattern = #http_cookie{domain = Key,
+ name = Name,
+ path = Path,
+ _ = '_'},
+ case dets:match_object(Db, Pattern) of
[] ->
- dets:insert(CookieDb, Cookie);
- [NewCookie] ->
- delete(NewCookie, Db),
- dets:insert(CookieDb, Cookie)
+ dets:insert(Db, Cookie);
+ [OldCookie] ->
+ delete(CookieDb, OldCookie),
+ dets:insert(Db, Cookie)
end,
ok.
+
+
+%%--------------------------------------------------------------------
+%% Func: header(CookieDb) -> ok
+%% Purpose: Cookies
+%%--------------------------------------------------------------------
+
+header(CookieDb, Scheme, {Host, _}, Path) ->
+ ?hcrd("header", [{scheme, Scheme}, {host, Host}, {path, Path}]),
+ case lookup_cookies(CookieDb, Host, Path) of
+ [] ->
+ {"cookie", ""};
+ Cookies ->
+ {"cookie", cookies_to_string(Scheme, Cookies)}
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Func: cookies(Headers, RequestPath, RequestHost) -> [cookie()]
+%% Purpose: Which cookies are stored
+%%--------------------------------------------------------------------
+
+cookies(Headers, RequestPath, RequestHost) ->
+ ?hcrt("cookies", [{headers, Headers},
+ {request_path, RequestPath},
+ {request_host, RequestHost}]),
+ Cookies = parse_set_cookies(Headers, {RequestPath, RequestHost}),
+ accept_cookies(Cookies, RequestPath, RequestHost).
+
+
+%%--------------------------------------------------------------------
+%% Func: which_cookies(CookieDb) -> [cookie()]
+%% Purpose: For test and debug purpose,
+%% dump the entire cookie database
+%%--------------------------------------------------------------------
+
+which_cookies(#cookie_db{db = undefined, session_db = SessionDb}) ->
+ SessionCookies = ets:tab2list(SessionDb),
+ [{session_cookies, SessionCookies}];
+which_cookies(#cookie_db{db = Db, session_db = SessionDb}) ->
+ Cookies = dets:match_object(Db, '_'),
+ SessionCookies = ets:tab2list(SessionDb),
+ [{cookies, Cookies}, {session_cookies, SessionCookies}].
+
+
%%%========================================================================
%%% Internal functions
%%%========================================================================
-lookup_cookies(Key, {undefined, Ets}) ->
- ets:match_object(Ets, #http_cookie{domain = Key,
- _ = '_'});
-lookup_cookies(Key, {Dets,Ets}) ->
- SessionCookies = ets:match_object(Ets, #http_cookie{domain = Key,
- _ = '_'}),
- Cookies = dets:match_object(Dets, #http_cookie{domain = Key,
- _ = '_'}),
+
+delete(#cookie_db{session_db = SessionDb},
+ #http_cookie{max_age = session} = Cookie) ->
+ ets:delete_object(SessionDb, Cookie);
+delete(#cookie_db{db = Db}, Cookie) ->
+ dets:delete_object(Db, Cookie).
+
+
+lookup_cookies(#cookie_db{db = undefined, session_db = SessionDb}, Key) ->
+ Pattern = #http_cookie{domain = Key, _ = '_'},
+ Cookies = ets:match_object(SessionDb, Pattern),
+ ?hcrt("lookup cookies", [{cookies, Cookies}]),
+ Cookies;
+
+lookup_cookies(#cookie_db{db = Db, session_db = SessionDb}, Key) ->
+ Pattern = #http_cookie{domain = Key, _ = '_'},
+ SessionCookies = ets:match_object(SessionDb, Pattern),
+ ?hcrt("lookup cookies", [{session_cookies, SessionCookies}]),
+ Cookies = dets:match_object(Db, Pattern),
+ ?hcrt("lookup cookies", [{cookies, Cookies}]),
Cookies ++ SessionCookies.
-delete(Cookie = #http_cookie{max_age = session}, {_, CookieDb}) ->
- ets:delete_object(CookieDb, Cookie);
-delete(Cookie, {CookieDb, _}) ->
- dets:delete_object(CookieDb, Cookie).
-lookup_cookies(Host, Path, Db) ->
+lookup_cookies(CookieDb, Host, Path) ->
Cookies =
case http_util:is_hostname(Host) of
true ->
- HostCookies = lookup_cookies(Host, Db),
+ HostCookies = lookup_cookies(CookieDb, Host),
[_| DomainParts] = string:tokens(Host, "."),
- lookup_domain_cookies(DomainParts, Db, HostCookies);
+ lookup_domain_cookies(CookieDb, DomainParts, HostCookies);
false -> % IP-adress
- lookup_cookies(Host, Db)
+ lookup_cookies(CookieDb, Host)
end,
- ValidCookies = valid_cookies(Cookies, [], Db),
+ ValidCookies = valid_cookies(CookieDb, Cookies),
lists:filter(fun(Cookie) ->
lists:prefix(Cookie#http_cookie.path, Path)
end, ValidCookies).
%% For instance if Host=localhost
-lookup_domain_cookies([], _, AccCookies) ->
+lookup_domain_cookies(_CookieDb, [], AccCookies) ->
lists:flatten(AccCookies);
+
%% Top domains can not have cookies
-lookup_domain_cookies([_], _, AccCookies) ->
+lookup_domain_cookies(_CookieDb, [_], AccCookies) ->
lists:flatten(AccCookies);
-lookup_domain_cookies([Next | DomainParts], CookieDb, AccCookies) ->
+
+lookup_domain_cookies(CookieDb, [Next | DomainParts], AccCookies) ->
Domain = merge_domain_parts(DomainParts, [Next ++ "."]),
- lookup_domain_cookies(DomainParts, CookieDb,
- [lookup_cookies(Domain, CookieDb)
- | AccCookies]).
+ lookup_domain_cookies(CookieDb, DomainParts,
+ [lookup_cookies(CookieDb, Domain) | AccCookies]).
merge_domain_parts([Part], Merged) ->
lists:flatten(["." | lists:reverse([Part | Merged])]);
merge_domain_parts([Part| Rest], Merged) ->
merge_domain_parts(Rest, [".", Part | Merged]).
-cookies_to_string(Scheme, Cookies = [Cookie | _]) ->
+cookies_to_string(Scheme, [Cookie | _] = Cookies) ->
Version = "$Version=" ++ Cookie#http_cookie.version ++ "; ",
cookies_to_string(Scheme, path_sort(Cookies), [Version]).
@@ -170,7 +266,7 @@ cookies_to_string(_, [], CookieStrs) ->
lists:flatten(lists:reverse(CookieStrs))
end;
-cookies_to_string(https, [Cookie = #http_cookie{secure = true}| Cookies],
+cookies_to_string(https, [#http_cookie{secure = true} = Cookie| Cookies],
CookieStrs) ->
Str = case Cookies of
[] ->
@@ -193,7 +289,7 @@ cookies_to_string(Scheme, [Cookie | Cookies], CookieStrs) ->
end,
cookies_to_string(Scheme, Cookies, [Str | CookieStrs]).
-cookie_to_string(Cookie = #http_cookie{name = Name, value = Value}) ->
+cookie_to_string(#http_cookie{name = Name, value = Value} = Cookie) ->
Str = Name ++ "=" ++ Value,
add_domain(add_path(Str, Cookie), Cookie).
@@ -208,19 +304,19 @@ add_domain(Str, #http_cookie{domain = Domain}) ->
Str ++ "; $Domain=" ++ Domain.
parse_set_cookies(OtherHeaders, DefaultPathDomain) ->
- SetCookieHeaders = lists:foldl(fun({"set-cookie", Value}, Acc) ->
- [string:tokens(Value, ",")| Acc];
- (_, Acc) ->
- Acc
- end, [], OtherHeaders),
+ SetCookieHeaders =
+ lists:foldl(fun({"set-cookie", Value}, Acc) ->
+ [string:tokens(Value, ",")| Acc];
+ (_, Acc) ->
+ Acc
+ end, [], OtherHeaders),
- lists:flatten(lists:map(fun(CookieHeader) ->
- NewHeader =
- fix_netscape_cookie(CookieHeader,
- []),
- parse_set_cookie(NewHeader, [],
- DefaultPathDomain) end,
- SetCookieHeaders)).
+ lists:flatten(
+ lists:map(fun(CookieHeader) ->
+ NewHeader = fix_netscape_cookie(CookieHeader, []),
+ parse_set_cookie(NewHeader, [], DefaultPathDomain)
+ end,
+ SetCookieHeaders)).
parse_set_cookie([], AccCookies, _) ->
AccCookies;
@@ -282,16 +378,16 @@ cookie_attributes([{"expires", Value}| Attributes], Cookie) ->
Time = http_util:convert_netscapecookie_date(Value),
ExpireTime = calendar:datetime_to_gregorian_seconds(Time),
cookie_attributes(Attributes,
- Cookie#http_cookie{max_age = ExpireTime});
+ Cookie#http_cookie{max_age = ExpireTime});
cookie_attributes([{"path", Value}| Attributes], Cookie) ->
cookie_attributes(Attributes,
- Cookie#http_cookie{path = Value});
+ Cookie#http_cookie{path = Value});
cookie_attributes([{"secure", _}| Attributes], Cookie) ->
cookie_attributes(Attributes,
- Cookie#http_cookie{secure = true});
+ Cookie#http_cookie{secure = true});
cookie_attributes([{"version", Value}| Attributes], Cookie) ->
cookie_attributes(Attributes,
- Cookie#http_cookie{version = Value});
+ Cookie#http_cookie{version = Value});
%% Disregard unknown attributes.
cookie_attributes([_| Attributes], Cookie) ->
cookie_attributes(Attributes, Cookie).
@@ -302,8 +398,7 @@ domain_default(Cookie = #http_cookie{domain = undefined},
domain_default(Cookie, _) ->
Cookie.
-path_default(Cookie = #http_cookie{path = undefined},
- DefaultPath) ->
+path_default(#http_cookie{path = undefined} = Cookie, DefaultPath) ->
Cookie#http_cookie{path = skip_right_most_slash(DefaultPath),
path_default = true};
path_default(Cookie, _) ->
@@ -321,7 +416,10 @@ accept_cookies(Cookies, RequestPath, RequestHost) ->
end, Cookies).
accept_cookie(Cookie, RequestPath, RequestHost) ->
- accept_path(Cookie, RequestPath) and accept_domain(Cookie, RequestHost).
+ Accepted =
+ accept_path(Cookie, RequestPath) andalso
+ accept_domain(Cookie, RequestHost),
+ Accepted.
accept_path(#http_cookie{path = Path}, RequestPath) ->
lists:prefix(Path, RequestPath).
@@ -330,18 +428,20 @@ accept_domain(#http_cookie{domain = RequestHost}, RequestHost) ->
true;
accept_domain(#http_cookie{domain = Domain}, RequestHost) ->
- HostCheck = case http_util:is_hostname(RequestHost) of
- true ->
- (lists:suffix(Domain, RequestHost) andalso
- (not
- lists:member($.,
- string:substr(RequestHost, 1,
- (length(RequestHost) -
- length(Domain))))));
- false ->
- false
- end,
- HostCheck andalso (hd(Domain) == $.)
+ HostCheck =
+ case http_util:is_hostname(RequestHost) of
+ true ->
+ (lists:suffix(Domain, RequestHost) andalso
+ (not
+ lists:member($.,
+ string:substr(RequestHost, 1,
+ (length(RequestHost) -
+ length(Domain))))));
+ false ->
+ false
+ end,
+ HostCheck
+ andalso (hd(Domain) =:= $.)
andalso (length(string:tokens(Domain, ".")) > 1).
cookie_expires(0) ->
@@ -356,16 +456,20 @@ is_cookie_expired(#http_cookie{max_age = ExpireTime}) ->
NowSec = calendar:datetime_to_gregorian_seconds({date(), time()}),
ExpireTime - NowSec =< 0.
-valid_cookies([], Valid, _) ->
+
+valid_cookies(Db, Cookies) ->
+ valid_cookies(Db, Cookies, []).
+
+valid_cookies(_Db, [], Valid) ->
Valid;
-valid_cookies([Cookie | Cookies], Valid, Db) ->
+valid_cookies(Db, [Cookie | Cookies], Valid) ->
case is_cookie_expired(Cookie) of
true ->
- delete(Cookie, Db),
- valid_cookies(Cookies, Valid, Db);
+ delete(Db, Cookie),
+ valid_cookies(Db, Cookies, Valid);
false ->
- valid_cookies(Cookies, [Cookie | Valid], Db)
+ valid_cookies(Db, Cookies, [Cookie | Valid])
end.
path_sort(Cookies)->
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 7b737c2f86..fec74932a2 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -28,7 +28,15 @@
%%--------------------------------------------------------------------
%% Internal Application API
--export([start_link/3, send/2, cancel/2, stream/3, stream_next/1]).
+-export([
+ start_link/2,
+ connect_and_send/2,
+ send/2,
+ cancel/2,
+ stream/3,
+ stream_next/1,
+ info/1
+ ]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -50,7 +58,7 @@
mfa, % {Moduel, Function, Args}
pipeline = queue:new(), % queue()
keep_alive = queue:new(), % queue()
- status = new, % new | pipeline | keep_alive | close | ssl_tunnel
+ status, % undefined | new | pipeline | keep_alive | close | ssl_tunnel
canceled = [], % [RequestId]
max_header_size = nolimit, % nolimit | integer()
max_body_size = nolimit, % nolimit | integer()
@@ -85,9 +93,13 @@
%% the reply or part of it has arrived.)
%%--------------------------------------------------------------------
%%--------------------------------------------------------------------
-start_link(Request, Options, ProfileName) ->
- {ok, proc_lib:spawn_link(?MODULE, init, [[Request, Options,
- ProfileName]])}.
+
+start_link(Options, ProfileName) ->
+ Args = [Options, ProfileName],
+ gen_server:start_link(?MODULE, Args, []).
+
+connect_and_send(Request, HandlerPid) ->
+ call({connect_and_send, Request}, HandlerPid).
%%--------------------------------------------------------------------
@@ -126,6 +138,18 @@ stream_next(Pid) ->
%%--------------------------------------------------------------------
+%% Function: info(Pid) -> [{Key, Val}]
+%% Pid = pid() - the pid of the http-request handler process.
+%%
+%% Description:
+%% Returns various information related to this handler
+%% Used for debugging and testing
+%%--------------------------------------------------------------------
+info(Pid) ->
+ call(info, Pid).
+
+
+%%--------------------------------------------------------------------
%% Function: stream(BodyPart, Request, Code) -> _
%% BodyPart = binary()
%% Request = #request{}
@@ -138,21 +162,21 @@ stream_next(Pid) ->
%%--------------------------------------------------------------------
%% Request should not be streamed
stream(BodyPart, Request = #request{stream = none}, _) ->
- ?hcrt("stream - none", [{body_part, BodyPart}]),
+ ?hcrt("stream - none", []),
{BodyPart, Request};
%% Stream to caller
stream(BodyPart, Request = #request{stream = Self}, Code)
when ((Code =:= 200) orelse (Code =:= 206)) andalso
((Self =:= self) orelse (Self =:= {self, once})) ->
- ?hcrt("stream - self", [{stream, Self}, {code, Code}, {body_part, BodyPart}]),
+ ?hcrt("stream - self", [{stream, Self}, {code, Code}]),
httpc_response:send(Request#request.from,
{Request#request.id, stream, BodyPart}),
{<<>>, Request};
stream(BodyPart, Request = #request{stream = Self}, 404)
when (Self =:= self) orelse (Self =:= {self, once}) ->
- ?hcrt("stream - self with 404", [{stream, Self}, {body_part, BodyPart}]),
+ ?hcrt("stream - self with 404", [{stream, Self}]),
httpc_response:send(Request#request.from,
{Request#request.id, stream, BodyPart}),
{<<>>, Request};
@@ -162,7 +186,7 @@ stream(BodyPart, Request = #request{stream = Self}, 404)
%% We keep this for backward compatibillity...
stream(BodyPart, Request = #request{stream = Filename}, Code)
when ((Code =:= 200) orelse (Code =:= 206)) andalso is_list(Filename) ->
- ?hcrt("stream - filename", [{stream, Filename}, {code, Code}, {body_part, BodyPart}]),
+ ?hcrt("stream - filename", [{stream, Filename}, {code, Code}]),
case file:open(Filename, [write, raw, append, delayed_write]) of
{ok, Fd} ->
?hcrt("stream - file open ok", [{fd, Fd}]),
@@ -174,7 +198,7 @@ stream(BodyPart, Request = #request{stream = Filename}, Code)
%% Stream to file
stream(BodyPart, Request = #request{stream = Fd}, Code)
when ((Code =:= 200) orelse (Code =:= 206)) ->
- ?hcrt("stream to file", [{stream, Fd}, {code, Code}, {body_part, BodyPart}]),
+ ?hcrt("stream to file", [{stream, Fd}, {code, Code}]),
case file:write(Fd, BodyPart) of
ok ->
{<<>>, Request};
@@ -183,7 +207,7 @@ stream(BodyPart, Request = #request{stream = Fd}, Code)
end;
stream(BodyPart, Request,_) -> % only 200 and 206 responses can be streamed
- ?hcrt("stream - ignore", [{request, Request}, {body_part, BodyPart}]),
+ ?hcrt("stream - ignore", [{request, Request}]),
{BodyPart, Request}.
@@ -192,10 +216,9 @@ stream(BodyPart, Request,_) -> % only 200 and 206 responses can be streamed
%%====================================================================
%%--------------------------------------------------------------------
-%% Function: init([Request, Options, ProfileName]) -> {ok, State} |
-%% {ok, State, Timeout} | ignore |{stop, Reason}
+%% Function: init([Options, ProfileName]) -> {ok, State} |
+%% {ok, State, Timeout} | ignore | {stop, Reason}
%%
-%% Request = #request{}
%% Options = #options{}
%% ProfileName = atom() - id of httpc manager process
%%
@@ -206,30 +229,16 @@ stream(BodyPart, Request,_) -> % only 200 and 206 responses can be streamed
%% but we do not want that so errors will be handled by the process
%% sending an init_error message to itself.
%%--------------------------------------------------------------------
-init([Request, Options, ProfileName]) ->
+init([Options, ProfileName]) ->
+ ?hcrv("init - starting", [{options, Options}, {profile, ProfileName}]),
process_flag(trap_exit, true),
-
handle_verbose(Options#options.verbose),
- Address = handle_proxy(Request#request.address, Options#options.proxy),
- {ok, State} =
- case {Address /= Request#request.address, Request#request.scheme} of
- {true, https} ->
- Error = https_through_proxy_is_not_currently_supported,
- self() ! {init_error,
- Error, httpc_response:error(Request, Error)},
- {ok, #state{request = Request, options = Options,
- status = ssl_tunnel}};
- %% This is what we should do if and when ssl supports
- %% "socket upgrading"
- %%send_ssl_tunnel_request(Address, Request,
- %% #state{options = Options,
- %% status = ssl_tunnel});
- {_, _} ->
- send_first_request(Address, Request,
- #state{options = Options,
- profile_name = ProfileName})
- end,
- gen_server:enter_loop(?MODULE, [], State).
+ State = #state{status = undefined,
+ options = Options,
+ profile_name = ProfileName},
+ ?hcrd("init - started", []),
+ {ok, State}.
+
%%--------------------------------------------------------------------
%% Function: handle_call(Request, From, State) -> {reply, Reply, State} |
@@ -240,39 +249,85 @@ init([Request, Options, ProfileName]) ->
%% {stop, Reason, State} (terminate/2 is called)
%% Description: Handling call messages
%%--------------------------------------------------------------------
-handle_call(Request, _, State = #state{session = Session =
- #tcp_session{socket = Socket,
- type = pipeline},
- timers = Timers,
- options = Options,
- profile_name = ProfileName}) ->
- Address = handle_proxy(Request#request.address, Options#options.proxy),
+
+
+%% This is the first request, the reason the proc was started
+handle_call({connect_and_send, #request{address = Address0,
+ scheme = Scheme} = Request},
+ _From,
+ #state{options = #options{proxy = Proxy},
+ status = undefined,
+ session = undefined} = State) ->
+ ?hcrv("connect and send", [{address0, Address0}, {proxy, Proxy}]),
+ Address = handle_proxy(Address0, Proxy),
+ if
+ ((Address =/= Address0) andalso (Scheme =:= https)) ->
+ %% This is what we should do if and when ssl supports
+ %% "socket upgrading"
+ %%send_ssl_tunnel_request(Address, Request,
+ %% #state{options = Options,
+ %% status = ssl_tunnel});
+ Reason = https_through_proxy_is_not_currently_supported,
+ Error = {error, Reason},
+ {stop, Error, Error, State};
+ true ->
+ case connect_and_send_first_request(Address, Request, State) of
+ {ok, NewState} ->
+ {reply, ok, NewState};
+ {stop, Error, NewState} ->
+ {stop, Error, Error, NewState}
+ end
+ end;
+
+handle_call(#request{address = Addr} = Request, _,
+ #state{status = Status,
+ session = #tcp_session{socket = Socket,
+ type = pipeline} = Session,
+ timers = Timers,
+ options = #options{proxy = Proxy} = _Options,
+ profile_name = ProfileName} = State)
+ when Status =/= undefined ->
+
+ ?hcrv("new request on a pipeline session",
+ [{request, Request},
+ {profile, ProfileName},
+ {status, Status},
+ {timers, Timers}]),
+
+ Address = handle_proxy(Addr, Proxy),
case httpc_request:send(Address, Request, Socket) of
ok ->
+
+ ?hcrd("request sent", []),
+
%% Activate the request time out for the new request
- NewState = activate_request_timeout(State#state{request =
- Request}),
+ NewState =
+ activate_request_timeout(State#state{request = Request}),
+
+ ClientClose =
+ httpc_request:is_client_closing(Request#request.headers),
- ClientClose = httpc_request:is_client_closing(
- Request#request.headers),
case State#state.request of
- #request{} -> %% Old request no yet finished
+ #request{} -> %% Old request not yet finished
+ ?hcrd("old request still not finished", []),
%% Make sure to use the new value of timers in state
- NewTimers = NewState#state.timers,
+ NewTimers = NewState#state.timers,
NewPipeline = queue:in(Request, State#state.pipeline),
- NewSession =
+ NewSession =
Session#tcp_session{queue_length =
%% Queue + current
queue:len(NewPipeline) + 1,
client_close = ClientClose},
httpc_manager:insert_session(NewSession, ProfileName),
+ ?hcrd("session updated", []),
{reply, ok, State#state{pipeline = NewPipeline,
- session = NewSession,
- timers = NewTimers}};
+ session = NewSession,
+ timers = NewTimers}};
undefined ->
- %% Note: tcp-message reciving has already been
+ %% Note: tcp-message receiving has already been
%% activated by handle_pipeline/2.
+ ?hcrd("no current request", []),
cancel_timer(Timers#timers.queue_timer,
timeout_queue),
NewSession =
@@ -281,54 +336,67 @@ handle_call(Request, _, State = #state{session = Session =
httpc_manager:insert_session(NewSession, ProfileName),
Relaxed =
(Request#request.settings)#http_options.relaxed,
- {reply, ok,
- NewState#state{request = Request,
- session = NewSession,
- mfa = {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]},
- timers =
- Timers#timers{queue_timer =
- undefined}}}
+ MFA = {httpc_response, parse,
+ [State#state.max_header_size, Relaxed]},
+ NewTimers = Timers#timers{queue_timer = undefined},
+ ?hcrd("session created", []),
+ {reply, ok, NewState#state{request = Request,
+ session = NewSession,
+ mfa = MFA,
+ timers = NewTimers}}
end;
{error, Reason} ->
+ ?hcri("failed sending request", [{reason, Reason}]),
{reply, {pipeline_failed, Reason}, State}
end;
-handle_call(Request, _, #state{session = Session =
- #tcp_session{type = keep_alive,
- socket = Socket},
- timers = Timers,
- options = Options,
- profile_name = ProfileName} = State) ->
-
- ClientClose = httpc_request:is_client_closing(Request#request.headers),
+handle_call(#request{address = Addr} = Request, _,
+ #state{status = Status,
+ session = #tcp_session{socket = Socket,
+ type = keep_alive} = Session,
+ timers = Timers,
+ options = #options{proxy = Proxy} = _Options,
+ profile_name = ProfileName} = State)
+ when Status =/= undefined ->
- Address = handle_proxy(Request#request.address,
- Options#options.proxy),
+ ?hcrv("new request on a keep-alive session",
+ [{request, Request},
+ {profile, ProfileName},
+ {status, Status}]),
+
+ Address = handle_proxy(Addr, Proxy),
case httpc_request:send(Address, Request, Socket) of
ok ->
+
+ ?hcrd("request sent", []),
+
+ %% Activate the request time out for the new request
NewState =
- activate_request_timeout(State#state{request =
- Request}),
+ activate_request_timeout(State#state{request = Request}),
+
+ ClientClose =
+ httpc_request:is_client_closing(Request#request.headers),
case State#state.request of
#request{} -> %% Old request not yet finished
%% Make sure to use the new value of timers in state
- NewTimers = NewState#state.timers,
+ ?hcrd("old request still not finished", []),
+ NewTimers = NewState#state.timers,
NewKeepAlive = queue:in(Request, State#state.keep_alive),
- NewSession =
+ NewSession =
Session#tcp_session{queue_length =
%% Queue + current
queue:len(NewKeepAlive) + 1,
client_close = ClientClose},
httpc_manager:insert_session(NewSession, ProfileName),
+ ?hcrd("session updated", []),
{reply, ok, State#state{keep_alive = NewKeepAlive,
- session = NewSession,
- timers = NewTimers}};
+ session = NewSession,
+ timers = NewTimers}};
undefined ->
%% Note: tcp-message reciving has already been
%% activated by handle_pipeline/2.
+ ?hcrd("no current request", []),
cancel_timer(Timers#timers.queue_timer,
timeout_queue),
NewSession =
@@ -337,16 +405,23 @@ handle_call(Request, _, #state{session = Session =
httpc_manager:insert_session(NewSession, ProfileName),
Relaxed =
(Request#request.settings)#http_options.relaxed,
- {reply, ok,
- NewState#state{request = Request,
- session = NewSession,
- mfa = {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]}}}
+ MFA = {httpc_response, parse,
+ [State#state.max_header_size, Relaxed]},
+ {reply, ok, NewState#state{request = Request,
+ session = NewSession,
+ mfa = MFA}}
end;
- {error, Reason} ->
+
+ {error, Reason} ->
+ ?hcri("failed sending request", [{reason, Reason}]),
{reply, {request_failed, Reason}, State}
- end.
+ end;
+
+
+handle_call(info, _, State) ->
+ Info = handler_info(State),
+ {reply, Info, State}.
+
%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
@@ -367,19 +442,30 @@ handle_call(Request, _, #state{session = Session =
%% handle_keep_alive_queue/2 on the other hand will just skip the
%% request as if it was never issued as in this case the request will
%% not have been sent.
-handle_cast({cancel, RequestId}, State = #state{request = Request =
- #request{id = RequestId},
- profile_name = ProfileName}) ->
+handle_cast({cancel, RequestId},
+ #state{request = #request{id = RequestId} = Request,
+ profile_name = ProfileName,
+ canceled = Canceled} = State) ->
+ ?hcrv("cancel current request", [{request_id, RequestId},
+ {profile, ProfileName},
+ {canceled, Canceled}]),
httpc_manager:request_canceled(RequestId, ProfileName),
+ ?hcrv("canceled", []),
{stop, normal,
- State#state{canceled = [RequestId | State#state.canceled],
- request = Request#request{from = answer_sent}}};
-handle_cast({cancel, RequestId}, State = #state{profile_name = ProfileName}) ->
+ State#state{canceled = [RequestId | Canceled],
+ request = Request#request{from = answer_sent}}};
+handle_cast({cancel, RequestId},
+ #state{profile_name = ProfileName,
+ canceled = Canceled} = State) ->
+ ?hcrv("cancel", [{request_id, RequestId},
+ {profile, ProfileName},
+ {canceled, Canceled}]),
httpc_manager:request_canceled(RequestId, ProfileName),
- {noreply, State#state{canceled = [RequestId | State#state.canceled]}};
+ ?hcrv("canceled", []),
+ {noreply, State#state{canceled = [RequestId | Canceled]}};
+
handle_cast(stream_next, #state{session = Session} = State) ->
- http_transport:setopts(socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket, [{active, once}]),
+ activate_once(Session),
{noreply, State#state{once = once}}.
@@ -390,7 +476,7 @@ handle_cast(stream_next, #state{session = Session} = State) ->
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info({Proto, _Socket, Data},
- #state{mfa = {Module, Function, Args} = MFA,
+ #state{mfa = {Module, Function, Args},
request = #request{method = Method,
stream = Stream} = Request,
session = Session,
@@ -399,64 +485,68 @@ handle_info({Proto, _Socket, Data},
(Proto =:= ssl) orelse
(Proto =:= httpc_handler) ->
- ?hcri("received data", [{proto, Proto}, {data, Data}, {mfa, MFA}, {method, Method}, {stream, Stream}, {session, Session}, {status_line, StatusLine}]),
+ ?hcri("received data", [{proto, Proto},
+ {module, Module},
+ {function, Function},
+ {method, Method},
+ {stream, Stream},
+ {session, Session},
+ {status_line, StatusLine}]),
FinalResult =
try Module:Function([Data | Args]) of
{ok, Result} ->
- ?hcrd("data processed - ok", [{result, Result}]),
+ ?hcrd("data processed - ok", []),
handle_http_msg(Result, State);
{_, whole_body, _} when Method =:= head ->
?hcrd("data processed - whole body", []),
handle_response(State#state{body = <<>>});
{Module, whole_body, [Body, Length]} ->
- ?hcrd("data processed - whole body", [{module, Module}, {body, Body}, {length, Length}]),
+ ?hcrd("data processed - whole body", [{length, Length}]),
{_, Code, _} = StatusLine,
{NewBody, NewRequest} = stream(Body, Request, Code),
%% When we stream we will not keep the already
%% streamed data, that would be a waste of memory.
- NewLength = case Stream of
- none ->
- Length;
- _ ->
- Length - size(Body)
- end,
+ NewLength =
+ case Stream of
+ none ->
+ Length;
+ _ ->
+ Length - size(Body)
+ end,
NewState = next_body_chunk(State),
-
- {noreply, NewState#state{mfa = {Module, whole_body,
- [NewBody, NewLength]},
+ NewMFA = {Module, whole_body, [NewBody, NewLength]},
+ {noreply, NewState#state{mfa = NewMFA,
request = NewRequest}};
NewMFA ->
- ?hcrd("data processed", [{new_mfa, NewMFA}]),
- http_transport:setopts(socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket,
- [{active, once}]),
+ ?hcrd("data processed - new mfa", []),
+ activate_once(Session),
{noreply, State#state{mfa = NewMFA}}
catch
- exit:_ ->
- ClientErrMsg = httpc_response:error(Request,
- {could_not_parse_as_http,
- Data}),
- NewState = answer_request(Request, ClientErrMsg, State),
+ exit:_Exit ->
+ ?hcrd("data processing exit", [{exit, _Exit}]),
+ ClientReason = {could_not_parse_as_http, Data},
+ ClientErrMsg = httpc_response:error(Request, ClientReason),
+ NewState = answer_request(Request, ClientErrMsg, State),
{stop, normal, NewState};
- error:_ ->
- ClientErrMsg = httpc_response:error(Request,
- {could_not_parse_as_http,
- Data}),
- NewState = answer_request(Request, ClientErrMsg, State),
+ error:_Error ->
+ ?hcrd("data processing error", [{error, _Error}]),
+ ClientReason = {could_not_parse_as_http, Data},
+ ClientErrMsg = httpc_response:error(Request, ClientReason),
+ NewState = answer_request(Request, ClientErrMsg, State),
{stop, normal, NewState}
end,
- ?hcri("data processed", [{result, FinalResult}]),
+ ?hcri("data processed", []),
FinalResult;
handle_info({Proto, Socket, Data},
- #state{mfa = MFA,
- request = Request,
- session = Session,
- status = Status,
+ #state{mfa = MFA,
+ request = Request,
+ session = Session,
+ status = Status,
status_line = StatusLine,
profile_name = Profile} = State)
when (Proto =:= tcp) orelse
@@ -474,6 +564,7 @@ handle_info({Proto, Socket, Data},
"~n",
[Proto, Socket, Data, MFA,
Request, Session, Status, StatusLine, Profile]),
+
{noreply, State};
@@ -513,28 +604,35 @@ handle_info({ssl_error, _, _} = Reason, State) ->
handle_info({timeout, RequestId},
#state{request = #request{id = RequestId} = Request,
canceled = Canceled} = State) ->
+ ?hcri("timeout of current request", [{id, RequestId}]),
httpc_response:send(Request#request.from,
- httpc_response:error(Request,timeout)),
+ httpc_response:error(Request, timeout)),
+ ?hcrv("response (timeout) sent - now terminate", []),
{stop, normal,
State#state{request = Request#request{from = answer_sent},
canceled = [RequestId | Canceled]}};
handle_info({timeout, RequestId}, #state{canceled = Canceled} = State) ->
+ ?hcri("timeout", [{id, RequestId}]),
Filter =
fun(#request{id = Id, from = From} = Request) when Id =:= RequestId ->
+ ?hcrv("found request", [{id, Id}, {from, From}]),
%% Notify the owner
Response = httpc_response:error(Request, timeout),
httpc_response:send(From, Response),
+ ?hcrv("response (timeout) sent", []),
[Request#request{from = answer_sent}];
(_) ->
true
end,
case State#state.status of
pipeline ->
+ ?hcrd("pipeline", []),
Pipeline = queue:filter(Filter, State#state.pipeline),
{noreply, State#state{canceled = [RequestId | Canceled],
pipeline = Pipeline}};
keep_alive ->
+ ?hcrd("keep_alive", []),
KeepAlive = queue:filter(Filter, State#state.keep_alive),
{noreply, State#state{canceled = [RequestId | Canceled],
keep_alive = KeepAlive}}
@@ -577,9 +675,10 @@ terminate(normal, #state{session = undefined}) ->
%% Init error sending, no session information has been setup but
%% there is a socket that needs closing.
-terminate(normal, #state{request = Request,
- session = #tcp_session{id = undefined,
- socket = Socket}}) ->
+terminate(normal,
+ #state{request = Request,
+ session = #tcp_session{id = undefined,
+ socket = Socket}}) ->
http_transport:close(socket_type(Request), Socket);
%% Socket closed remotely
@@ -590,6 +689,9 @@ terminate(normal,
request = Request,
timers = Timers,
pipeline = Pipeline}) ->
+ ?hcrt("terminate(normal) - remote close",
+ [{id, Id}, {profile, ProfileName}]),
+
%% Clobber session
(catch httpc_manager:delete_session(Id, ProfileName)),
@@ -605,23 +707,28 @@ terminate(normal,
%% And, just in case, close our side (**really** overkill)
http_transport:close(socket_type(Request), Socket);
-terminate(_, State = #state{session = Session,
- request = undefined,
- profile_name = ProfileName,
- timers = Timers,
- pipeline = Pipeline,
- keep_alive = KeepAlive}) ->
- catch httpc_manager:delete_session(Session#tcp_session.id,
- ProfileName),
+terminate(_, #state{session = #tcp_session{id = Id,
+ socket = Socket,
+ scheme = Scheme},
+ request = undefined,
+ profile_name = ProfileName,
+ timers = Timers,
+ pipeline = Pipeline,
+ keep_alive = KeepAlive} = State) ->
+ (catch httpc_manager:delete_session(Id, ProfileName)),
maybe_retry_queue(Pipeline, State),
maybe_retry_queue(KeepAlive, State),
cancel_timer(Timers#timers.queue_timer, timeout_queue),
- Socket = Session#tcp_session.socket,
- http_transport:close(socket_type(Session#tcp_session.scheme), Socket);
+ http_transport:close(socket_type(Scheme), Socket);
+
+terminate(Reason, #state{request = undefined}) ->
+ ?hcrt("terminate", [{reason, Reason}]),
+ ok;
-terminate(Reason, State = #state{request = Request}) ->
+terminate(Reason, #state{request = Request} = State) ->
+ ?hcrd("terminate", [{reason, Reason}, {request, Request}]),
NewState = maybe_send_answer(Request,
httpc_response:error(Request, Reason),
State),
@@ -641,13 +748,16 @@ maybe_send_answer(Request, Answer, State) ->
answer_request(Request, Answer, State).
deliver_answers([]) ->
+ ?hcrd("deliver answer done", []),
ok;
-deliver_answers([#request{from = From} = Request | Requests])
+deliver_answers([#request{id = Id, from = From} = Request | Requests])
when is_pid(From) ->
Response = httpc_response:error(Request, socket_closed_remotely),
+ ?hcrd("deliver answer", [{id, Id}, {from, From}, {response, Response}]),
httpc_response:send(From, Response),
deliver_answers(Requests);
-deliver_answers([_|Requests]) ->
+deliver_answers([Request|Requests]) ->
+ ?hcrd("skip deliver answer", [{request, Request}]),
deliver_answers(Requests).
@@ -691,19 +801,22 @@ new_queue(Queue, Fun) ->
end, List),
queue:from_list(NewList).
-%%--------------------------------------------------------------------
+
+%%%--------------------------------------------------------------------
%%% Internal functions
-%%--------------------------------------------------------------------
+%%%--------------------------------------------------------------------
-connect(SocketType, ToAddress, #options{ipfamily = IpFamily,
- ip = FromAddress,
- port = FromPort}, Timeout) ->
+connect(SocketType, ToAddress,
+ #options{ipfamily = IpFamily,
+ ip = FromAddress,
+ port = FromPort,
+ socket_opts = Opts0}, Timeout) ->
Opts1 =
case FromPort of
default ->
- [];
+ Opts0;
_ ->
- [{port, FromPort}]
+ [{port, FromPort} | Opts0]
end,
Opts2 =
case FromAddress of
@@ -728,101 +841,157 @@ connect(SocketType, ToAddress, #options{ipfamily = IpFamily,
http_transport:connect(SocketType, ToAddress, Opts3, Timeout)
end.
-
-send_first_request(Address, Request, #state{options = Options} = State) ->
- SocketType = socket_type(Request),
- ConnTimeout = (Request#request.settings)#http_options.connect_timeout,
- ?hcri("connect",
+connect_and_send_first_request(Address,
+ #request{settings = Settings,
+ headers = Headers,
+ address = OrigAddress,
+ scheme = Scheme} = Request,
+ #state{options = Options} = State) ->
+
+ ?hcrd("connect",
[{address, Address}, {request, Request}, {options, Options}]),
+
+ SocketType = socket_type(Request),
+ ConnTimeout = Settings#http_options.connect_timeout,
case connect(SocketType, Address, Options, ConnTimeout) of
{ok, Socket} ->
- ?hcri("connected - now send first request", [{socket, Socket}]),
+ ?hcrd("connected - now send first request", [{socket, Socket}]),
case httpc_request:send(Address, Request, Socket) of
ok ->
- ?hcri("first request sent", []),
+ ?hcrd("first request sent", []),
ClientClose =
- httpc_request:is_client_closing(
- Request#request.headers),
+ httpc_request:is_client_closing(Headers),
SessionType = httpc_manager:session_type(Options),
Session =
- #tcp_session{id = {Request#request.address, self()},
- scheme = Request#request.scheme,
- socket = Socket,
+ #tcp_session{id = {OrigAddress, self()},
+ scheme = Scheme,
+ socket = Socket,
client_close = ClientClose,
- type = SessionType},
- TmpState = State#state{request = Request,
- session = Session,
- mfa = init_mfa(Request, State),
- status_line =
- init_status_line(Request),
- headers = undefined,
- body = undefined,
- status = new},
- http_transport:setopts(SocketType,
- Socket, [{active, once}]),
+ type = SessionType},
+ TmpState =
+ State#state{request = Request,
+ session = Session,
+ mfa = init_mfa(Request, State),
+ status_line = init_status_line(Request),
+ headers = undefined,
+ body = undefined,
+ status = new},
+ ?hcrt("activate socket", []),
+ activate_once(Session),
NewState = activate_request_timeout(TmpState),
{ok, NewState};
- {error, Reason} ->
- %% Commented out in wait of ssl support to avoid
- %% dialyzer warning
- %%case State#state.status of
- %% new -> % Called from init/1
- self() ! {init_error, error_sending,
- httpc_response:error(Request, Reason)},
- {ok, State#state{request = Request,
- session =
- #tcp_session{socket = Socket}}}
- %%ssl_tunnel -> % Not called from init/1
- %% NewState =
- %% answer_request(Request,
- %%httpc_response:error(Request,
- %%Reason),
- %% State),
- %% {stop, normal, NewState}
- %% end
+ {error, Reason} ->
+ ?hcrv("failed sending request", [{reason, Reason}]),
+ Error = {error, {send_failed,
+ httpc_response:error(Request, Reason)}},
+ {stop, Error, State#state{request = Request}}
end;
- {error, Reason} ->
- %% Commented out in wait of ssl support to avoid
- %% dialyzer warning
- %% case State#state.status of
- %% new -> % Called from init/1
- self() ! {init_error, error_connecting,
- httpc_response:error(Request, Reason)},
- {ok, State#state{request = Request}}
- %% ssl_tunnel -> % Not called from init/1
- %% NewState =
- %% answer_request(Request,
- %% httpc_response:error(Request,
- %% Reason),
- %% State),
- %% {stop, normal, NewState}
- %%end
+ {error, Reason} ->
+ ?hcri("connect failed", [{reason, Reason}]),
+ Error = {error, {connect_failed,
+ httpc_response:error(Request, Reason)}},
+ {stop, Error, State#state{request = Request}}
end.
+
+handler_info(#state{request = Request,
+ session = Session,
+ status_line = _StatusLine,
+ pipeline = Pipeline,
+ keep_alive = KeepAlive,
+ status = Status,
+ canceled = _Canceled,
+ options = _Options,
+ timers = _Timers} = _State) ->
+
+ ?hcrt("handler info", [{request, Request},
+ {session, Session},
+ {pipeline, Pipeline},
+ {keep_alive, KeepAlive},
+ {status, Status}]),
+
+ %% Info about the current request
+ RequestInfo =
+ case Request of
+ undefined ->
+ [];
+ #request{id = Id,
+ started = ReqStarted} ->
+ [{id, Id}, {started, ReqStarted}]
+ end,
+
+ ?hcrt("handler info", [{request_info, RequestInfo}]),
+
+ %% Info about the current session/socket
+ SessionType = Session#tcp_session.type,
+ QueueLen = case Session#tcp_session.type of
+ pipeline ->
+ queue:len(Pipeline);
+ keep_alive ->
+ queue:len(KeepAlive)
+ end,
+ Socket = Session#tcp_session.socket,
+ Scheme = Session#tcp_session.scheme,
+ SocketType = socket_type(Scheme),
+
+ ?hcrt("handler info", [{session_type, SessionType},
+ {queue_length, QueueLen},
+ {scheme, Scheme},
+ {socket_type, SocketType},
+ {socket, Socket}]),
+
+ SocketOpts = http_transport:getopts(SocketType, Socket),
+ SocketStats = http_transport:getstat(SocketType, Socket),
+
+ Remote = http_transport:peername(SocketType, Socket),
+ Local = http_transport:sockname(SocketType, Socket),
+
+ ?hcrt("handler info", [{remote, Remote},
+ {local, Local},
+ {socket_opts, SocketOpts},
+ {socket_stats, SocketStats}]),
+
+ SocketInfo = [{remote, Remote},
+ {local, Local},
+ {socket_opts, SocketOpts},
+ {socket_stats, SocketStats}],
+
+ SessionInfo =
+ [{type, SessionType},
+ {queue_length, QueueLen},
+ {scheme, Scheme},
+ {socket_info, SocketInfo}],
+
+ [{status, Status},
+ {current_request, RequestInfo},
+ {session, SessionInfo}].
+
+
+
handle_http_msg({Version, StatusCode, ReasonPharse, Headers, Body},
State = #state{request = Request}) ->
- ?hcrt("handle_http_msg", [{body, Body}]),
+ ?hcrt("handle_http_msg", [{headers, Headers}]),
case Headers#http_response_h.'content-type' of
"multipart/byteranges" ++ _Param ->
- exit(not_yet_implemented);
+ exit({not_yet_implemented, multypart_byteranges});
_ ->
- StatusLine = {Version, StatusCode, ReasonPharse},
+ StatusLine = {Version, StatusCode, ReasonPharse},
{ok, NewRequest} = start_stream(StatusLine, Headers, Request),
handle_http_body(Body,
State#state{request = NewRequest,
status_line = StatusLine,
headers = Headers})
end;
-handle_http_msg({ChunkedHeaders, Body},
- State = #state{headers = Headers}) ->
- ?hcrt("handle_http_msg", [{chunked_headers, ChunkedHeaders}, {body, Body}]),
+handle_http_msg({ChunkedHeaders, Body}, #state{headers = Headers} = State) ->
+ ?hcrt("handle_http_msg",
+ [{chunked_headers, ChunkedHeaders}, {headers, Headers}]),
NewHeaders = http_chunk:handle_headers(Headers, ChunkedHeaders),
handle_response(State#state{headers = NewHeaders, body = Body});
-handle_http_msg(Body, State = #state{status_line = {_,Code, _}}) ->
- ?hcrt("handle_http_msg", [{body, Body}, {code, Code}]),
- {NewBody, NewRequest}= stream(Body, State#state.request, Code),
+handle_http_msg(Body, #state{status_line = {_,Code, _}} = State) ->
+ ?hcrt("handle_http_msg", [{code, Code}]),
+ {NewBody, NewRequest} = stream(Body, State#state.request, Code),
handle_response(State#state{body = NewBody, request = NewRequest}).
handle_http_body(<<>>, State = #state{status_line = {_,304, _}}) ->
@@ -837,11 +1006,12 @@ handle_http_body(<<>>, State = #state{request = #request{method = head}}) ->
?hcrt("handle_http_body - head", []),
handle_response(State#state{body = <<>>});
-handle_http_body(Body, State = #state{headers = Headers,
- max_body_size = MaxBodySize,
- status_line = {_,Code, _},
- request = Request}) ->
- ?hcrt("handle_http_body", [{body, Body}, {max_body_size, MaxBodySize}, {code, Code}]),
+handle_http_body(Body, #state{headers = Headers,
+ max_body_size = MaxBodySize,
+ status_line = {_,Code, _},
+ request = Request} = State) ->
+ ?hcrt("handle_http_body",
+ [{max_body_size, MaxBodySize}, {headers, Headers}, {code, Code}]),
TransferEnc = Headers#http_response_h.'transfer-encoding',
case case_insensitive_header(TransferEnc) of
"chunked" ->
@@ -850,12 +1020,17 @@ handle_http_body(Body, State = #state{headers = Headers,
State#state.max_header_size,
{Code, Request}) of
{Module, Function, Args} ->
- ?hcrt("handle_http_body - new mfa", [{module, Module}, {function, Function}, {args, Args}]),
+ ?hcrt("handle_http_body - new mfa",
+ [{module, Module},
+ {function, Function},
+ {args, Args}]),
NewState = next_body_chunk(State),
{noreply, NewState#state{mfa =
{Module, Function, Args}}};
{ok, {ChunkedHeaders, NewBody}} ->
- ?hcrt("handle_http_body - nyew body", [{chunked_headers, ChunkedHeaders}, {new_body, NewBody}]),
+ ?hcrt("handle_http_body - new body",
+ [{chunked_headers, ChunkedHeaders},
+ {new_body, NewBody}]),
NewHeaders = http_chunk:handle_headers(Headers,
ChunkedHeaders),
handle_response(State#state{headers = NewHeaders,
@@ -872,12 +1047,13 @@ handle_http_body(Body, State = #state{headers = Headers,
?hcrt("handle_http_body - other", []),
Length =
list_to_integer(Headers#http_response_h.'content-length'),
- case ((Length =< MaxBodySize) or (MaxBodySize == nolimit)) of
+ case ((Length =< MaxBodySize) orelse (MaxBodySize =:= nolimit)) of
true ->
case httpc_response:whole_body(Body, Length) of
{ok, Body} ->
- {NewBody, NewRequest}= stream(Body, Request, Code),
- handle_response(State#state{body = NewBody,
+ {NewBody, NewRequest} =
+ stream(Body, Request, Code),
+ handle_response(State#state{body = NewBody,
request = NewRequest});
MFA ->
NewState = next_body_chunk(State),
@@ -893,90 +1069,79 @@ handle_http_body(Body, State = #state{headers = Headers,
end
end.
-%%% Normaly I do not comment out code, I throw it away. But this might
-%%% actually be used on day if ssl is improved.
-%% handle_response(State = #state{status = ssl_tunnel,
-%% request = Request,
-%% options = Options,
-%% session = #tcp_session{socket = Socket,
-%% scheme = Scheme},
-%% status_line = {_, 200, _}}) ->
-%% %%% Insert code for upgrading the socket if and when ssl supports this.
-%% Address = handle_proxy(Request#request.address, Options#options.proxy),
-%% send_first_request(Address, Request, State);
-%% handle_response(State = #state{status = ssl_tunnel,
-%% request = Request}) ->
-%% NewState = answer_request(Request,
-%% httpc_response:error(Request,
-%% ssl_proxy_tunnel_failed),
-%% State),
-%% {stop, normal, NewState};
-
-handle_response(State = #state{status = new}) ->
- handle_response(try_to_enable_pipeline_or_keep_alive(State));
-
-handle_response(State =
- #state{request = Request,
+handle_response(#state{status = new} = State) ->
+ ?hcrd("handle response - status = new", []),
+ handle_response(try_to_enable_pipeline_or_keep_alive(State));
+
+handle_response(#state{request = Request,
status = Status,
session = Session,
status_line = StatusLine,
headers = Headers,
body = Body,
options = Options,
- profile_name = ProfileName}) when Status =/= new ->
- ?hcrt("handle response", [{status, Status}, {session, Session}, {status_line, StatusLine}, {profile_name, ProfileName}]),
+ profile_name = ProfileName} = State)
+ when Status =/= new ->
+
+ ?hcrd("handle response", [{profile, ProfileName},
+ {status, Status},
+ {request, Request},
+ {session, Session},
+ {status_line, StatusLine}]),
+
handle_cookies(Headers, Request, Options, ProfileName),
case httpc_response:result({StatusLine, Headers, Body}, Request) of
%% 100-continue
continue ->
+ ?hcrd("handle response - continue", []),
%% Send request body
{_, RequestBody} = Request#request.content,
http_transport:send(socket_type(Session#tcp_session.scheme),
Session#tcp_session.socket,
RequestBody),
%% Wait for next response
- http_transport:setopts(socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket,
- [{active, once}]),
+ activate_once(Session),
Relaxed = (Request#request.settings)#http_options.relaxed,
- {noreply,
- State#state{mfa = {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]},
- status_line = undefined,
- headers = undefined,
- body = undefined
- }};
+ MFA = {httpc_response, parse,
+ [State#state.max_header_size, Relaxed]},
+ {noreply, State#state{mfa = MFA,
+ status_line = undefined,
+ headers = undefined,
+ body = undefined}};
+
%% Ignore unexpected 100-continue response and receive the
%% actual response that the server will send right away.
{ignore, Data} ->
+ ?hcrd("handle response - ignore", [{data, Data}]),
Relaxed = (Request#request.settings)#http_options.relaxed,
- NewState = State#state{mfa =
- {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]},
+ MFA = {httpc_response, parse,
+ [State#state.max_header_size, Relaxed]},
+ NewState = State#state{mfa = MFA,
status_line = undefined,
- headers = undefined,
- body = undefined},
+ headers = undefined,
+ body = undefined},
handle_info({httpc_handler, dummy, Data}, NewState);
+
%% On a redirect or retry the current request becomes
%% obsolete and the manager will create a new request
%% with the same id as the current.
{redirect, NewRequest, Data} ->
- ?hcrt("handle response - redirect", [{new_request, NewRequest}, {data, Data}]),
+ ?hcrt("handle response - redirect",
+ [{new_request, NewRequest}, {data, Data}]),
ok = httpc_manager:redirect_request(NewRequest, ProfileName),
handle_queue(State#state{request = undefined}, Data);
{retry, TimeNewRequest, Data} ->
- ?hcrt("handle response - retry", [{time_new_request, TimeNewRequest}, {data, Data}]),
+ ?hcrt("handle response - retry",
+ [{time_new_request, TimeNewRequest}, {data, Data}]),
ok = httpc_manager:retry_request(TimeNewRequest, ProfileName),
handle_queue(State#state{request = undefined}, Data);
{ok, Msg, Data} ->
- ?hcrt("handle response - result ok", [{msg, Msg}, {data, Data}]),
+ ?hcrd("handle response - ok", []),
end_stream(StatusLine, Request),
NewState = answer_request(Request, Msg, State),
handle_queue(NewState, Data);
{stop, Msg} ->
- ?hcrt("handle response - result stop", [{msg, Msg}]),
+ ?hcrd("handle response - stop", [{msg, Msg}]),
end_stream(StatusLine, Request),
NewState = answer_request(Request, Msg, State),
{stop, normal, NewState}
@@ -990,60 +1155,67 @@ handle_cookies(_,_, #options{cookies = verify}, _) ->
ok;
handle_cookies(Headers, Request, #options{cookies = enabled}, ProfileName) ->
{Host, _ } = Request#request.address,
- Cookies = http_cookie:cookies(Headers#http_response_h.other,
+ Cookies = httpc_cookie:cookies(Headers#http_response_h.other,
Request#request.path, Host),
httpc_manager:store_cookies(Cookies, Request#request.address,
ProfileName).
%% This request could not be pipelined or used as sequential keept alive
%% queue
-handle_queue(State = #state{status = close}, _) ->
+handle_queue(#state{status = close} = State, _) ->
{stop, normal, State};
-handle_queue(State = #state{status = keep_alive}, Data) ->
+handle_queue(#state{status = keep_alive} = State, Data) ->
handle_keep_alive_queue(State, Data);
-handle_queue(State = #state{status = pipeline}, Data) ->
+handle_queue(#state{status = pipeline} = State, Data) ->
handle_pipeline(State, Data).
-handle_pipeline(State =
- #state{status = pipeline, session = Session,
+handle_pipeline(#state{status = pipeline,
+ session = Session,
profile_name = ProfileName,
- options = #options{pipeline_timeout = TimeOut}},
- Data) ->
+ options = #options{pipeline_timeout = TimeOut}} =
+ State,
+ Data) ->
+
+ ?hcrd("handle pipeline", [{profile, ProfileName},
+ {session, Session},
+ {timeout, TimeOut}]),
+
case queue:out(State#state.pipeline) of
{empty, _} ->
+ ?hcrd("epmty pipeline queue", []),
+
%% The server may choose too teminate an idle pipeline
%% in this case we want to receive the close message
%% at once and not when trying to pipeline the next
%% request.
- http_transport:setopts(socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket,
- [{active, once}]),
+ activate_once(Session),
+
%% If a pipeline that has been idle for some time is not
%% closed by the server, the client may want to close it.
- NewState = activate_queue_timeout(TimeOut, State),
+ NewState = activate_queue_timeout(TimeOut, State),
NewSession = Session#tcp_session{queue_length = 0},
httpc_manager:insert_session(NewSession, ProfileName),
%% Note mfa will be initilized when a new request
%% arrives.
{noreply,
- NewState#state{request = undefined,
- mfa = undefined,
+ NewState#state{request = undefined,
+ mfa = undefined,
status_line = undefined,
- headers = undefined,
- body = undefined
- }
- };
+ headers = undefined,
+ body = undefined}};
{{value, NextRequest}, Pipeline} ->
case lists:member(NextRequest#request.id,
State#state.canceled) of
true ->
+ ?hcrv("next request had been cancelled", []),
%% See comment for handle_cast({cancel, RequestId})
{stop, normal,
State#state{request =
NextRequest#request{from = answer_sent}}};
false ->
+ ?hcrv("next request", [{request, NextRequest}]),
NewSession =
Session#tcp_session{queue_length =
%% Queue + current
@@ -1051,21 +1223,19 @@ handle_pipeline(State =
httpc_manager:insert_session(NewSession, ProfileName),
Relaxed =
(NextRequest#request.settings)#http_options.relaxed,
+ MFA = {httpc_response,
+ parse,
+ [State#state.max_header_size, Relaxed]},
NewState =
- State#state{pipeline = Pipeline,
- request = NextRequest,
- mfa = {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]},
+ State#state{pipeline = Pipeline,
+ request = NextRequest,
+ mfa = MFA,
status_line = undefined,
- headers = undefined,
- body = undefined},
+ headers = undefined,
+ body = undefined},
case Data of
<<>> ->
- http_transport:setopts(
- socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket,
- [{active, once}]),
+ activate_once(Session),
{noreply, NewState};
_ ->
%% If we already received some bytes of
@@ -1076,22 +1246,25 @@ handle_pipeline(State =
end
end.
-handle_keep_alive_queue(State = #state{status = keep_alive,
- session = Session,
- profile_name = ProfileName,
- options = #options{keep_alive_timeout
- = TimeOut}
- },
- Data) ->
+handle_keep_alive_queue(
+ #state{status = keep_alive,
+ session = Session,
+ profile_name = ProfileName,
+ options = #options{keep_alive_timeout = TimeOut}} = State,
+ Data) ->
+
+ ?hcrd("handle keep_alive", [{profile, ProfileName},
+ {session, Session},
+ {timeout, TimeOut}]),
+
case queue:out(State#state.keep_alive) of
{empty, _} ->
+ ?hcrd("empty keep_alive queue", []),
%% The server may choose too terminate an idle keep_alive session
%% in this case we want to receive the close message
%% at once and not when trying to send the next
%% request.
- http_transport:setopts(socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket,
- [{active, once}]),
+ activate_once(Session),
%% If a keep_alive session has been idle for some time is not
%% closed by the server, the client may want to close it.
NewState = activate_queue_timeout(TimeOut, State),
@@ -1111,25 +1284,25 @@ handle_keep_alive_queue(State = #state{status = keep_alive,
case lists:member(NextRequest#request.id,
State#state.canceled) of
true ->
- handle_keep_alive_queue(State#state{keep_alive =
- KeepAlive}, Data);
+ ?hcrv("next request has already been canceled", []),
+ handle_keep_alive_queue(
+ State#state{keep_alive = KeepAlive}, Data);
false ->
+ ?hcrv("next request", [{request, NextRequest}]),
Relaxed =
(NextRequest#request.settings)#http_options.relaxed,
+ MFA = {httpc_response, parse,
+ [State#state.max_header_size, Relaxed]},
NewState =
- State#state{request = NextRequest,
- keep_alive = KeepAlive,
- mfa = {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]},
+ State#state{request = NextRequest,
+ keep_alive = KeepAlive,
+ mfa = MFA,
status_line = undefined,
- headers = undefined,
- body = undefined},
+ headers = undefined,
+ body = undefined},
case Data of
<<>> ->
- http_transport:setopts(
- socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket, [{active, once}]),
+ activate_once(Session),
{noreply, NewState};
_ ->
%% If we already received some bytes of
@@ -1140,11 +1313,6 @@ handle_keep_alive_queue(State = #state{status = keep_alive,
end
end.
-call(Msg, Pid, Timeout) ->
- gen_server:call(Pid, Msg, Timeout).
-
-cast(Msg, Pid) ->
- gen_server:cast(Pid, Msg).
case_insensitive_header(Str) when is_list(Str) ->
http_util:to_lower(Str);
@@ -1152,20 +1320,34 @@ case_insensitive_header(Str) when is_list(Str) ->
case_insensitive_header(Str) ->
Str.
-activate_request_timeout(State = #state{request = Request}) ->
- Time = (Request#request.settings)#http_options.timeout,
- case Time of
+activate_once(#tcp_session{scheme = Scheme, socket = Socket}) ->
+ SocketType = socket_type(Scheme),
+ http_transport:setopts(SocketType, Socket, [{active, once}]).
+
+activate_request_timeout(
+ #state{request = #request{timer = undefined} = Request} = State) ->
+ Timeout = (Request#request.settings)#http_options.timeout,
+ case Timeout of
infinity ->
State;
_ ->
- Ref = erlang:send_after(Time, self(),
- {timeout, Request#request.id}),
- State#state
- {timers =
- #timers{request_timers =
- [{Request#request.id, Ref}|
- (State#state.timers)#timers.request_timers]}}
- end.
+ ReqId = Request#request.id,
+ ?hcrt("activate request timer",
+ [{request_id, ReqId},
+ {time_consumed, t() - Request#request.started},
+ {timeout, Timeout}]),
+ Msg = {timeout, ReqId},
+ Ref = erlang:send_after(Timeout, self(), Msg),
+ Request2 = Request#request{timer = Ref},
+ ReqTimers = [{Request#request.id, Ref} |
+ (State#state.timers)#timers.request_timers],
+ Timers = #timers{request_timers = ReqTimers},
+ State#state{request = Request2, timers = Timers}
+ end;
+
+%% Timer is already running! This is the case for a redirect or retry
+activate_request_timeout(State) ->
+ State.
activate_queue_timeout(infinity, State) ->
State;
@@ -1187,18 +1369,21 @@ is_keep_alive_enabled_server("HTTP/1.0",
is_keep_alive_enabled_server(_,_) ->
false.
-is_keep_alive_connection(Headers, Session) ->
- (not ((Session#tcp_session.client_close) or
- httpc_response:is_server_closing(Headers))).
-
-try_to_enable_pipeline_or_keep_alive(State =
- #state{session = Session,
- request = #request{method = Method},
- status_line = {Version, _, _},
- headers = Headers,
- profile_name = ProfileName}) ->
- case (is_keep_alive_enabled_server(Version, Headers) andalso
- is_keep_alive_connection(Headers, Session)) of
+is_keep_alive_connection(Headers, #tcp_session{client_close = ClientClose}) ->
+ (not ((ClientClose) orelse httpc_response:is_server_closing(Headers))).
+
+try_to_enable_pipeline_or_keep_alive(
+ #state{session = Session,
+ request = #request{method = Method},
+ status_line = {Version, _, _},
+ headers = Headers,
+ profile_name = ProfileName} = State) ->
+ ?hcrd("try to enable pipeline or keep-alive",
+ [{version, Version},
+ {headers, Headers},
+ {session, Session}]),
+ case is_keep_alive_enabled_server(Version, Headers) andalso
+ is_keep_alive_connection(Headers, Session) of
true ->
case (is_pipeline_enabled_client(Session) andalso
httpc_request:is_idempotent(Method)) of
@@ -1209,15 +1394,16 @@ try_to_enable_pipeline_or_keep_alive(State =
httpc_manager:insert_session(Session, ProfileName),
%% Make sure type is keep_alive in session
%% as it in this case might be pipeline
- State#state{status = keep_alive,
- session =
- Session#tcp_session{type = keep_alive}}
+ NewSession = Session#tcp_session{type = keep_alive},
+ State#state{status = keep_alive,
+ session = NewSession}
end;
false ->
State#state{status = close}
end.
-answer_request(Request, Msg, #state{timers = Timers} = State) ->
+answer_request(Request, Msg, #state{timers = Timers} = State) ->
+ ?hcrt("answer request", [{request, Request}]),
httpc_response:send(Request#request.from, Msg),
RequestTimers = Timers#timers.request_timers,
TimerRef =
@@ -1253,14 +1439,14 @@ retry_pipeline([Request | PipeLine],
case (catch httpc_manager:retry_request(Request, ProfileName)) of
ok ->
RequestTimers = Timers#timers.request_timers,
+ ReqId = Request#request.id,
TimerRef =
- proplists:get_value(Request#request.id, RequestTimers,
- undefined),
- cancel_timer(TimerRef, {timeout, Request#request.id}),
- State#state{timers = Timers#timers{request_timers =
- lists:delete({Request#request.id,
- TimerRef},
- RequestTimers)}};
+ proplists:get_value(ReqId, RequestTimers, undefined),
+ cancel_timer(TimerRef, {timeout, ReqId}),
+ NewReqsTimers = lists:delete({ReqId, TimerRef}, RequestTimers),
+ NewTimers = Timers#timers{request_timers = NewReqsTimers},
+ State#state{timers = NewTimers};
+
Error ->
answer_request(Request#request.from,
httpc_response:error(Request, Error), State)
@@ -1345,12 +1531,14 @@ socket_type(#request{scheme = https, settings = Settings}) ->
socket_type(http) ->
ip_comm;
socket_type(https) ->
- {ssl, []}. %% Dummy value ok for ex setops that does not use this value
+ {ssl, []}. %% Dummy value ok for ex setopts that does not use this value
-start_stream({_Version, _Code, _ReasonPhrase}, _Headers, #request{stream = none} = Request) ->
+start_stream({_Version, _Code, _ReasonPhrase}, _Headers,
+ #request{stream = none} = Request) ->
?hcrt("start stream - none", []),
{ok, Request};
-start_stream({_Version, Code, _ReasonPhrase}, Headers, #request{stream = self} = Request)
+start_stream({_Version, Code, _ReasonPhrase}, Headers,
+ #request{stream = self} = Request)
when (Code =:= 200) orelse (Code =:= 206) ->
?hcrt("start stream - self", [{code, Code}]),
Msg = httpc_response:stream_start(Headers, Request, ignore),
@@ -1363,7 +1551,8 @@ start_stream({_Version, Code, _ReasonPhrase}, Headers,
Msg = httpc_response:stream_start(Headers, Request, self()),
httpc_response:send(Request#request.from, Msg),
{ok, Request};
-start_stream({_Version, Code, _ReasonPhrase}, _Headers, #request{stream = Filename} = Request)
+start_stream({_Version, Code, _ReasonPhrase}, _Headers,
+ #request{stream = Filename} = Request)
when ((Code =:= 200) orelse (Code =:= 206)) andalso is_list(Filename) ->
?hcrt("start stream", [{code, Code}, {filename, Filename}]),
case file:open(Filename, [write, raw, append, delayed_write]) of
@@ -1436,6 +1625,7 @@ handle_verbose(trace) ->
handle_verbose(_) ->
ok.
+
%%% Normaly I do not comment out code, I throw it away. But this might
%%% actually be used one day if ssl is improved.
%% send_ssl_tunnel_request(Address, Request = #request{address = {Host, Port}},
@@ -1497,3 +1687,21 @@ handle_verbose(_) ->
%% d(_, _, _) ->
%% ok.
+
+call(Msg, Pid) ->
+ Timeout = infinity,
+ call(Msg, Pid, Timeout).
+call(Msg, Pid, Timeout) ->
+ gen_server:call(Pid, Msg, Timeout).
+
+cast(Msg, Pid) ->
+ gen_server:cast(Pid, Msg).
+
+
+%% to(To, Start) when is_integer(Start) andalso (Start >= 0) ->
+%% http_util:timeout(To, Start);
+%% to(To, _Start) ->
+%% http_util:timeout(To, t()).
+
+t() ->
+ http_util:timestamp().
diff --git a/lib/inets/src/http_client/httpc_handler_sup.erl b/lib/inets/src/http_client/httpc_handler_sup.erl
index d9edaa0599..2a69fd15d0 100644
--- a/lib/inets/src/http_client/httpc_handler_sup.erl
+++ b/lib/inets/src/http_client/httpc_handler_sup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
%% API
-export([start_link/0]).
--export([start_child/1]).
+-export([start_child/2]).
%% Supervisor callback
-export([init/1]).
@@ -34,25 +34,28 @@
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
-start_child(Args) ->
+start_child(Options, Profile) ->
+ Args = [Options, Profile],
supervisor:start_child(?MODULE, Args).
-
+
+
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
init(Args) ->
+
RestartStrategy = simple_one_for_one,
MaxR = 0,
MaxT = 3600,
- Name = undefined, % As simple_one_for_one is used.
+ Name = undefined, % As simple_one_for_one is used.
StartFunc = {httpc_handler, start_link, Args},
- Restart = temporary, % E.g. should not be restarted
- Shutdown = 4000,
- Modules = [httpc_handler],
- Type = worker,
-
+ Restart = temporary, % E.g. should not be restarted
+ Shutdown = 4000,
+ Modules = [httpc_handler],
+ Type = worker,
ChildSpec = {Name, StartFunc, Restart, Shutdown, Type, Modules},
+
{ok, {{RestartStrategy, MaxR, MaxT}, [ChildSpec]}}.
diff --git a/lib/inets/src/http_client/httpc_internal.hrl b/lib/inets/src/http_client/httpc_internal.hrl
index ec709b9860..4d76c4beb3 100644
--- a/lib/inets/src/http_client/httpc_internal.hrl
+++ b/lib/inets/src/http_client/httpc_internal.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -46,7 +46,7 @@
%% bool() - true if auto redirect on 30x response
autoredirect = true,
- %% Ssl socket options
+ %% ssl socket options
ssl = [],
%% {User, Password} = {string(), string()}
@@ -63,41 +63,45 @@
%%% HTTP Client per profile setting.
-record(options,
{
- proxy = {undefined, []}, % {{ProxyHost, ProxyPort}, [NoProxy]},
- %% 0 means persistent connections are used without pipelining
- pipeline_timeout = ?HTTP_PIPELINE_TIMEOUT,
- max_pipeline_length = ?HTTP_PIPELINE_LENGTH,
- max_keep_alive_length = ?HTTP_KEEP_ALIVE_LENGTH,
- keep_alive_timeout = ?HTTP_KEEP_ALIVE_TIMEOUT, % Used when pipeline_timeout = 0
- max_sessions = ?HTTP_MAX_TCP_SESSIONS,
- cookies = disabled, % enabled | disabled | verify
- verbose = false,
- ipfamily = inet, % inet | inet6 | inet6fb4
- ip = default, % specify local interface
- port = default % specify local port
- }
+ proxy = {undefined, []}, % {{ProxyHost, ProxyPort}, [NoProxy]},
+ %% 0 means persistent connections are used without pipelining
+ pipeline_timeout = ?HTTP_PIPELINE_TIMEOUT,
+ max_pipeline_length = ?HTTP_PIPELINE_LENGTH,
+ max_keep_alive_length = ?HTTP_KEEP_ALIVE_LENGTH,
+ keep_alive_timeout = ?HTTP_KEEP_ALIVE_TIMEOUT, % Used when pipeline_timeout = 0
+ max_sessions = ?HTTP_MAX_TCP_SESSIONS,
+ cookies = disabled, % enabled | disabled | verify
+ verbose = false,
+ ipfamily = inet, % inet | inet6 | inet6fb4
+ ip = default, % specify local interface
+ port = default, % specify local port
+ socket_opts = [] % other socket options
+ }
).
%%% All data associated to a specific HTTP request
-record(request,
{
- id, % ref() - Request Id
- from, % pid() - Caller
- redircount = 0,% Number of redirects made for this request
- scheme, % http | https
- address, % ({Host,Port}) Destination Host and Port
- path, % string() - Path of parsed URL
- pquery, % string() - Rest of parsed URL
- method, % atom() - HTTP request Method
- headers, % #http_request_h{}
- content, % {ContentType, Body} - Current HTTP request
- settings, % #http_options{} - User defined settings
- abs_uri, % string() ex: "http://www.erlang.org"
- userinfo, % string() - optinal "<userinfo>@<host>:<port>"
- stream, % Boolean() - stream async reply?
- headers_as_is % Boolean() - workaround for servers that does
- %% not honor the http standard, can also be used for testing purposes.
- }
+ id, % ref() - Request Id
+ from, % pid() - Caller
+ redircount = 0,% Number of redirects made for this request
+ scheme, % http | https
+ address, % ({Host,Port}) Destination Host and Port
+ path, % string() - Path of parsed URL
+ pquery, % string() - Rest of parsed URL
+ method, % atom() - HTTP request Method
+ headers, % #http_request_h{}
+ content, % {ContentType, Body} - Current HTTP request
+ settings, % #http_options{} - User defined settings
+ abs_uri, % string() ex: "http://www.erlang.org"
+ userinfo, % string() - optinal "<userinfo>@<host>:<port>"
+ stream, % Boolean() - stream async reply?
+ headers_as_is, % Boolean() - workaround for servers that does
+ % not honor the http standard, can also be used for testing purposes.
+ started, % integer() > 0 - When we started processing the request
+ timer, % undefined | ref()
+ socket_opts % undefined | [socket_option()]
+ }
).
-record(tcp_session,
@@ -107,7 +111,7 @@
scheme, % http (HTTP/TCP) | https (HTTP/SSL/TCP)
socket, % Open socket, used by connection
queue_length = 1, % Current length of pipeline or keep alive queue
- type % pipeline | keep_alive (wait for response before sending new request)
+ type % pipeline | keep_alive (wait for response before sending new request)
}).
-record(http_cookie,
diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl
index 63b00c7dce..f8fc6322ed 100644
--- a/lib/inets/src/http_client/httpc_manager.erl
+++ b/lib/inets/src/http_client/httpc_manager.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -25,51 +25,85 @@
-include("http_internal.hrl").
%% Internal Application API
--export([start_link/1, start_link/2, request/2, cancel_request/2,
- request_canceled/2, retry_request/2, redirect_request/2,
- insert_session/2, delete_session/2, set_options/2, store_cookies/3,
- cookies/2, session_type/1]).
+-export([
+ start_link/3,
+ request/2,
+ cancel_request/2,
+ request_canceled/2,
+ retry_request/2,
+ redirect_request/2,
+ insert_session/2,
+ delete_session/2,
+ set_options/2,
+ store_cookies/3,
+ which_cookies/1, which_cookies/2,
+ reset_cookies/1,
+ session_type/1,
+ info/1
+ ]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
code_change/3]).
--record(state, {
+-record(state,
+ {
cancel = [], % [{RequestId, HandlerPid, ClientPid}]
- handler_db, % ets() - Entry: {Requestid, HandlerPid, ClientPid}
- cookie_db, % {ets(), dets()} - {session_cookie_db, cookie_db}
+ handler_db, % ets() - Entry: #handler_info{}
+ cookie_db, % cookie_db()
session_db, % ets() - Entry: #tcp_session{}
profile_name, % atom()
options = #options{}
}).
+-record(handler_info,
+ {
+ id, % Id of the request: request_id()
+ starter, % Pid of the handler starter process (temp): pid()
+ handler, % Pid of the handler process: pid()
+ from, % From for the request: from()
+ state % State of the handler: initiating | operational | canceled
+ }).
+
+%% Entries in the handler / request cross-ref table
+%% -record(request_info,
+%% {
+%% id, % Id of the request
+%% handler, % Pid of the handler process
+%% from, % The From value for the caller
+%% mref % Monitor ref for the caller
+%% }).
+
%%====================================================================
%% Internal Application API
%%====================================================================
%%--------------------------------------------------------------------
-%% Function: start_link({ProfileName, CookieDir}) -> {ok, Pid}
+%% Function: start_link(ProfileName, CookieDir, ManagedHow) -> {ok, Pid}
%%
%% ProfileName - httpc_manager_<Profile>
%% CookieDir - directory()
+%% ManagedHow - stand_alone | inets
%%
-%% Description: Starts the http request manger process. (Started by
-%% the intes supervisor.)
-%%--------------------------------------------------------------------
-start_link({default, CookieDir}) ->
- gen_server:start_link({local, ?MODULE}, ?MODULE,
- [?MODULE, {http_default_cookie_db, CookieDir}],
- []);
-start_link({Profile, CookieDir}) ->
- ProfileName = list_to_atom("httpc_manager_" ++ atom_to_list(Profile)),
- gen_server:start_link({local, ProfileName}, ?MODULE,
- [ProfileName,
- {http_default_cookie_db, CookieDir}], []).
-start_link({Profile, CookieDir}, stand_alone) ->
- ProfileName = list_to_atom("stand_alone_" ++ atom_to_list(Profile)),
- gen_server:start_link(?MODULE, [ProfileName,
- {http_default_cookie_db, CookieDir}],
- []).
+%% Description: Starts the http request manager process.
+%% (If ManagedHow = inets then started by the inets supervisor.)
+%%--------------------------------------------------------------------
+
+start_link(Profile, CookieDir, stand_alone) ->
+ ProfileName = httpc:profile_name("stand_alone_", Profile),
+ Args = [ProfileName, CookieDir],
+ Opts = [],
+ %% Opts = [{debug, [log, statistics]}],
+ gen_server:start_link(?MODULE, Args, Opts);
+start_link(Profile, CookieDir, _) ->
+ ProfileName = httpc:profile_name(Profile),
+ Server = {local, ProfileName},
+ Args = [ProfileName, CookieDir],
+ Opts = [],
+ %% Opts = [{debug, [log, statistics]}],
+ gen_server:start_link(Server, ?MODULE, Args, Opts).
+
+
%%--------------------------------------------------------------------
%% Function: request(Request, ProfileName) ->
%% {ok, Requestid} | {error, Reason}
@@ -78,8 +112,10 @@ start_link({Profile, CookieDir}, stand_alone) ->
%%
%% Description: Sends a request to the httpc manager process.
%%--------------------------------------------------------------------
+
request(Request, ProfileName) ->
- call(ProfileName, {request, Request}, infinity).
+ call(ProfileName, {request, Request}).
+
%%--------------------------------------------------------------------
%% Function: retry_request(Request, ProfileName) -> _
@@ -90,9 +126,11 @@ request(Request, ProfileName) ->
%% to be called by the httpc handler process if it has to terminate with
%% a non empty pipeline.
%%--------------------------------------------------------------------
+
retry_request(Request, ProfileName) ->
cast(ProfileName, {retry_or_redirect_request, Request}).
+
%%--------------------------------------------------------------------
%% Function: redirect_request(Request, ProfileName) -> _
%% Request = #request{}
@@ -102,9 +140,11 @@ retry_request(Request, ProfileName) ->
%% manager process, intended to be called by the httpc handler process
%% when the automatic redirect option is set.
%%--------------------------------------------------------------------
+
redirect_request(Request, ProfileName) ->
cast(ProfileName, {retry_or_redirect_request, Request}).
+
%%--------------------------------------------------------------------
%% Function: cancel_request(RequestId, ProfileName) -> ok
%% RequestId - ref()
@@ -112,8 +152,10 @@ redirect_request(Request, ProfileName) ->
%%
%% Description: Cancels the request with <RequestId>.
%%--------------------------------------------------------------------
+
cancel_request(RequestId, ProfileName) ->
- call(ProfileName, {cancel_request, RequestId}, infinity).
+ call(ProfileName, {cancel_request, RequestId}).
+
%%--------------------------------------------------------------------
%% Function: request_canceled(RequestId, ProfileName) -> ok
@@ -123,9 +165,11 @@ cancel_request(RequestId, ProfileName) ->
%% Description: Confirms that a request has been canceld. Intended to
%% be called by the httpc handler process.
%%--------------------------------------------------------------------
+
request_canceled(RequestId, ProfileName) ->
cast(ProfileName, {request_canceled, RequestId}).
+
%%--------------------------------------------------------------------
%% Function: insert_session(Session, ProfileName) -> _
%% Session - #tcp_session{}
@@ -135,9 +179,12 @@ request_canceled(RequestId, ProfileName) ->
%% table <ProfileName>_session_db. Intended to be called by
%% the httpc request handler process.
%%--------------------------------------------------------------------
+
insert_session(Session, ProfileName) ->
- Db = list_to_atom(atom_to_list(ProfileName) ++ "_session_db"),
- ets:insert(Db, Session).
+ SessionDbName = session_db_name(ProfileName),
+ ?hcrt("insert session", [{session, Session}, {profile, ProfileName}]),
+ ets:insert(SessionDbName, Session).
+
%%--------------------------------------------------------------------
%% Function: delete_session(SessionId, ProfileName) -> _
@@ -148,9 +195,12 @@ insert_session(Session, ProfileName) ->
%% table httpc_manager_session_db_<Profile>. Intended to be called by
%% the httpc request handler process.
%%--------------------------------------------------------------------
+
delete_session(SessionId, ProfileName) ->
- Db = list_to_atom(atom_to_list(ProfileName) ++ "_session_db"),
- ets:delete(Db, SessionId).
+ SessionDbName = session_db_name(ProfileName),
+ ?hcrt("delete session", [{session_is, SessionId}, {profile, ProfileName}]),
+ ets:delete(SessionDbName, SessionId).
+
%%--------------------------------------------------------------------
%% Function: set_options(Options, ProfileName) -> ok
@@ -166,9 +216,11 @@ delete_session(SessionId, ProfileName) ->
%%
%% Description: Sets the options to be used by the client.
%%--------------------------------------------------------------------
+
set_options(Options, ProfileName) ->
cast(ProfileName, {set_options, Options}).
+
%%--------------------------------------------------------------------
%% Function: store_cookies(Cookies, Address, ProfileName) -> ok
%%
@@ -183,8 +235,22 @@ store_cookies([], _, _) ->
store_cookies(Cookies, Address, ProfileName) ->
cast(ProfileName, {store_cookies, {Cookies, Address}}).
+
+%%--------------------------------------------------------------------
+%% Function: reset_cookies(ProfileName) -> void()
+%%
+%% Url = string()
+%% ProfileName = atom()
+%%
+%% Description: Resets the cookie database
+%%--------------------------------------------------------------------
+
+reset_cookies(ProfileName) ->
+ call(ProfileName, reset_cookies).
+
+
%%--------------------------------------------------------------------
-%% Function: cookies(Url, ProfileName) -> ok
+%% Function: which_cookies(Url, ProfileName) -> [cookie()]
%%
%% Url = string()
%% ProfileName = atom()
@@ -192,8 +258,25 @@ store_cookies(Cookies, Address, ProfileName) ->
%% Description: Retrieves the cookies that would be sent when
%% requesting <Url>.
%%--------------------------------------------------------------------
-cookies(Url, ProfileName) ->
- call(ProfileName, {cookies, Url}, infinity).
+
+which_cookies(ProfileName) ->
+ call(ProfileName, which_cookies).
+which_cookies(Url, ProfileName) ->
+ call(ProfileName, {which_cookies, Url}).
+
+
+%%--------------------------------------------------------------------
+%% Function: info(ProfileName) -> list()
+%%
+%% ProfileName = atom()
+%%
+%% Description: Retrieves various info about the manager and the
+%% handlers it manages
+%%--------------------------------------------------------------------
+
+info(ProfileName) ->
+ call(ProfileName, info).
+
%%--------------------------------------------------------------------
%% Function: session_type(Options) -> ok
@@ -202,11 +285,13 @@ cookies(Url, ProfileName) ->
%%
%% Description: Determines if to use pipelined sessions or not.
%%--------------------------------------------------------------------
+
session_type(#options{pipeline_timeout = 0}) ->
keep_alive;
session_type(_) ->
pipeline.
+
%%====================================================================
%% gen_server callback functions
%%====================================================================
@@ -216,19 +301,46 @@ session_type(_) ->
%% {ok, State, Timeout} | ignore |{stop, Reason}
%% Description: Initiates the httpc_manger process
%%--------------------------------------------------------------------
-init([ProfileName, CookiesConf | _]) ->
+init([ProfileName, CookiesDir]) ->
process_flag(trap_exit, true),
- SessionDb = list_to_atom(atom_to_list(ProfileName) ++ "_session_db"),
- ets:new(SessionDb,
+ ?hcrv("starting", [{profile, ProfileName}]),
+ case (catch do_init(ProfileName, CookiesDir)) of
+ {ok, _} = OK ->
+ ?hcrd("started", [OK]),
+ OK;
+ {error, Reason} ->
+ {stop, Reason};
+ Crap ->
+ {stop, Crap}
+ end.
+
+
+do_init(ProfileName, CookiesDir) ->
+ %% Create session db
+ ?hcrt("create session db", []),
+ SessionDbName = session_db_name(ProfileName),
+ ets:new(SessionDbName,
[public, set, named_table, {keypos, #tcp_session.id}]),
- ?hcri("starting", [{profile, ProfileName}]),
- {ok, #state{handler_db = ets:new(handler_db, [protected, set]),
- cookie_db =
- http_cookie:open_cookie_db({CookiesConf,
- http_session_cookie_db}),
- session_db = SessionDb,
- profile_name = ProfileName
- }}.
+
+ %% Create handler db
+ ?hcrt("create handler/request db", []),
+ HandlerDbName = handler_db_name(ProfileName),
+ ets:new(HandlerDbName,
+ [protected, set, named_table, {keypos, #handler_info.id}]),
+
+ %% Cookie DB
+ ?hcrt("create cookie db", []),
+ SessionCookieDbName = session_cookie_db_name(ProfileName),
+ CookieDbName = cookie_db_name(ProfileName),
+ CookieDb = httpc_cookie:open_db(CookieDbName, CookiesDir,
+ SessionCookieDbName),
+
+ State = #state{handler_db = HandlerDbName,
+ cookie_db = CookieDb,
+ session_db = SessionDbName,
+ profile_name = ProfileName},
+ {ok, State}.
+
%%--------------------------------------------------------------------
%% Function: handle_call(Request, From, State) -> {reply, Reply, State} |
@@ -239,45 +351,80 @@ init([ProfileName, CookiesConf | _]) ->
%% {stop, Reason, State} (terminate/2 is called)
%% Description: Handling call messages
%%--------------------------------------------------------------------
-handle_call({request, Request}, _, State) ->
- ?hcri("request", [{request, Request}]),
+handle_call({request, Request}, _From, State) ->
+ ?hcrv("request", [{request, Request}]),
case (catch handle_request(Request, State)) of
- {reply, Msg, NewState} ->
- {reply, Msg, NewState};
+ {ok, ReqId, NewState} ->
+ {reply, {ok, ReqId}, NewState};
+
Error ->
- {stop, Error, httpc_response:error(Request, Error), State}
+ NewError = {error, {failed_process_request, Error}},
+ {reply, NewError, State}
end;
-handle_call({cancel_request, RequestId}, From, State) ->
- ?hcri("cancel_request", [{request_id, RequestId}]),
+handle_call({cancel_request, RequestId}, From,
+ #state{handler_db = HandlerDb} = State) ->
+ ?hcrv("cancel_request", [{request_id, RequestId}]),
case ets:lookup(State#state.handler_db, RequestId) of
[] ->
- ok, %% Nothing to cancel
- {reply, ok, State};
- [{_, Pid, _}] ->
+ ?hcrd("nothing to cancel", []),
+ Reply = ok, %% Nothing to cancel
+ {reply, Reply, State};
+
+ [#handler_info{handler = Pid}] when is_pid(Pid) ->
+ ?hcrd("found operational handler for this request",
+ [{handler, Pid}]),
httpc_handler:cancel(RequestId, Pid),
{noreply, State#state{cancel =
- [{RequestId, Pid, From} |
+ [{RequestId, Pid, From} |
+ State#state.cancel]}};
+
+ [#handler_info{starter = Pid, state = HandlerState}]
+ when is_pid(Pid) ->
+ ?hcri("found *initiating* handler for this request",
+ [{starter, Pid}, {state, HandlerState}]),
+ ets:update_element(HandlerDb, RequestId,
+ {#handler_info.state, canceled}),
+ {noreply, State#state{cancel =
+ [{RequestId, Pid, From} |
State#state.cancel]}}
+
end;
-handle_call({cookies, Url}, _, State) ->
+handle_call(reset_cookies, _, #state{cookie_db = CookieDb} = State) ->
+ ?hcrv("reset cookies", []),
+ httpc_cookie:reset_db(CookieDb),
+ {reply, ok, State};
+
+handle_call(which_cookies, _, #state{cookie_db = CookieDb} = State) ->
+ ?hcrv("which cookies", []),
+ CookieHeaders = httpc_cookie:which_cookies(CookieDb),
+ {reply, CookieHeaders, State};
+
+handle_call({which_cookies, Url}, _, #state{cookie_db = CookieDb} = State) ->
+ ?hcrv("which cookies", [{url, Url}]),
case http_uri:parse(Url) of
{Scheme, _, Host, Port, Path, _} ->
CookieHeaders =
- http_cookie:header(Scheme, {Host, Port},
- Path, State#state.cookie_db),
+ httpc_cookie:header(CookieDb, Scheme, {Host, Port}, Path),
{reply, CookieHeaders, State};
Msg ->
{reply, Msg, State}
end;
-handle_call(Msg, From, State) ->
- Report = io_lib:format("HTTPC_MANAGER recived unkown call: ~p"
- "from: ~p~n", [Msg, From]),
- error_logger:error_report(Report),
+handle_call(info, _, State) ->
+ ?hcrv("info", []),
+ Info = get_manager_info(State),
+ {reply, Info, State};
+
+handle_call(Req, From, #state{profile_name = ProfileName} = State) ->
+ error_report(ProfileName,
+ "received unkown request"
+ "~n Req: ~p"
+ "~n From: ~p", [Req, From]),
{reply, {error, 'API_violation'}, State}.
+
%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
@@ -286,29 +433,61 @@ handle_call(Msg, From, State) ->
%%--------------------------------------------------------------------
handle_cast({retry_or_redirect_request, {Time, Request}},
#state{profile_name = ProfileName} = State) ->
- {ok, _} = timer:apply_after(Time, ?MODULE, retry_request, [Request, ProfileName]),
- {noreply, State};
+ ?hcrv("retry or redirect request", [{time, Time}, {request, Request}]),
+ case timer:apply_after(Time, ?MODULE, retry_request,
+ [Request, ProfileName]) of
+ {ok, _} ->
+ {noreply, State};
+ {error, Reason} ->
+ error_report(ProfileName,
+ "failed scheduling retry/redirect request"
+ "~n Time: ~p"
+ "~n Request: ~p"
+ "~n Reason: ~p", [Time, Request, Reason]),
+ {noreply, State}
+ end;
-handle_cast({retry_or_redirect_request, Request}, State) ->
+handle_cast({retry_or_redirect_request, Request},
+ #state{profile_name = Profile,
+ handler_db = HandlerDb} = State) ->
+ ?hcrv("retry or redirect request", [{request, Request}]),
case (catch handle_request(Request, State)) of
- {reply, {ok, _}, NewState} ->
+ {ok, _, NewState} ->
{noreply, NewState};
+
Error ->
- httpc_response:error(Request, Error),
- {stop, Error, State}
+ ReqId = Request#request.id,
+ error_report(Profile,
+ "failed to retry or redirect request ~p"
+ "~n Error: ~p", [ReqId, Error]),
+ case ets:lookup(HandlerDb, ReqId) of
+ [#handler_info{from = From}] ->
+ Error2 = httpc_response:error(Request, Error),
+ httpc_response:send(From, Error2),
+ ok;
+
+ _ ->
+ ok
+ end,
+ {noreply, State}
end;
handle_cast({request_canceled, RequestId}, State) ->
+ ?hcrv("request canceled", [{request_id, RequestId}]),
ets:delete(State#state.handler_db, RequestId),
case lists:keysearch(RequestId, 1, State#state.cancel) of
{value, Entry = {RequestId, _, From}} ->
+ ?hcrt("found in cancel", [{from, From}]),
gen_server:reply(From, ok),
{noreply,
State#state{cancel = lists:delete(Entry, State#state.cancel)}};
- _ ->
+ Else ->
+ ?hcrt("not found in cancel", [{else, Else}]),
{noreply, State}
end;
+
handle_cast({set_options, Options}, State = #state{options = OldOptions}) ->
+ ?hcrv("set options", [{options, Options}, {old_options, OldOptions}]),
NewOptions =
#options{proxy = get_proxy(Options, OldOptions),
pipeline_timeout = get_pipeline_timeout(Options, OldOptions),
@@ -320,7 +499,8 @@ handle_cast({set_options, Options}, State = #state{options = OldOptions}) ->
ipfamily = get_ipfamily(Options, OldOptions),
ip = get_ip(Options, OldOptions),
port = get_port(Options, OldOptions),
- verbose = get_verbose(Options, OldOptions)
+ verbose = get_verbose(Options, OldOptions),
+ socket_opts = get_socket_opts(Options, OldOptions)
},
case {OldOptions#options.verbose, NewOptions#options.verbose} of
{Same, Same} ->
@@ -345,10 +525,10 @@ handle_cast({store_cookies, {Cookies, _}}, State) ->
ok = do_store_cookies(Cookies, State),
{noreply, State};
-handle_cast(Msg, State) ->
- Report = io_lib:format("HTTPC_MANAGER recived unkown cast: ~p",
- [Msg]),
- error_logger:error_report(Report),
+handle_cast(Msg, #state{profile_name = ProfileName} = State) ->
+ error_report(ProfileName,
+ "recived unknown message"
+ "~n Msg: ~p", [Msg]),
{noreply, State}.
@@ -359,17 +539,32 @@ handle_cast(Msg, State) ->
%% {stop, Reason, State} (terminate/2 is called)
%% Description: Handling all non call/cast messages
%%---------------------------------------------------------
-handle_info({'EXIT', _, _}, State) ->
- %% Handled in DOWN
+handle_info({connect_and_send, StarterPid, ReqId, HandlerPid, Res}, State) ->
+ handle_connect_and_send(StarterPid, ReqId, HandlerPid, Res, State),
+ {noreply, State};
+
+handle_info({failed_starting_handler, StarterPid, ReqId, Res}, State) ->
+ handle_failed_starting_handler(StarterPid, ReqId, Res, State),
+ {noreply, State};
+
+handle_info({'EXIT', Pid, Reason}, #state{handler_db = HandlerDb} = State) ->
+ maybe_handle_terminating_starter(Pid, Reason, HandlerDb),
{noreply, State};
+
handle_info({'DOWN', _, _, Pid, _}, State) ->
- ets:match_delete(State#state.handler_db, {'_', Pid, '_'}),
+
+ %%
+ %% Check what happens to waiting requests! Chall we not send a reply?
+ %%
+
+ Pattern = #handler_info{handler = Pid, _ = '_'},
+ ets:match_delete(State#state.handler_db, Pattern),
%% If there where any canceled request, handled by the
%% the process that now has terminated, the
%% cancelation can be viewed as sucessfull!
- NewCanceldList =
- lists:foldl(fun(Entry = {_, HandlerPid, From}, Acc) ->
+ NewCanceledList =
+ lists:foldl(fun({_, HandlerPid, From} = Entry, Acc) ->
case HandlerPid of
Pid ->
gen_server:reply(From, ok),
@@ -378,21 +573,25 @@ handle_info({'DOWN', _, _, Pid, _}, State) ->
Acc
end
end, State#state.cancel, State#state.cancel),
- {noreply, State#state{cancel = NewCanceldList}};
-handle_info(Info, State) ->
- Report = io_lib:format("Unknown message in "
- "httpc_manager:handle_info ~p~n", [Info]),
- error_logger:error_report(Report),
+ {noreply, State#state{cancel = NewCanceledList}};
+
+handle_info(Info, #state{profile_name = ProfileName} = State) ->
+ error_report(ProfileName,
+ "received unknown info"
+ "~n Info: ~p", [Info]),
{noreply, State}.
+
+
%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> _ (ignored by gen_server)
%% Description: Shutdown the httpc_handler
%%--------------------------------------------------------------------
terminate(_, State) ->
- http_cookie:close_cookie_db(State#state.cookie_db),
+ httpc_cookie:close_db(State#state.cookie_db),
ets:delete(State#state.session_db),
ets:delete(State#state.handler_db).
+
%%--------------------------------------------------------------------
%% Func: code_change(_OldVsn, State, Extra) -> {ok, NewState}
%% Purpose: Convert process state when code is changed
@@ -400,70 +599,217 @@ terminate(_, State) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+
%%--------------------------------------------------------------------
%% Internal functions
%%--------------------------------------------------------------------
-handle_request(#request{settings =
- #http_options{version = "HTTP/0.9"}} = Request,
- State) ->
- %% Act as an HTTP/0.9 client that does not know anything
- %% about persistent connections
- NewRequest = handle_cookies(generate_request_id(Request), State),
- NewHeaders =
- (NewRequest#request.headers)#http_request_h{connection
- = undefined},
- start_handler(NewRequest#request{headers = NewHeaders}, State),
- {reply, {ok, NewRequest#request.id}, State};
+get_manager_info(#state{handler_db = HDB,
+ cookie_db = CDB} = _State) ->
+ HandlerInfo = get_handler_info(HDB),
+ CookieInfo = httpc_cookie:which_cookies(CDB),
+ [{handlers, HandlerInfo}, {cookies, CookieInfo}].
+
+get_handler_info(Tab) ->
+ Pattern = #handler_info{handler = '$1',
+ state = '$2',
+ _ = '_'},
+ Handlers1 = [{Pid, State} || [Pid, State] <- ets:match(Tab, Pattern)],
+ F = fun({Pid, State} = Elem, Acc) when State =/= canceled ->
+ case lists:keymember(Pid, 1, Acc) of
+ true ->
+ Acc;
+ false ->
+ [Elem | Acc]
+ end;
+ (_, Acc) ->
+ Acc
+ end,
+ Handlers2 = lists:foldl(F, [], Handlers1),
+ Handlers3 = [{Pid, State, httpc_handler:info(Pid)} ||
+ {Pid, State} <- Handlers2],
+ Handlers3.
+
+
+%%
+%% The request handler process is started asynchronously by a
+%% "starter process". When that process terminates it sends
+%% one of two messages. These ara handled by the two functions
+%% below.
+%%
+
+handle_connect_and_send(_StarterPid, ReqId, HandlerPid, Result,
+ #state{profile_name = Profile,
+ handler_db = HandlerDb}) ->
+ case ets:lookup(HandlerDb, ReqId) of
+ [#handler_info{state = initiating} = HandlerInfo] when Result =:= ok ->
+ ?hcri("received connect-and-send ack for initiating handler", []),
+ HandlerInfo2 = HandlerInfo#handler_info{starter = undefined,
+ handler = HandlerPid,
+ state = operational},
+ ets:insert(HandlerDb, HandlerInfo2),
+ ok;
+
+ [#handler_info{state = canceled} = HandlerInfo] when Result =:= ok ->
+ ?hcri("received connect-and-send ack for canceled handler", []),
+ httpc_handler:cancel(ReqId, HandlerPid),
+ HandlerInfo2 = HandlerInfo#handler_info{starter = undefined,
+ handler = HandlerPid},
+ ets:insert(HandlerDb, HandlerInfo2),
+ ok;
+
+ [#handler_info{from = From}] ->
+ error_report(Profile,
+ "handler (~p) failed to connect and/or "
+ "send request ~p"
+ "~n Error: ~p", [HandlerPid, ReqId, Result]),
+ ?hcri("received connect-and-send error", [{result, Result}]),
+ Reason2 =
+ case Result of
+ {error, Reason} ->
+ {failed_connecting, Reason};
+ _ ->
+ {failed_connecting, Result}
+ end,
+ DummyReq = #request{id = ReqId},
+ httpc_response:send(From, httpc_response:error(DummyReq, Reason2)),
+ %% gen_server:reply(From, Error),
+ ets:delete(HandlerDb, ReqId),
+ ok;
+
+ [] ->
+ error_report(Profile,
+ "handler successfully (~p) started for unknown request ~p",
+ [HandlerPid, ReqId]),
+ httpc_handler:cancel(ReqId, HandlerPid)
+ end.
+
+handle_failed_starting_handler(_StarterPid, ReqId, Error,
+ #state{profile_name = Profile,
+ handler_db = HandlerDb}) ->
+ case ets:lookup(HandlerDb, ReqId) of
+ [#handler_info{state = canceled,
+ from = From}] ->
+ error_report(Profile,
+ "failed starting handler for request ~p"
+ "~n Error: ~p", [ReqId, Error]),
+ request_canceled(Profile, ReqId), % Fake signal from handler
+ gen_server:reply(From, Error),
+ ets:delete(HandlerDb, ReqId),
+ ok;
+
+ [#handler_info{from = From}] ->
+ error_report(Profile,
+ "failed starting handler for request ~p"
+ "~n Error: ~p", [ReqId, Error]),
+ gen_server:reply(From, Error),
+ ets:delete(HandlerDb, ReqId),
+ ok;
+
+ [] ->
+ error_report(Profile,
+ "failed starting handler for unknown request ~p"
+ "~n Error: ~p", [ReqId, Error]),
+ ok
+ end.
+
+
+maybe_handle_terminating_starter(MeybeStarterPid, Reason, HandlerDb) ->
+ Pattern = #handler_info{starter = MeybeStarterPid, _ = '_'},
+ case ets:match_object(HandlerDb, Pattern) of
+ [#handler_info{id = ReqId, from = From, state = initiating}] ->
+ Error = {error, {failed_starting_request_handler, Reason}},
+ gen_server:reply(From, Error),
+ ets:delete(HandlerDb, ReqId),
+ ok;
+ _ ->
+ ok
+ end.
+
+
+%% -----
+%% Act as an HTTP/0.9 client that does not know anything
+%% about persistent connections
handle_request(#request{settings =
- #http_options{version = "HTTP/1.0"}} = Request,
+ #http_options{version = "HTTP/0.9"}} = Request0,
State) ->
- %% Act as an HTTP/1.0 client that does not
- %% use persistent connections
-
- NewRequest = handle_cookies(generate_request_id(Request), State),
- NewHeaders =
- (NewRequest#request.headers)#http_request_h{connection
- = "close"},
- start_handler(NewRequest#request{headers = NewHeaders}, State),
- {reply, {ok, NewRequest#request.id}, State};
-
-handle_request(Request, State = #state{options = Options}) ->
-
- NewRequest = handle_cookies(generate_request_id(Request), State),
- SessionType = session_type(Options),
- case select_session(Request#request.method,
- Request#request.address,
- Request#request.scheme, SessionType, State) of
+ Request1 = handle_cookies(generate_request_id(Request0), State),
+ Hdrs0 = Request1#request.headers,
+ Hdrs1 = Hdrs0#http_request_h{connection = undefined},
+ Request2 = Request1#request{headers = Hdrs1},
+ create_handler_starter(Request2, State),
+ {ok, Request2#request.id, State};
+
+%% -----
+%% Act as an HTTP/1.0 client that does not
+%% use persistent connections
+handle_request(#request{settings =
+ #http_options{version = "HTTP/1.0"}} = Request0,
+ State) ->
+ Request1 = handle_cookies(generate_request_id(Request0), State),
+ Hdrs0 = Request1#request.headers,
+ Hdrs1 = Hdrs0#http_request_h{connection = "close"},
+ Request2 = Request1#request{headers = Hdrs1},
+ create_handler_starter(Request2, State),
+ {ok, Request2#request.id, State};
+
+
+%% -----
+handle_request(#request{method = Method,
+ address = Address,
+ scheme = Scheme} = Request0,
+ #state{options = Opts} = State) ->
+ Request1 = handle_cookies(generate_request_id(Request0), State),
+ SessionType = session_type(Opts),
+ case select_session(Method, Address, Scheme, SessionType, State) of
{ok, HandlerPid} ->
- pipeline_or_keep_alive(NewRequest, HandlerPid, State);
+ pipeline_or_keep_alive(Request1, HandlerPid, State);
no_connection ->
- start_handler(NewRequest, State);
- {no_session, OpenSessions} when OpenSessions
- < Options#options.max_sessions ->
- start_handler(NewRequest, State);
+ create_handler_starter(Request1, State);
+ {no_session, OpenSessions}
+ when OpenSessions < Opts#options.max_sessions ->
+ create_handler_starter(Request1, State);
{no_session, _} ->
%% Do not start any more persistent connections
%% towards this server.
- NewHeaders =
- (NewRequest#request.headers)#http_request_h{connection
- = "close"},
- start_handler(NewRequest#request{headers = NewHeaders}, State)
+ Hdrs0 = Request1#request.headers,
+ Hdrs1 = Hdrs0#http_request_h{connection = "close"},
+ Request2 = Request1#request{headers = Hdrs1},
+ create_handler_starter(Request2, State)
end,
- {reply, {ok, NewRequest#request.id}, State}.
+ {ok, Request1#request.id, State}.
-select_session(Method, HostPort, Scheme, SessionTyp,
- #state{options = #options{max_pipeline_length =
- MaxPipe,
+
+select_session(Method, HostPort, Scheme, SessionType,
+ #state{options = #options{max_pipeline_length = MaxPipe,
max_keep_alive_length = MaxKeepAlive},
session_db = SessionDb}) ->
- case httpc_request:is_idempotent(Method) or (SessionTyp == keep_alive) of
+ ?hcrd("select session", [{session_type, SessionType},
+ {max_pipeline_length, MaxPipe},
+ {max_keep_alive_length, MaxKeepAlive}]),
+ case httpc_request:is_idempotent(Method) orelse
+ (SessionType =:= keep_alive) of
true ->
- Candidates = ets:match(SessionDb,
- {'_', {HostPort, '$1'},
- false, Scheme, '_', '$2', SessionTyp}),
- select_session(Candidates, MaxKeepAlive, MaxPipe, SessionTyp);
+ %% Look for handlers connecting to this host (HostPort)
+ %% tcp_session with record name field (tcp_session) and
+ %% socket fields ignored. The fields id (part of: HostPort),
+ %% client_close, scheme and type specified.
+ %% The fields id (part of: HandlerPid) and queue_length
+ %% specified.
+ Pattern = #tcp_session{id = {HostPort, '$1'},
+ client_close = false,
+ scheme = Scheme,
+ socket = '_',
+ queue_length = '$2',
+ type = SessionType},
+ %% {'_', {HostPort, '$1'}, false, Scheme, '_', '$2', SessionTyp},
+ Candidates = ets:match(SessionDb, Pattern),
+ ?hcrd("select session", [{host_port, HostPort},
+ {scheme, Scheme},
+ {type, SessionType},
+ {candidates, Candidates}]),
+ select_session(Candidates, MaxKeepAlive, MaxPipe, SessionType);
false ->
no_connection
end.
@@ -473,51 +819,102 @@ select_session(Candidates, Max, _, keep_alive) ->
select_session(Candidates, _, Max, pipeline) ->
select_session(Candidates, Max).
+select_session([] = _Candidates, _Max) ->
+ ?hcrd("select session - no candicate", []),
+ no_connection;
select_session(Candidates, Max) ->
- case Candidates of
+ NewCandidates =
+ [{Pid, Length} || [Pid, Length] <- Candidates, Length =< Max],
+ case lists:keysort(2, NewCandidates) of
[] ->
- no_connection;
- _ ->
- NewCandidates =
- lists:foldl(
- fun([Pid, Length], Acc) when Length =< Max ->
- [{Pid, Length} | Acc];
- (_, Acc) ->
- Acc
- end, [], Candidates),
-
- case lists:keysort(2, NewCandidates) of
- [] ->
- {no_session, length(Candidates)};
- [{HandlerPid, _} | _] ->
- {ok, HandlerPid}
- end
+ {no_session, length(Candidates)};
+ [{HandlerPid, _} | _] ->
+ ?hcrd("select session - found one", [{handler, HandlerPid}]),
+ {ok, HandlerPid}
end.
-pipeline_or_keep_alive(Request, HandlerPid, State) ->
+pipeline_or_keep_alive(#request{id = Id} = Request, HandlerPid, State) ->
+ ?hcrd("pipeline of keep-alive", [{id, Id}, {handler, HandlerPid}]),
case (catch httpc_handler:send(Request, HandlerPid)) of
ok ->
- ets:insert(State#state.handler_db, {Request#request.id,
- HandlerPid,
- Request#request.from});
- _ -> %timeout pipelining failed
- start_handler(Request, State)
+ ?hcrd("pipeline or keep-alive - successfully sent", []),
+ Entry = #handler_info{id = Id,
+ handler = HandlerPid,
+ state = operational},
+ ets:insert(State#state.handler_db, Entry);
+
+ _ -> %% timeout pipelining failed
+ ?hcrd("pipeline or keep-alive - failed sending -> "
+ "start a new handler", []),
+ create_handler_starter(Request, State)
end.
-start_handler(Request, State) ->
- {ok, Pid} =
- case is_inets_manager() of
- true ->
- httpc_handler_sup:start_child([Request, State#state.options,
- State#state.profile_name]);
- false ->
- httpc_handler:start_link(Request, State#state.options,
- State#state.profile_name)
- end,
- ets:insert(State#state.handler_db, {Request#request.id,
- Pid, Request#request.from}),
- erlang:monitor(process, Pid).
+create_handler_starter(#request{socket_opts = SocketOpts} = Request,
+ #state{options = Options} = State)
+ when is_list(SocketOpts) ->
+ %% The user provided us with (override) socket options
+ ?hcrt("create handler starter", [{socket_opts, SocketOpts}, {options, Options}]),
+ Options2 = Options#options{socket_opts = SocketOpts},
+ create_handler_starter(Request#request{socket_opts = undefined},
+ State#state{options = Options2});
+
+create_handler_starter(#request{id = Id,
+ from = From} = Request,
+ #state{profile_name = ProfileName,
+ options = Options,
+ handler_db = HandlerDb} = _State) ->
+ ?hcrv("create handler starter", [{id, Id}, {profile, ProfileName}]),
+ IsInetsManager = is_inets_manager(),
+ ManagerPid = self(),
+ StarterFun =
+ fun() ->
+ ?hcrd("handler starter - start",
+ [{id, Id},
+ {profile, ProfileName},
+ {inets_manager, IsInetsManager}]),
+ Result1 =
+ case IsInetsManager of
+ true ->
+ httpc_handler_sup:start_child(Options,
+ ProfileName);
+ false ->
+ httpc_handler:start_link(Options,
+ ProfileName)
+ end,
+ ?hcrd("handler starter - maybe connect and send",
+ [{id, Id}, {profile, ProfileName}, {result, Result1}]),
+ case Result1 of
+ {ok, HandlerPid} ->
+ Result2 = httpc_handler:connect_and_send(Request,
+ HandlerPid),
+ ?hcrd("handler starter - connected and sent",
+ [{id, Id}, {profile, ProfileName},
+ {handler, HandlerPid}, {result, Result2}]),
+ ConnAndSendMessage =
+ {connect_and_send,
+ self(), Id, HandlerPid, Result2},
+ ManagerPid ! ConnAndSendMessage;
+ {error, Reason} ->
+ StartFailureMessage =
+ {failed_starting_handler, self(), Id, Reason},
+ ManagerPid ! StartFailureMessage;
+ _ ->
+ StartFailureMessage =
+ {failed_starting_handler, self(), Id, Result1},
+ ManagerPid ! StartFailureMessage
+ end
+ end,
+ Starter = erlang:spawn_link(StarterFun),
+ ?hcrd("create handler starter - started", [{id, Id}, {starter, Starter}]),
+ Entry = #handler_info{id = Id,
+ starter = Starter,
+ from = From,
+ state = initiating},
+ ets:insert(HandlerDb, Entry),
+ ok.
+
+
is_inets_manager() ->
case get('$ancestors') of
[httpc_profile_sup | _] ->
@@ -532,32 +929,55 @@ generate_request_id(Request) ->
RequestId = make_ref(),
Request#request{id = RequestId};
_ ->
- %% This is an automatic redirect or a retryed pipelined
- %% request keep the old id.
+ %% This is an automatic redirect or a retryed pipelined request
+ %% => keep the old id.
Request
end.
handle_cookies(Request, #state{options = #options{cookies = disabled}}) ->
Request;
-handle_cookies(Request = #request{scheme = Scheme, address = Address,
- path = Path, headers =
- Headers = #http_request_h{other = Other}},
- #state{cookie_db = Db}) ->
- case http_cookie:header(Scheme, Address, Path, Db) of
+handle_cookies(
+ #request{scheme = Scheme,
+ address = Address,
+ path = Path,
+ headers = #http_request_h{other = Other} = Hdrs} = Request,
+ #state{cookie_db = CookieDb}) ->
+ case httpc_cookie:header(CookieDb, Scheme, Address, Path) of
{"cookie", ""} ->
Request;
CookieHeader ->
- NewHeaders =
- Headers#http_request_h{other = [CookieHeader | Other]},
+ NewHeaders = Hdrs#http_request_h{other = [CookieHeader | Other]},
Request#request{headers = NewHeaders}
end.
do_store_cookies([], _) ->
ok;
-do_store_cookies([Cookie | Cookies], State) ->
- ok = http_cookie:insert(Cookie, State#state.cookie_db),
+do_store_cookies([Cookie | Cookies], #state{cookie_db = CookieDb} = State) ->
+ ok = httpc_cookie:insert(CookieDb, Cookie),
do_store_cookies(Cookies, State).
+
+
+session_db_name(ProfileName) ->
+ make_db_name(ProfileName, "__session_db").
+
+cookie_db_name(ProfileName) ->
+ make_db_name(ProfileName, "__cookie_db").
+
+session_cookie_db_name(ProfileName) ->
+ make_db_name(ProfileName, "__session_cookie_db").
+
+handler_db_name(ProfileName) ->
+ make_db_name(ProfileName, "__handler_db").
+
+make_db_name(ProfileName, Post) ->
+ list_to_atom(atom_to_list(ProfileName) ++ Post).
+
+
+
+call(ProfileName, Msg) ->
+ Timeout = infinity,
+ call(ProfileName, Msg, Timeout).
call(ProfileName, Msg, Timeout) ->
gen_server:call(ProfileName, Msg, Timeout).
@@ -611,6 +1031,9 @@ get_port(Opts, #options{port = Default}) ->
get_verbose(Opts, #options{verbose = Default}) ->
proplists:get_value(verbose, Opts, Default).
+get_socket_opts(Opts, #options{socket_opts = Default}) ->
+ proplists:get_value(socket_opts, Opts, Default).
+
handle_verbose(debug) ->
dbg:p(self(), [call]),
@@ -621,6 +1044,12 @@ handle_verbose(trace) ->
handle_verbose(_) ->
ok.
+
+error_report(Profile, F, A) ->
+ Report = io_lib:format("HTTPC-MANAGER<~p> " ++ F ++ "~n", [Profile | A]),
+ error_logger:error_report(Report).
+
+
%% d(F) ->
%% d(F, []).
diff --git a/lib/inets/src/http_client/httpc_profile_sup.erl b/lib/inets/src/http_client/httpc_profile_sup.erl
index 2351083435..29f86aa373 100644
--- a/lib/inets/src/http_client/httpc_profile_sup.erl
+++ b/lib/inets/src/http_client/httpc_profile_sup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -28,6 +28,7 @@
%% Supervisor callback
-export([init/1]).
+
%%%=========================================================================
%%% API
%%%=========================================================================
@@ -39,7 +40,8 @@ start_child(PropList) ->
undefined ->
{error, no_profile};
Profile ->
- Dir = proplists:get_value(data_dir, PropList, only_session_cookies),
+ Dir =
+ proplists:get_value(data_dir, PropList, only_session_cookies),
Spec = httpc_child_spec(Profile, Dir),
supervisor:start_child(?MODULE, Spec)
end.
@@ -63,12 +65,12 @@ stop_child(Profile) ->
end.
id(Profile) ->
- DefaultProfile = http:default_profile(),
+ DefaultProfile = httpc:default_profile(),
case Profile of
DefaultProfile ->
httpc_manager;
_ ->
- {http, Profile}
+ {httpc, Profile}
end.
@@ -98,7 +100,7 @@ child_spec([{httpc, PropList} | Rest], Acc) when is_list(PropList) ->
httpc_child_spec(Profile, Dir) ->
Name = id(Profile),
- StartFunc = {httpc_manager, start_link, [{Profile, Dir}]},
+ StartFunc = {httpc_manager, start_link, [Profile, Dir, inets]},
Restart = permanent,
Shutdown = 4000,
Modules = [httpc_manager],
diff --git a/lib/inets/src/http_client/httpc_request.erl b/lib/inets/src/http_client/httpc_request.erl
index 3d66638d66..55e0af4b42 100644
--- a/lib/inets/src/http_client/httpc_request.erl
+++ b/lib/inets/src/http_client/httpc_request.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -39,14 +39,47 @@
%%
%% Description: Composes and sends a HTTP-request.
%%-------------------------------------------------------------------------
-send(SendAddr, #request{method = Method, scheme = Scheme,
- path = Path, pquery = Query, headers = Headers,
- content = Content, address = Address,
- abs_uri = AbsUri, headers_as_is = HeadersAsIs,
- settings = HttpOptions,
- userinfo = UserInfo},
- Socket) ->
+send(SendAddr, #request{scheme = Scheme, socket_opts = SocketOpts} = Request,
+ Socket)
+ when is_list(SocketOpts) ->
+ SocketType = socket_type(Scheme),
+ case http_transport:setopts(SocketType, Socket, SocketOpts) of
+ ok ->
+ send(SendAddr, Socket, SocketType,
+ Request#request{socket_opts = undefined});
+ {error, Reason} ->
+ {error, {setopts_failed, Reason}}
+ end;
+send(SendAddr, #request{scheme = Scheme} = Request, Socket) ->
+ SocketType = socket_type(Scheme),
+ send(SendAddr, Socket, SocketType, Request).
+
+send(SendAddr, Socket, SocketType,
+ #request{method = Method,
+ path = Path,
+ pquery = Query,
+ headers = Headers,
+ content = Content,
+ address = Address,
+ abs_uri = AbsUri,
+ headers_as_is = HeadersAsIs,
+ settings = HttpOptions,
+ userinfo = UserInfo}) ->
+ ?hcrt("send",
+ [{send_addr, SendAddr},
+ {socket, Socket},
+ {method, Method},
+ {path, Path},
+ {pquery, Query},
+ {headers, Headers},
+ {content, Content},
+ {address, Address},
+ {abs_uri, AbsUri},
+ {headers_as_is, HeadersAsIs},
+ {settings, HttpOptions},
+ {userinfo, UserInfo}]),
+
TmpHeaders = handle_user_info(UserInfo, Headers),
{TmpHeaders2, Body} =
@@ -70,9 +103,14 @@ send(SendAddr, #request{method = Method, scheme = Scheme,
Version = HttpOptions#http_options.version,
Message = [method(Method), " ", Uri, " ",
- version(Version), ?CRLF, headers(FinalHeaders, Version), ?CRLF, Body],
+ version(Version), ?CRLF,
+ headers(FinalHeaders, Version), ?CRLF, Body],
+
+ ?hcrd("send", [{message, Message}]),
- http_transport:send(socket_type(Scheme), Socket, lists:append(Message)).
+ http_transport:send(SocketType, Socket, lists:append(Message)).
+
+
%%-------------------------------------------------------------------------
%% is_idempotent(Method) ->
@@ -123,7 +161,7 @@ is_client_closing(Headers) ->
%%% Internal functions
%%%========================================================================
post_data(Method, Headers, {ContentType, Body}, HeadersAsIs)
- when Method == post; Method == put ->
+ when (Method =:= post) orelse (Method =:= put) ->
ContentLength = body_length(Body),
NewBody = case Headers#http_request_h.expect of
"100-continue" ->
diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl
index e2ba66f730..df7d40a33e 100644
--- a/lib/inets/src/http_client/httpc_response.erl
+++ b/lib/inets/src/http_client/httpc_response.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -132,8 +132,13 @@ result(Response = {{_,Code,_}, _, _}, Request) when (Code div 100) =:= 5 ->
result(Response, Request) ->
transparent(Response, Request).
-send(To, Msg) ->
- To ! {http, Msg}.
+send(Receiver, Msg) when is_pid(Receiver) ->
+ Receiver ! {http, Msg};
+send(Receiver, Msg) when is_function(Receiver) ->
+ (catch Receiver(Msg));
+send({Module, Function, Args}, Msg) ->
+ (catch apply(Module, Function, [Msg | Args])).
+
%%%========================================================================
%%% Internal functions
diff --git a/lib/inets/src/http_lib/Makefile b/lib/inets/src/http_lib/Makefile
index 27e7ee65c5..7f4c92861c 100644
--- a/lib/inets/src/http_lib/Makefile
+++ b/lib/inets/src/http_lib/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -22,6 +22,7 @@ include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
# ----------------------------------------------------
# Application version
# ----------------------------------------------------
@@ -29,10 +30,12 @@ include ../../vsn.mk
VSN = $(INETS_VSN)
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
@@ -50,10 +53,12 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
+
# ----------------------------------------------------
# FLAGS
@@ -82,6 +87,7 @@ clean:
docs:
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -96,6 +102,8 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
+
diff --git a/lib/inets/src/http_lib/http_chunk.erl b/lib/inets/src/http_lib/http_chunk.erl
index cd20dce9d5..621bc68eae 100644
--- a/lib/inets/src/http_lib/http_chunk.erl
+++ b/lib/inets/src/http_lib/http_chunk.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Description: Implements chunked transfer encoding see RFC2616 section
@@ -186,13 +186,6 @@ decode_data(ChunkSize, TotalChunk,
Info = {MaxBodySize, BodySoFar, AccLength, MaxHeaderSize, Stream})
when ChunkSize =< size(TotalChunk) ->
case TotalChunk of
- %% Potential last chunk
- <<_:ChunkSize/binary, ?CR, ?LF, "0">> ->
- {?MODULE, decode_data, [ChunkSize, TotalChunk, Info]};
- <<_:ChunkSize/binary, ?CR, ?LF, "0", ?CR>> ->
- {?MODULE, decode_data, [ChunkSize, TotalChunk, Info]};
- <<_:ChunkSize/binary, ?CR, ?LF>> ->
- {?MODULE, decode_data, [ChunkSize, TotalChunk, Info]};
%% Last chunk
<<Data:ChunkSize/binary, ?CR, ?LF, "0", ";">> ->
%% Note ignore_extensions will call decode_trailer/1
@@ -223,6 +216,10 @@ decode_data(ChunkSize, TotalChunk,
NewBody,
integer_to_list(AccLength));
%% There are more chunks, so here we go agin...
+ <<Data:ChunkSize/binary, ?CR, ?LF>> ->
+ {NewBody, NewStream} =
+ stream(<<BodySoFar/binary, Data/binary>>, Stream),
+ {?MODULE, decode_size, [<<>>, [], {MaxBodySize, NewBody, AccLength, MaxHeaderSize, NewStream}]};
<<Data:ChunkSize/binary, ?CR, ?LF, Rest/binary>>
when (AccLength < MaxBodySize) or (MaxBodySize == nolimit) ->
{NewBody, NewStream} =
diff --git a/lib/inets/src/http_lib/http_transport.erl b/lib/inets/src/http_lib/http_transport.erl
index 8100d7183a..7c2ac626e6 100644
--- a/lib/inets/src/http_lib/http_transport.erl
+++ b/lib/inets/src/http_lib/http_transport.erl
@@ -1,32 +1,48 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-%
+
-module(http_transport).
% Internal application API
--export([start/1, connect/3, connect/4, listen/2, listen/3,
- accept/2, accept/3, close/2,
- send/3, controlling_process/3, setopts/3,
- peername/2, resolve/0]).
+-export([
+ start/1,
+ connect/3, connect/4,
+ listen/2, listen/3,
+ accept/2, accept/3,
+ close/2,
+ send/3,
+ controlling_process/3,
+ setopts/3, getopts/2, getopts/3,
+ getstat/2,
+ peername/2, sockname/2,
+ resolve/0
+ ]).
-export([negotiate/3]).
+-include("inets_internal.hrl").
+-define(SERVICE, httpl).
+-define(hlri(Label, Content), ?report_important(Label, ?SERVICE, Content)).
+-define(hlrv(Label, Content), ?report_verbose(Label, ?SERVICE, Content)).
+-define(hlrd(Label, Content), ?report_debug(Label, ?SERVICE, Content)).
+-define(hlrt(Label, Content), ?report_trace(Label, ?SERVICE, Content)).
+
%%%=========================================================================
%%% Internal application API
@@ -77,14 +93,22 @@ connect(SocketType, Address, Opts) ->
connect(ip_comm = _SocketType, {Host, Port}, Opts0, Timeout)
when is_list(Opts0) ->
Opts = [binary, {packet, 0}, {active, false}, {reuseaddr, true} | Opts0],
+ ?hlrt("connect using gen_tcp",
+ [{host, Host}, {port, Port}, {opts, Opts}, {timeout, Timeout}]),
gen_tcp:connect(Host, Port, Opts, Timeout);
connect({ssl, SslConfig}, {Host, Port}, _, Timeout) ->
Opts = [binary, {active, false}] ++ SslConfig,
+ ?hlrt("connect using ssl",
+ [{host, Host}, {port, Port}, {ssl_config, SslConfig},
+ {timeout, Timeout}]),
ssl:connect(Host, Port, Opts, Timeout);
connect({erl_ssl, SslConfig}, {Host, Port}, _, Timeout) ->
Opts = [binary, {active, false}, {ssl_imp, new}] ++ SslConfig,
+ ?hlrt("connect using erl_ssl",
+ [{host, Host}, {port, Port}, {ssl_config, SslConfig},
+ {timeout, Timeout}]),
ssl:connect(Host, Port, Opts, Timeout).
@@ -209,6 +233,7 @@ accept(ip_comm, ListenSocket, Timeout) ->
accept({ssl,_SSLConfig}, ListenSocket, Timeout) ->
ssl:transport_accept(ListenSocket, Timeout).
+
%%-------------------------------------------------------------------------
%% controlling_process(SocketType, Socket, NewOwner) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
@@ -222,6 +247,7 @@ controlling_process(ip_comm, Socket, NewOwner) ->
controlling_process({ssl, _}, Socket, NewOwner) ->
ssl:controlling_process(Socket, NewOwner).
+
%%-------------------------------------------------------------------------
%% setopts(SocketType, Socket, Options) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
@@ -231,10 +257,62 @@ controlling_process({ssl, _}, Socket, NewOwner) ->
%% gen_tcp or ssl.
%%-------------------------------------------------------------------------
setopts(ip_comm, Socket, Options) ->
- inet:setopts(Socket,Options);
+ ?hlrt("ip_comm setopts", [{socket, Socket}, {options, Options}]),
+ inet:setopts(Socket, Options);
setopts({ssl, _}, Socket, Options) ->
+ ?hlrt("ssl setopts", [{socket, Socket}, {options, Options}]),
ssl:setopts(Socket, Options).
+
+%%-------------------------------------------------------------------------
+%% getopts(SocketType, Socket [, Opts]) -> ok | {error, Reason}
+%% SocketType = ip_comm | {ssl, _}
+%% Socket = socket()
+%% Opts = socket_options()
+%% Description: Gets the values for some options.
+%%-------------------------------------------------------------------------
+getopts(SocketType, Socket) ->
+ Opts = [packet, packet_size, recbuf, sndbuf, priority, tos, send_timeout],
+ getopts(SocketType, Socket, Opts).
+
+getopts(ip_comm, Socket, Options) ->
+ ?hlrt("ip_comm getopts", [{socket, Socket}, {options, Options}]),
+ case inet:getopts(Socket, Options) of
+ {ok, SocketOpts} ->
+ SocketOpts;
+ {error, _} ->
+ []
+ end;
+getopts({ssl, _}, Socket, Options) ->
+ ?hlrt("ssl getopts", [{socket, Socket}, {options, Options}]),
+ case ssl:getopts(Socket, Options) of
+ {ok, SocketOpts} ->
+ SocketOpts;
+ {error, _} ->
+ []
+ end.
+
+
+%%-------------------------------------------------------------------------
+%% getstat(SocketType, Socket) -> socket_stats()
+%% SocketType = ip_comm | {ssl, _}
+%% Socket = socket()
+%% socket_stats() = list()
+%% Description: Gets the socket stats values for the socket
+%%-------------------------------------------------------------------------
+getstat(ip_comm = _SocketType, Socket) ->
+ ?hlrt("ip_comm getstat", [{socket, Socket}]),
+ case inet:getstat(Socket) of
+ {ok, Stats} ->
+ Stats;
+ {error, _} ->
+ []
+ end;
+getstat({ssl, _} = _SocketType, _Socket) ->
+ %% ?hlrt("ssl getstat", [{socket, Socket}]),
+ [].
+
+
%%-------------------------------------------------------------------------
%% send(RequestOrSocketType, Socket, Message) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
@@ -247,6 +325,7 @@ send(ip_comm, Socket, Message) ->
send({ssl, _}, Socket, Message) ->
ssl:send(Socket, Message).
+
%%-------------------------------------------------------------------------
%% close(SocketType, Socket) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
@@ -260,9 +339,11 @@ close({ssl, _}, Socket) ->
ssl:close(Socket).
%%-------------------------------------------------------------------------
-%% peername(SocketType, Socket) -> ok | {error, Reason}
+%% peername(SocketType, Socket) -> {Port, SockName}
%% SocketType = ip_comm | {ssl, _}
%% Socket = socket()
+%% Port = integer() (-1 if error occured)
+%% PeerName = string()
%%
%% Description: Returns the address and port for the other end of a
%% connection, usning either gen_tcp or ssl.
@@ -297,6 +378,48 @@ peername({ssl, _}, Socket) ->
{-1, "unknown"}
end.
+
+%%-------------------------------------------------------------------------
+%% sockname(SocketType, Socket) -> {Port, SockName}
+%% SocketType = ip_comm | {ssl, _}
+%% Socket = socket()
+%% Port = integer() (-1 if error occured)
+%% SockName = string()
+%%
+%% Description: Returns the address and port for the local (our) end
+%% other end of connection, using either gen_tcp or ssl.
+%%-------------------------------------------------------------------------
+sockname(ip_comm, Socket) ->
+ case inet:sockname(Socket) of
+ {ok,{{A, B, C, D}, Port}} ->
+ SockName = integer_to_list(A)++"."++integer_to_list(B)++"."++
+ integer_to_list(C)++"."++integer_to_list(D),
+ {Port, SockName};
+ {ok,{{A, B, C, D, E, F, G, H}, Port}} ->
+ SockName = http_util:integer_to_hexlist(A) ++ ":"++
+ http_util:integer_to_hexlist(B) ++ ":" ++
+ http_util:integer_to_hexlist(C) ++ ":" ++
+ http_util:integer_to_hexlist(D) ++ ":" ++
+ http_util:integer_to_hexlist(E) ++ ":" ++
+ http_util:integer_to_hexlist(F) ++ ":" ++
+ http_util:integer_to_hexlist(G) ++":"++
+ http_util:integer_to_hexlist(H),
+ {Port, SockName};
+ {error, _} ->
+ {-1, "unknown"}
+ end;
+
+sockname({ssl, _}, Socket) ->
+ case ssl:sockname(Socket) of
+ {ok,{{A, B, C, D}, Port}} ->
+ SockName = integer_to_list(A)++"."++integer_to_list(B)++"."++
+ integer_to_list(C)++"."++integer_to_list(D),
+ {Port, SockName};
+ {error, _} ->
+ {-1, "unknown"}
+ end.
+
+
%%-------------------------------------------------------------------------
%% resolve() -> HostName
%% HostName = string()
diff --git a/lib/inets/src/http_lib/http_util.erl b/lib/inets/src/http_lib/http_util.erl
index b03b780cf8..ddb58c7116 100644
--- a/lib/inets/src/http_lib/http_util.erl
+++ b/lib/inets/src/http_lib/http_util.erl
@@ -1,27 +1,33 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
-module(http_util).
--export([to_upper/1, to_lower/1, convert_netscapecookie_date/1,
+-export([
+ to_upper/1, to_lower/1,
+ convert_netscapecookie_date/1,
hexlist_to_integer/1, integer_to_hexlist/1,
- convert_month/1, is_hostname/1]).
+ convert_month/1,
+ is_hostname/1,
+ timestamp/0, timeout/2
+ ]).
+
%%%=========================================================================
%%% Internal application API
@@ -100,6 +106,21 @@ convert_month("Dec") -> 12.
is_hostname(Dest) ->
inet_parse:domain(Dest).
+
+timestamp() ->
+ {A,B,C} = os:timestamp(),
+ A*1000000000+B*1000+(C div 1000).
+
+timeout(Timeout, Started) ->
+ %% NewTimeout = Timeout - (timestamp() - Started),
+ case Timeout - (timestamp() - Started) of
+ NewTimeout when Timeout > 0 ->
+ NewTimeout;
+ _ ->
+ 0
+ end.
+
+
%%%========================================================================
%%% Internal functions
%%%========================================================================
diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile
index 4bbd23df3f..ce1405011e 100644
--- a/lib/inets/src/http_server/Makefile
+++ b/lib/inets/src/http_server/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -33,7 +33,7 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# ----------------------------------------------------
@@ -92,7 +92,7 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"'
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
# ----------------------------------------------------
@@ -133,6 +133,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/http_server/httpd.erl b/lib/inets/src/http_server/httpd.erl
index 554f162fc5..8fe54ccef6 100644
--- a/lib/inets/src/http_server/httpd.erl
+++ b/lib/inets/src/http_server/httpd.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -358,7 +358,7 @@ foreach([KeyValue|Rest]) ->
get_addr_and_port(ConfigFile) ->
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
@@ -506,7 +506,7 @@ get_status(Addr,Port,Timeout) when is_integer(Port) ->
end.
do_reload_config(ConfigList, Mode) ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl
index 9c93e2c5fe..3e498d1db7 100644
--- a/lib/inets/src/http_server/httpd_conf.erl
+++ b/lib/inets/src/http_server/httpd_conf.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -864,17 +864,22 @@ load_traverse(Line, [Context|Contexts], [Module|Modules], NewContexts,
{'EXIT', {undef, _}} ->
?hdrt("does not implement load", []),
load_traverse(Line, Contexts, Modules,
- [Context|NewContexts], ConfigList,yes);
+ [Context|NewContexts], ConfigList, yes);
{'EXIT', Reason} ->
error_logger:error_report({'EXIT', Reason}),
load_traverse(Line, Contexts, Modules,
[Context|NewContexts], ConfigList, State);
+ ok ->
+ ?hdrt("line processed", []),
+ load_traverse(Line, Contexts, Modules,
+ [Context|NewContexts], ConfigList, yes);
+
{ok, NewContext} ->
?hdrt("line processed", [{new_context, NewContext}]),
load_traverse(Line, Contexts, Modules,
- [NewContext|NewContexts], ConfigList,yes);
+ [NewContext|NewContexts], ConfigList, yes);
{ok, NewContext, ConfigEntry} when is_tuple(ConfigEntry) ->
?hdrt("line processed",
diff --git a/lib/inets/src/http_server/httpd_instance_sup.erl b/lib/inets/src/http_server/httpd_instance_sup.erl
index 3b5464132c..0aaeb838c2 100644
--- a/lib/inets/src/http_server/httpd_instance_sup.erl
+++ b/lib/inets/src/http_server/httpd_instance_sup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -37,7 +37,7 @@
%%% Internal Application API
%%%=========================================================================
start_link([{_, _}| _] = Config, AcceptTimeout, Debug) ->
- case httpd_conf:validate_properties(Config) of
+ case (catch httpd_conf:validate_properties(Config)) of
{ok, Config2} ->
Address = proplists:get_value(bind_address, Config2),
Port = proplists:get_value(port, Config2),
@@ -66,7 +66,7 @@ start_link(ConfigFile, AcceptTimeout, Debug) ->
start_link([{_, _}| _] = Config, AcceptTimeout, ListenInfo, Debug) ->
- case httpd_conf:validate_properties(Config) of
+ case (catch httpd_conf:validate_properties(Config)) of
{ok, Config2} ->
Address = proplists:get_value(bind_address, Config2),
Port = proplists:get_value(port, Config2),
@@ -154,7 +154,7 @@ make_name(Address,Port) ->
file_2_config(ConfigFile) ->
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, ConfigList),
Port = proplists:get_value(port, ConfigList),
diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl
index ad2cc4bda3..8eee08e766 100644
--- a/lib/inets/src/http_server/httpd_request.erl
+++ b/lib/inets/src/http_server/httpd_request.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -68,10 +68,11 @@ body_data(Headers, Body) ->
{binary_to_list(BodyThisReq), Next}
end.
+
%%-------------------------------------------------------------------------
%% validate(Method, Uri, Version) -> ok | {error, {bad_request, Reason} |
%% {error, {not_supported, {Method, Uri, Version}}
-%% Method = "HEAD" | "GET" | "POST" | "TRACE"
+%% Method = "HEAD" | "GET" | "POST" | "TRACE" | "PUT" | "DELETE"
%% Uri = uri()
%% Version = "HTTP/N.M"
%% Description: Checks that HTTP-request-line is valid.
@@ -84,6 +85,10 @@ validate("GET", Uri, "HTTP/0.9") ->
validate_uri(Uri);
validate("GET", Uri, "HTTP/1." ++ _N) ->
validate_uri(Uri);
+validate("PUT", Uri, "HTTP/1." ++ _N) ->
+ validate_uri(Uri);
+validate("DELETE", Uri, "HTTP/1." ++ _N) ->
+ validate_uri(Uri);
validate("POST", Uri, "HTTP/1." ++ _N) ->
validate_uri(Uri);
validate("TRACE", Uri, "HTTP/1." ++ N) when hd(N) >= $1 ->
diff --git a/lib/inets/src/http_server/httpd_sup.erl b/lib/inets/src/http_server/httpd_sup.erl
index fc41994727..3399f78b53 100644
--- a/lib/inets/src/http_server/httpd_sup.erl
+++ b/lib/inets/src/http_server/httpd_sup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -169,7 +169,7 @@ httpd_child_spec([Value| _] = Config, AcceptTimeout, Debug)
httpd_child_spec(ConfigFile, AcceptTimeout, Debug) ->
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
diff --git a/lib/inets/src/http_server/mod_alias.erl b/lib/inets/src/http_server/mod_alias.erl
index 7073f5405d..ec0a12242f 100644
--- a/lib/inets/src/http_server/mod_alias.erl
+++ b/lib/inets/src/http_server/mod_alias.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -28,44 +28,51 @@
path/3]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
-define(VMODULE,"ALIAS").
%% do
-do(Info) ->
- case proplists:get_value(status, Info#mod.data) of
+do(#mod{data = Data} = Info) ->
+ ?hdrt("do", []),
+ case proplists:get_value(status, Data) of
%% A status code has been generated!
{_StatusCode, _PhraseArgs, _Reason} ->
- {proceed,Info#mod.data};
+ {proceed, Data};
%% No status code has been generated!
undefined ->
- case proplists:get_value(response, Info#mod.data) of
+ case proplists:get_value(response, Data) of
%% No response has been generated!
undefined ->
do_alias(Info);
%% A response has been generated or sent!
_Response ->
- {proceed, Info#mod.data}
+ {proceed, Data}
end
end.
-do_alias(Info) ->
- {ShortPath, Path, AfterPath} =
- real_name(Info#mod.config_db,
- Info#mod.request_uri,
- httpd_util:multi_lookup(Info#mod.config_db,alias)),
+do_alias(#mod{config_db = ConfigDB,
+ request_uri = ReqURI,
+ data = Data}) ->
+ {ShortPath, Path, AfterPath} =
+ real_name(ConfigDB, ReqURI, which_alias(ConfigDB)),
+ ?hdrt("real name",
+ [{request_uri, ReqURI},
+ {short_path, ShortPath},
+ {path, Path},
+ {after_path, AfterPath}]),
%% Relocate if a trailing slash is missing else proceed!
LastChar = lists:last(ShortPath),
case file:read_file_info(ShortPath) of
- {ok, FileInfo} when FileInfo#file_info.type == directory,
- LastChar /= $/ ->
- ServerName = httpd_util:lookup(Info#mod.config_db, server_name),
- Port = port_string(httpd_util:lookup(Info#mod.config_db,port, 80)),
- URL = "http://" ++ ServerName ++ Port ++
- Info#mod.request_uri ++ "/",
+ {ok, FileInfo} when ((FileInfo#file_info.type =:= directory) andalso
+ (LastChar =/= $/)) ->
+ ?hdrt("directory and last-char is a /", []),
+ ServerName = which_server_name(ConfigDB),
+ Port = port_string( which_port(ConfigDB) ),
+ URL = "http://" ++ ServerName ++ Port ++ ReqURI ++ "/",
ReasonPhrase = httpd_util:reason_phrase(301),
- Message = httpd_util:message(301, URL, Info#mod.config_db),
+ Message = httpd_util:message(301, URL, ConfigDB),
{proceed,
[{response,
{301, ["Location: ", URL, "\r\n"
@@ -76,25 +83,26 @@ do_alias(Info) ->
"<BODY>\n<H1>",ReasonPhrase,
"</H1>\n", Message,
"\n</BODY>\n</HTML>\n"]}}|
- [{real_name, {Path, AfterPath}} | Info#mod.data]]};
+ [{real_name, {Path, AfterPath}} | Data]]};
_NoFile ->
- {proceed,[{real_name, {Path, AfterPath}} | Info#mod.data]}
+ {proceed, [{real_name, {Path, AfterPath}} | Data]}
end.
port_string(80) ->
"";
port_string(Port) ->
- ":"++integer_to_list(Port).
+ ":" ++ integer_to_list(Port).
%% real_name
real_name(ConfigDB, RequestURI, []) ->
- DocumentRoot = httpd_util:lookup(ConfigDB, document_root, ""),
+ DocumentRoot = which_document_root(ConfigDB),
RealName = DocumentRoot ++ RequestURI,
{ShortPath, _AfterPath} = httpd_util:split_path(RealName),
- {Path, AfterPath} = httpd_util:split_path(default_index(ConfigDB,
- RealName)),
+ {Path, AfterPath} =
+ httpd_util:split_path(default_index(ConfigDB, RealName)),
{ShortPath, Path, AfterPath};
+
real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) ->
case inets_regexp:match(RequestURI, "^" ++ FakeName) of
{match, _, _} ->
@@ -105,7 +113,7 @@ real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) ->
httpd_util:split_path(default_index(ConfigDB, ActualName)),
{ShortPath, Path, AfterPath};
nomatch ->
- real_name(ConfigDB,RequestURI,Rest)
+ real_name(ConfigDB, RequestURI, Rest)
end.
%% real_script_name
@@ -113,20 +121,21 @@ real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) ->
real_script_name(_ConfigDB, _RequestURI, []) ->
not_a_script;
real_script_name(ConfigDB, RequestURI, [{FakeName,RealName} | Rest]) ->
- case inets_regexp:match(RequestURI,"^"++FakeName) of
+ case inets_regexp:match(RequestURI, "^" ++ FakeName) of
{match,_,_} ->
- {ok,ActualName,_}=inets_regexp:sub(RequestURI,"^"++FakeName,RealName),
- httpd_util:split_script_path(default_index(ConfigDB,ActualName));
+ {ok, ActualName, _} =
+ inets_regexp:sub(RequestURI, "^" ++ FakeName, RealName),
+ httpd_util:split_script_path(default_index(ConfigDB, ActualName));
nomatch ->
- real_script_name(ConfigDB,RequestURI,Rest)
+ real_script_name(ConfigDB, RequestURI, Rest)
end.
%% default_index
default_index(ConfigDB, Path) ->
case file:read_file_info(Path) of
- {ok, FileInfo} when FileInfo#file_info.type == directory ->
- DirectoryIndex = httpd_util:lookup(ConfigDB, directory_index, []),
+ {ok, FileInfo} when FileInfo#file_info.type =:= directory ->
+ DirectoryIndex = which_directory_index(ConfigDB),
append_index(Path, DirectoryIndex);
_ ->
Path
@@ -147,9 +156,9 @@ append_index(RealName, [Index | Rest]) ->
path(Data, ConfigDB, RequestURI) ->
case proplists:get_value(real_name, Data) of
undefined ->
- DocumentRoot = httpd_util:lookup(ConfigDB, document_root, ""),
+ DocumentRoot = which_document_root(ConfigDB),
{Path, _AfterPath} =
- httpd_util:split_path(DocumentRoot++RequestURI),
+ httpd_util:split_path(DocumentRoot ++ RequestURI),
Path;
{Path, _AfterPath} ->
Path
@@ -164,7 +173,7 @@ path(Data, ConfigDB, RequestURI) ->
load("DirectoryIndex " ++ DirectoryIndex, []) ->
{ok, DirectoryIndexes} = inets_regexp:split(DirectoryIndex," "),
{ok,[], {directory_index, DirectoryIndexes}};
-load("Alias " ++ Alias,[]) ->
+load("Alias " ++ Alias, []) ->
case inets_regexp:split(Alias," ") of
{ok, [FakeName, RealName]} ->
{ok,[],{alias,{FakeName,RealName}}};
@@ -191,13 +200,13 @@ store({directory_index, Value} = Conf, _) when is_list(Value) ->
end;
store({directory_index, Value}, _) ->
{error, {wrong_type, {directory_index, Value}}};
-store({alias, {Fake, Real}} = Conf, _) when is_list(Fake),
- is_list(Real) ->
+store({alias, {Fake, Real}} = Conf, _)
+ when is_list(Fake) andalso is_list(Real) ->
{ok, Conf};
store({alias, Value}, _) ->
{error, {wrong_type, {alias, Value}}};
-store({script_alias, {Fake, Real}} = Conf, _) when is_list(Fake),
- is_list(Real) ->
+store({script_alias, {Fake, Real}} = Conf, _)
+ when is_list(Fake) andalso is_list(Real) ->
{ok, Conf};
store({script_alias, Value}, _) ->
{error, {wrong_type, {script_alias, Value}}}.
@@ -208,3 +217,21 @@ is_directory_index_list([Head | Tail]) when is_list(Head) ->
is_directory_index_list(Tail);
is_directory_index_list(_) ->
false.
+
+
+%% ---------------------------------------------------------------------
+
+which_alias(ConfigDB) ->
+ httpd_util:multi_lookup(ConfigDB, alias).
+
+which_server_name(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, server_name).
+
+which_port(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, port, 80).
+
+which_document_root(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, document_root, "").
+
+which_directory_index(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, directory_index, []).
diff --git a/lib/inets/src/http_server/mod_cgi.erl b/lib/inets/src/http_server/mod_cgi.erl
index ab12a3b57b..33605b9698 100644
--- a/lib/inets/src/http_server/mod_cgi.erl
+++ b/lib/inets/src/http_server/mod_cgi.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -335,6 +335,8 @@ script_elements(#mod{method = "GET"}, {PathInfo, QueryString}) ->
[{query_string, QueryString}, {path_info, PathInfo}];
script_elements(#mod{method = "POST", entity_body = Body}, _) ->
[{entity_body, Body}];
+script_elements(#mod{method = "PUT", entity_body = Body}, _) ->
+ [{entity_body, Body}];
script_elements(_, _) ->
[].
diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl
index dd6f62ae2d..484d4b3fb4 100644
--- a/lib/inets/src/http_server/mod_esi.erl
+++ b/lib/inets/src/http_server/mod_esi.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -249,7 +249,24 @@ erl(#mod{method = Method} = ModData, ESIBody, Modules)
{proceed, [{status,{400, none, BadRequest}} | ModData#mod.data]}
end;
-erl(#mod{method = "POST", entity_body = Body} = ModData, ESIBody, Modules) ->
+erl(#mod{request_uri = ReqUri,
+ method = "PUT",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed, [{status,{501,{"PUT", ReqUri, Version},
+ ?NICE("Erl mechanism doesn't support method PUT")}}|
+ Data]};
+
+erl(#mod{request_uri = ReqUri,
+ method = "DELETE",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed,[{status,{501,{"DELETE", ReqUri, Version},
+ ?NICE("Erl mechanism doesn't support method DELETE")}}|
+ Data]};
+
+erl(#mod{method = "POST",
+ entity_body = Body} = ModData, ESIBody, Modules) ->
case httpd_util:split(ESIBody,":|%3A|/",2) of
{ok,[ModuleName, Function]} ->
generate_webpage(ModData, ESIBody, Modules,
@@ -444,8 +461,26 @@ input_type([_First|Rest]) ->
%%------------------------ Eval mechanism --------------------------------
-eval(#mod{request_uri = ReqUri, method = "POST",
- http_version = Version, data = Data}, _ESIBody, _Modules) ->
+eval(#mod{request_uri = ReqUri,
+ method = "PUT",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed,[{status,{501,{"PUT", ReqUri, Version},
+ ?NICE("Eval mechanism doesn't support method PUT")}}|
+ Data]};
+
+eval(#mod{request_uri = ReqUri,
+ method = "DELETE",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed,[{status,{501,{"DELETE", ReqUri, Version},
+ ?NICE("Eval mechanism doesn't support method DELETE")}}|
+ Data]};
+
+eval(#mod{request_uri = ReqUri,
+ method = "POST",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
{proceed,[{status,{501,{"POST", ReqUri, Version},
?NICE("Eval mechanism doesn't support method POST")}}|
Data]};
diff --git a/lib/inets/src/inets_app/Makefile b/lib/inets/src/inets_app/Makefile
index 2dab99386a..33c9e34a3a 100644
--- a/lib/inets/src/inets_app/Makefile
+++ b/lib/inets/src/inets_app/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -22,6 +22,7 @@ include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
# ----------------------------------------------------
# Application version
# ----------------------------------------------------
@@ -32,12 +33,13 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
+
MODULES = \
inets_service \
inets \
@@ -49,7 +51,8 @@ HRL_FILES = inets_internal.hrl
ERL_FILES = $(MODULES:%=%.erl)
-TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) \
+TARGET_FILES= \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR)) \
$(APP_TARGET) \
$(APPUP_TARGET)
@@ -66,7 +69,7 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
# ----------------------------------------------------
@@ -108,14 +111,15 @@ $(APPUP_TARGET): $(APPUP_SRC) ../../vsn.mk
include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
- $(INSTALL_DIR) $(RELSYSDIR)/src
+ $(INSTALL_DIR) $(RELSYSDIR)/src
$(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src
- $(INSTALL_DIR) $(RELSYSDIR)/ebin
+ $(INSTALL_DIR) $(RELSYSDIR)/ebin
$(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/inets_app/inets.app.src b/lib/inets/src/inets_app/inets.app.src
index 6524c3b19b..04f6365b98 100644
--- a/lib/inets/src/inets_app/inets.app.src
+++ b/lib/inets/src/inets_app/inets.app.src
@@ -1,19 +1,19 @@
%% This is an -*- erlang -*- file.
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -34,7 +34,8 @@
ftp_sup,
%% HTTP client:
- http,
+ http, %% Old client API module
+ httpc, %% New client API module
httpc_handler,
httpc_handler_sup,
httpc_manager,
@@ -42,7 +43,7 @@
httpc_request,
httpc_response,
httpc_sup,
- http_cookie,
+ httpc_cookie,
http_uri, %% Proably will by used by server also in the future
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index 0112a64239..2efa7ccb60 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -1,34 +1,31 @@
%% This is an -*- erlang -*- file.
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
{"%VSN%",
[
{"5.2",
[
- {load_module, inets, soft_purge, soft_purge, []}
+ {restart_application, inets}
]
},
{"5.1.3",
[
- {load_module, httpd_response, soft_purge, soft_purge, []},
- {update, ftp, {advanced, upgrade_from_pre_5_12},
- soft_purge, soft_purge, []},
- {update, httpc_handler, soft, soft_purge, soft_purge, []}
+ {restart_application, inets}
]
},
{"5.1.2",
@@ -40,15 +37,12 @@
[
{"5.2",
[
- {load_module, inets, soft_purge, soft_purge, []}
+ {restart_application, inets}
]
},
{"5.1.3",
[
- {load_module, httpd_response, soft_purge, soft_purge, []},
- {update, ftp, {advanced, downgrade_to_pre_5_12},
- soft_purge, soft_purge, []},
- {update, httpc_handler, soft, soft_purge, soft_purge, []}
+ {restart_application, inets}
]
},
{"5.1.2",
diff --git a/lib/inets/src/inets_app/inets.erl b/lib/inets/src/inets_app/inets.erl
index 77cb14cc20..7e3f862ee7 100644
--- a/lib/inets/src/inets_app/inets.erl
+++ b/lib/inets/src/inets_app/inets.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -522,9 +522,7 @@ change_pattern({Mod, Service, Pattern})
catch
exit:{Where, Reason} ->
{error, {Where, Reason}}
- end;
- _ ->
- exit({bad_pattern, Pattern})
+ end
end,
ok.
@@ -728,7 +726,7 @@ call_service(Service, Call, Args) ->
service_module(tftpd) ->
tftp;
service_module(httpc) ->
- http;
+ httpc;
service_module(ftpc) ->
ftp;
service_module(Service) ->
diff --git a/lib/inets/src/tftp/Makefile b/lib/inets/src/tftp/Makefile
index 63f70f7943..b4339da1e2 100644
--- a/lib/inets/src/tftp/Makefile
+++ b/lib/inets/src/tftp/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -33,7 +33,8 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
@@ -53,10 +54,12 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
+
# ----------------------------------------------------
# FLAGS
@@ -64,6 +67,8 @@ INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
ERL_COMPILE_FLAGS += $(INETS_FLAGS) \
+'{parse_transform,sys_pre_attributes}' \
+'{attribute,insert,app_vsn,$(APP_VSN)}'
+
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
@@ -90,6 +95,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile
new file mode 100644
index 0000000000..668752da9e
--- /dev/null
+++ b/lib/inets/test/Makefile
@@ -0,0 +1,343 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+# For an outline of how this all_SUITE_data stuff works, see the
+# make file ../../ssl/test/Makefile.
+#
+include $(ERL_TOP)/make/target.mk
+
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN = $(INETS_VSN)
+
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+INCLUDES = -I. \
+ -I$(ERL_TOP)/lib/test_server/include/ \
+ -I$(ERL_TOP)/lib/inets/src/inets_app \
+ -I$(ERL_TOP)/lib/inets/src/http_lib \
+ -I$(ERL_TOP)/lib/inets/src/http_client \
+ -I$(ERL_TOP)/lib/inets/src/ftp
+
+CP = cp
+
+ifeq ($(TESTROOT_DIR),)
+TESTROOT_DIR = /ldisk/tests/$(USER)/inets
+endif
+
+ifeq ($(INETS_DATA_DIR),)
+INETS_DATA_DIR = $(TESTROOT_DIR)/data_dir
+endif
+
+ifeq ($(INETS_PRIV_DIR),)
+INETS_PRIV_DIR = $(TESTROOT_DIR)/priv_dir
+endif
+
+INETS_FLAGS = -Dinets_data_dir='"$(INETS_DATA_DIR)"' \
+ -Dinets_priv_dir='"$(INETS_PRIV_DIR)"'
+
+
+###
+### test suite debug flags
+###
+ifeq ($(FTP_DEBUG_CLIENT),)
+ FTP_DEBUG_CLIENT = y
+endif
+
+ifeq ($(FTP_DEBUG_CLIENT),)
+ FTP_FLAGS += -Dftp_debug_client
+endif
+
+ifeq ($(FTP_TRACE_CLIENT),)
+ FTP_DEBUG_CLIENT = y
+endif
+
+ifeq ($(FTP_TRACE_CLIENT),y)
+ FTP_FLAGS += -Dftp_trace_client
+endif
+
+ifneq ($(FTP_DEBUG),)
+ FTP_DEBUG = s
+endif
+
+ifeq ($(FTP_DEBUG),l)
+ FTP_FLAGS += -Dftp_log
+endif
+
+ifeq ($(FTP_DEBUG),d)
+ FTP_FLAGS += -Dftp_debug -Dftp_log
+endif
+
+ifeq ($(INETS_DEBUG),)
+ INETS_DEBUG = d
+endif
+
+ifeq ($(INETS_DEBUG),l)
+ INETS_FLAGS += -Dinets_log
+endif
+
+ifeq ($(INETS_DEBUG),d)
+ INETS_FLAGS += -Dinets_debug -Dinets_log
+endif
+
+
+###
+### HTTPD verbosity flags
+###
+
+ifneq ($(MANV),)
+ INETS_FLAGS += -Dhttpd_manager_verbosity=$(MANV)
+else
+ INETS_FLAGS += -Dhttpd_manager_verbosity=trace
+endif
+
+ifneq ($(REQV),)
+ INETS_FLAGS += -Dhttpd_request_handler_verbosity=$(REQV)
+else
+ INETS_FLAGS += -Dhttpd_request_handler_verbosity=trace
+endif
+
+ifneq ($(ACCV),)
+ INETS_FLAGS += -Dhttpd_acceptor_verbosity=$(ACCV)
+else
+ INETS_FLAGS += -Dhttpd_acceptor_verbosity=trace
+endif
+
+ifneq ($(AUTHV),)
+ INETS_FLAGS += -Dhttpd_auth_verbosity=$(AUTHV)
+else
+ INETS_FLAGS += -Dhttpd_auth_verbosity=log
+endif
+
+ifneq ($(SECV),)
+ INETS_FLAGS += -Dhttpd_security_verbosity=$(SECV)
+else
+ INETS_FLAGS += -Dhttpd_security_verbosity=log
+endif
+
+INETS_ROOT = ../../inets
+
+MODULES = \
+ inets_test_lib \
+ ftp_SUITE \
+ ftp_format_SUITE \
+ ftp_solaris8_sparc_test \
+ ftp_solaris9_sparc_test \
+ ftp_solaris10_sparc_test \
+ ftp_solaris10_x86_test \
+ ftp_linux_x86_test \
+ ftp_linux_ppc_test \
+ ftp_macosx_x86_test \
+ ftp_macosx_ppc_test \
+ ftp_openbsd_x86_test \
+ ftp_freebsd_x86_test \
+ ftp_netbsd_x86_test \
+ ftp_windows_xp_test \
+ ftp_windows_2003_server_test \
+ ftp_suite_lib \
+ ftp_ticket_test \
+ http_format_SUITE \
+ httpc_SUITE \
+ httpc_cookie_SUITE \
+ httpd_SUITE \
+ httpd_basic_SUITE \
+ httpd_mod \
+ httpd_block \
+ httpd_load \
+ httpd_time_test \
+ httpd_1_1 \
+ httpd_test_lib \
+ inets_sup_SUITE \
+ inets_SUITE \
+ inets_app_test \
+ inets_appup_test \
+ tftp_test_lib \
+ tftp_SUITE
+
+
+EBIN = .
+
+HRL_FILES = inets_test_lib.hrl \
+ inets_internal.hrl \
+ ftp_internal.hrl \
+ httpc_internal.hrl \
+ http_internal.hrl \
+ tftp_test_lib.hrl
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+SOURCE = $(ERL_FILES) $(HRL_FILES)
+
+TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INETS_SPECS = inets.spec inets.spec.vxworks
+INETS_FILES = inets.config $(INETS_SPECS)
+
+# SUB_SUITES = \
+# inets_sup_suite \
+# inets_httpd_suite \
+# inets_httpc_suite \
+# inets_ftp_suite \
+# inets_tftp_suite
+
+INETS_DATADIRS = inets_SUITE_data inets_sup_SUITE_data
+HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data
+HTTPC_DATADIRS = httpc_SUITE_data
+FTP_DATADIRS = ftp_SUITE_data
+
+DATADIRS = $(INETS_DATADIRS) $(HTTPD_DATADIRS) $(HTTPC_DATADIRS) $(FTP_DATADIRS)
+
+EMAKEFILE = Emakefile
+MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
+
+ifeq ($(MAKE_EMAKE),)
+BUILDTARGET = $(TARGET_FILES)
+RELTEST_FILES = $(INETS_SPECS) $(SOURCE)
+else
+BUILDTARGET = emakebuild
+RELTEST_FILES = $(EMAKEFILE) $(INETS_SPECS) $(SOURCE)
+endif
+
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+
+RELTESTSYSDIR = $(RELEASE_PATH)/inets_test
+RELTESTSYSALLDATADIR = $(RELTESTSYSDIR)/all_SUITE_data
+RELTESTSYSBINDIR = $(RELTESTSYSALLDATADIR)/bin
+
+
+# ----------------------------------------------------
+# FLAGS
+# The path to the test_server ebin dir is needed when
+# running the target "targets".
+# ----------------------------------------------------
+ERL_COMPILE_FLAGS += -pa ../../../internal_tools/test_server/ebin \
+ $(INCLUDES) $(FTP_FLAGS) $(INETS_FLAGS)
+
+# ----------------------------------------------------
+# Targets
+# erl -sname kalle -pa ../ebin
+# If you intend to run the test suite locally (private), then
+# there is some requirements:
+# 1) INETS_PRIV_DIR must be created
+# ----------------------------------------------------
+
+tests debug opt: $(BUILDTARGET)
+
+targets: $(TARGET_FILES)
+
+.PHONY: emakebuild
+
+emakebuild: $(EMAKEFILE)
+
+$(EMAKEFILE):
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' | grep -v Warning > $(EMAKEFILE)
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) | grep -v Warning >> $(EMAKEFILE)
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core *~
+
+docs:
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)/test
+ $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/test
+ $(INSTALL_DATA) $(INETS_FILES) $(RELSYSDIR)/test
+ @for d in $(DATADIRS); do \
+ echo "installing data dir $$d"; \
+ echo $$d/TAR.exclude2 > $$d/TAR.exclude2; \
+ cat $$d/TAR.exclude >> $$d/TAR.exclude2; \
+ find $$d -name '*.contrib*' >> $$d/TAR.exclude2; \
+ find $$d -name '*.keep*' >> $$d/TAR.exclude2; \
+ find $$d -name '*.mkelem*' >> $$d/TAR.exclude2; \
+ find $$d -name '*~' >> $$d/TAR.exclude2; \
+ find $$d -name 'erl_crash.dump' >> $$d/TAR.exclude2; \
+ find $$d -name 'core' >> $$d/TAR.exclude2; \
+ find $$d -name '.cmake.state' >> $$d/TAR.exclude2; \
+ tar cfX - $$d/TAR.exclude2 $$d | (cd $(RELSYSDIR)/test; tar xf -); \
+ done
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELTESTSYSDIR)
+ $(INSTALL_DATA) $(RELTEST_FILES) $(RELTESTSYSDIR)
+ chmod -f -R u+w $(RELTESTSYSDIR)
+ tar chf - $(DATADIRS) | (cd $(RELTESTSYSDIR); tar xf -)
+ $(INSTALL_DIR) $(RELTESTSYSALLDATADIR)
+ $(INSTALL_DIR) $(RELTESTSYSBINDIR)
+ chmod -f -R +x $(RELTESTSYSBINDIR)
+ $(INSTALL_DIR) $(RELTESTSYSALLDATADIR)/win32/lib
+
+release_docs_spec:
+
+info:
+ @echo "MAKE_EMAKE = $(MAKE_EMAKE)"
+ @echo "EMAKEFILE = $(EMAKEFILE)"
+ @echo "BUILDTARGET = $(BUILDTARGET)"
+ @echo ""
+ @echo "MODULES = $(MODULES)"
+ @echo "ERL_FILES = $(ERL_FILES)"
+ @echo "SOURCE = $(SOURCE)"
+ @echo "TARGET_FILES = $(TARGET_FILES)"
+ @echo ""
+ @echo "INETS_SPECS = $(INETS_SPECS)"
+ @echo "INETS_FILES = $(INETS_FILES)"
+ @echo ""
+ @echo "RELEASE_PATH = $(RELEASE_PATH)"
+ @echo "RELSYSDIR = $(RELSYSDIR)"
+ @echo "RELTESTSYSDIR = $(RELTESTSYSDIR)"
+ @echo "RELTESTSYSALLDATADIR = $(RELTESTSYSALLDATADIR)"
+ @echo "RELTESTSYSBINDIR = $(RELTESTSYSBINDIR)"
+ @echo ""
+ @echo "DATADIRS = $(DATADIRS)"
+ @echo "REL_DATADIRS = $(REL_DATADIRS)"
+ @echo ""
+ @echo "INETS_DATA_DIR = $(INETS_DATA_DIR)"
+ @echo "INETS_PRIV_DIR = $(INETS_PRIV_DIR)"
+ @echo "INETS_ROOT = $(INETS_ROOT)"
+ @echo "INETS_FLAGS = $(INETS_FLAGS)"
+ @echo "FTP_FLAGS = $(FTP_FLAGS)"
+
+tftp:
+ erlc $(ERL_COMPILE_FLAGS) tftp_test_lib.erl tftp_SUITE.erl && erl -pa ../../inets/ebin -s tftp_SUITE t -s erlang halt
+
+tftp_work:
+ echo "tftp_test_lib:t([{tftp_SUITE, all}])."
+ erlc $(ERL_COMPILE_FLAGS) tftp_test_lib.erl tftp_SUITE.erl && erl -pa ../../inets/ebin
diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl
new file mode 100644
index 0000000000..e7404f945b
--- /dev/null
+++ b/lib/inets/test/ftp_SUITE.erl
@@ -0,0 +1,143 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+% -export([init_per_testcase/2, end_per_testcase/2]).
+-export([init_per_suite/1, end_per_suite/1]).
+
+%% Test cases must be exported.
+-export([solaris8_test/1,
+ solaris9_test/1,
+ solaris10_test/1,
+ linux_x86_test/1,
+ linux_ppc_test/1,
+ macosx_x86_test/1,
+ macosx_ppc_test/1,
+ openbsd_test/1,
+ freebsd_test/1,
+ netbsd_test/1,
+ windows_xp_test/1,
+ windows_2003_server_test/1,
+ ticket_tests/1]).
+
+-define(FTP_USER, "anonymous").
+-define(FTP_PASS, passwd()).
+-define(FTP_PORT, 21).
+
+-define(BAD_HOST, "badhostname").
+-define(BAD_USER, "baduser").
+-define(BAD_DIR, "baddirectory").
+
+-ifdef(ftp_debug_client).
+-define(ftp_open(Host, Flags), do_ftp_open(Host, [debug] ++ Flags)).
+-else.
+-ifdef(ftp_trace_client).
+-define(ftp_open(Host, Flags), do_ftp_open(Host, [trace] ++ Flags)).
+-else.
+-define(ftp_open(Host, Flags), do_ftp_open(Host, [verbose] ++ Flags)).
+-endif.
+-endif.
+
+
+%%--------------------------------------------------------------------
+%% all(Arg) -> [Doc] | [Case] | {skip, Comment}
+%% Arg - doc | suite
+%% Doc - string()
+%% Case - atom()
+%% Name of a test case function.
+%% Comment - string()
+%% Description: Returns documentation/test cases in this test suite
+%% or a skip tuple if the platform is not supported.
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test the ftp client in the inets application."];
+all(suite) ->
+ [
+ solaris8_test,
+ solaris9_test,
+ solaris10_test,
+ linux_x86_test,
+ linux_ppc_test,
+ macosx_x86_test,
+ macosx_ppc_test,
+ openbsd_test,
+ freebsd_test,
+ netbsd_test,
+ windows_xp_test,
+ windows_2003_server_test,
+ ticket_tests
+ ].
+
+solaris8_test(suite) ->
+ [{ftp_solaris8_sparc_test,all}].
+solaris9_test(suite) ->
+ [{ftp_solaris9_sparc_test,all}].
+solaris10_test(suite) ->
+ [{ftp_solaris10_sparc_test,all}, {ftp_solaris10_x86_test,all}].
+linux_x86_test(suite) ->
+ [{ftp_linux_x86_test,all}].
+linux_ppc_test(suite) ->
+ [{ftp_linux_ppc_test,all}].
+macosx_x86_test(suite) ->
+ [{ftp_macosx_x86_test,all}].
+macosx_ppc_test(suite) ->
+ [{ftp_macosx_ppc_test,all}].
+openbsd_test(suite) ->
+ [{ftp_openbsd_x86_test,all}].
+freebsd_test(suite) ->
+ [{ftp_freebsd_x86_test,all}].
+netbsd_test(suite) ->
+ [{ftp_netbsd_x86_test,all}].
+windows_xp_test(suite) ->
+ [{ftp_windows_xp_test,all}].
+windows_2003_server_test(suite) ->
+ [{ftp_windows_2003_server_test,all}].
+
+ticket_tests(suite) ->
+ [{ftp_ticket_test, all}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ inets:start(),
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ inets:stop(),
+ ok.
diff --git a/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel
new file mode 100644
index 0000000000..75096ce687
--- /dev/null
+++ b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel
@@ -0,0 +1,18 @@
+%% Add a host name in the appropriate list
+%% Each "platform" contains a list of hostnames (a string) that can
+%% be used for testing the ftp client.
+%% The definition below are an example!!
+[{solaris8_sparc, ["solaris8_sparc_dummy1", "solaris8_sparc_dummy2"]},
+ {solaris9_sparc, ["solaris9_sparc_dummy1"]},
+ {solaris10_sparc, ["solaris10_sparc_dummy1"]},
+ {solaris10_x86, ["solaris10_x86_dummy1", "solaris10_x86_dummy2"]},
+ {linux_x86, ["linux_x86_dummy1", "linux_x86_dummy2"]},
+ {linux_ppc, ["linux_ppc_dummy1"]},
+ {macosx_ppc, ["macosx_ppc_dummy1"]},
+ {macosx_x86, ["macosx_x86_dummy1", "macosx_x86_dummy2"]},
+ {openbsd_x86, []},
+ {freebsd_x86, ["freebsd_x86_dummy1"]},
+ {netbsd_x86, []},
+ {windows_xp, []},
+ {windows_2003_server, ["win2003_dummy1"]},
+ {ticket_test, ["solaris8_x86_dummy1", "linux_x86_dummy1"]}].
diff --git a/lib/inets/test/ftp_format_SUITE.erl b/lib/inets/test/ftp_format_SUITE.erl
new file mode 100644
index 0000000000..9ca6575b2d
--- /dev/null
+++ b/lib/inets/test/ftp_format_SUITE.erl
@@ -0,0 +1,341 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(ftp_format_SUITE).
+-author('[email protected]').
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("ftp_internal.hrl").
+
+%% Test server specific exports
+-export([all/1, init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases must be exported.
+-export([ftp_response/1, ftp_150/1,
+ ftp_200/1, ftp_220/1, ftp_226/1, ftp_257/1, ftp_331/1, ftp_425/1,
+ ftp_other_status_codes/1, ftp_multiple_lines/1,
+ ftp_multipel_ctrl_messages/1, format_error/1]).
+
+all(doc) ->
+ ["Test library functions for the ftp client."];
+all(suite) ->
+ [ftp_response, format_error].
+
+init_per_testcase(_, Config) ->
+ Dog = test_server:timetrap(?t:minutes(1)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ [{watchdog, Dog} | NewConfig].
+
+end_per_testcase(_, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+ftp_response(doc) ->
+ ["Test ftp_response:parse_lines/3 and ftp_response:interpret/1."
+ " This test case will simulate that the "
+ "message will be recived a little at the time on a socket and the "
+ "package may be broken up into smaller parts at arbitrary point."];
+ftp_response(suite) ->
+ [ftp_150, ftp_200, ftp_220, ftp_226, ftp_257, ftp_331, ftp_425,
+ ftp_other_status_codes, ftp_multiple_lines, ftp_multipel_ctrl_messages].
+
+ftp_150(doc) ->
+ ["Especially check that respons can be devided in a random place."];
+ftp_150(suite) ->
+ [];
+ftp_150(Config) when is_list(Config) ->
+ FtpResponse = ["150 ASCII data conn", "ection for /bin/ls ",
+ "(134.138.177", ".89,50434) (0 bytes).\r\n"],
+
+ "150 ASCII data connection for /bin/ls "
+ "(134.138.177.89,50434) (0 bytes).\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_prel, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_200(doc) ->
+ ["Especially check that respons can be devided after the first status "
+ "code character and in the end delimiter."];
+ftp_200(suite) ->
+ [];
+ftp_200(Config) when is_list(Config) ->
+ FtpResponse = ["2", "00 PORT command successful.", [?CR], [?LF]],
+
+ "200 PORT command successful.\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_220(doc) ->
+ ["Especially check that respons can be devided after the "
+ "first with space "];
+ftp_220(suite) ->
+ [];
+ftp_220(Config) when is_list(Config) ->
+ FtpResponse = ["220 ","fingon FTP server (SunOS 5.8) ready.\r\n"],
+
+ "220 fingon FTP server (SunOS 5.8) ready.\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_226(doc) ->
+ ["Especially check that respons can be devided after second status code"
+ " character and in the end delimiter."];
+ftp_226(suite) ->
+ [];
+ftp_226(Config) when is_list(Config) ->
+ FtpResponse = ["22" "6 Transfer complete.\r", [?LF]],
+
+ "226 Transfer complete.\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_257(doc) ->
+ ["Especially check that quoted chars do not cause a problem."];
+ftp_257(suite) ->
+ [];
+ftp_257(Config) when is_list(Config) ->
+ FtpResponse = ["257 \"/\" is current directory.\r\n"],
+
+ "257 \"/\" is current directory.\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_331(doc) ->
+ ["Especially check that respons can be devided after the third status "
+ " status code character."];
+ftp_331(suite) ->
+ [];
+ftp_331(Config) when is_list(Config) ->
+ %% Brake before white space after code
+ FtpResponse =
+ ["331"," Guest login ok, send ient as password.\r\n"],
+
+ "331 Guest login ok, send ient as password.\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_interm, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_425(doc) ->
+ ["Especially check a message that was received in only one part."];
+ftp_425(suite) ->
+ [];
+ftp_425(Config) when is_list(Config) ->
+ FtpResponse =
+ ["425 Can't build data connection: Connection refused.\r\n"],
+
+ "425 Can't build data connection: Connection refused.\r\n"
+ = Msg = parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {trans_neg_compl, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_multiple_lines(doc) ->
+ ["Especially check multiple lines devided in significant places"];
+ftp_multiple_lines(suite) ->
+ [];
+ftp_multiple_lines(Config) when is_list(Config) ->
+ FtpResponse = ["21", "4","-The",
+ " following commands are recognized:\r\n"
+ " USER EPRT STRU MAIL* ALLO CWD",
+ " STAT* XRMD \r\n"
+ " PASS LPRT MODE MSND* "
+ " REST* XCWD HELP PWD ", [?CRLF],
+ " ACCT* EPSV RETR MSOM* RNFR LIST "
+ " NOOP XPWD \r\n",
+ " REIN* LPSV STOR MSAM* RNTO NLST "
+ " MKD CDUP \r\n"
+ " QUIT PASV APPE MRSQ* ABOR SITE* "
+ " XMKD XCUP \r\n"
+ " PORT TYPE MLFL* MRCP* DELE SYST "
+ " RMD STOU \r\n"
+ "214 (*'s => unimplemented)", [?CR], [?LF]],
+
+
+ FtpResponse1 = ["214-", "The",
+ " following commands are recognized:\r\n"
+ " USER EPRT STRU MAIL* ALLO CWD",
+ " STAT* XRMD \r\n"
+ " PASS LPRT MODE MSND* "
+ " REST* XCWD HELP PWD ", [?CRLF],
+ " ACCT* EPSV RETR MSOM* RNFR LIST "
+ " NOOP XPWD \r\n",
+ " REIN* LPSV STOR MSAM* RNTO NLST "
+ " MKD CDUP \r\n"
+ " QUIT PASV APPE MRSQ* ABOR SITE* "
+ " XMKD XCUP \r\n"
+ " PORT TYPE MLFL* MRCP* DELE SYST "
+ " RMD STOU \r\n"
+ "2", "14 (*'s => unimplemented)", [?CR], [?LF]],
+
+ FtpResponse2 = ["214-", "The",
+ " following commands are recognized:\r\n"
+ " USER EPRT STRU MAIL* ALLO CWD",
+ " STAT* XRMD \r\n"
+ " PASS LPRT MODE MSND* "
+ " REST* XCWD HELP PWD ", [?CRLF],
+ " ACCT* EPSV RETR MSOM* RNFR LIST "
+ " NOOP XPWD \r\n",
+ " REIN* LPSV STOR MSAM* RNTO NLST "
+ " MKD CDUP \r\n"
+ " QUIT PASV APPE MRSQ* ABOR SITE* "
+ " XMKD XCUP \r\n"
+ " PORT TYPE MLFL* MRCP* DELE SYST "
+ " RMD STOU \r\n"
+ "21", "4"," (*'s => unimplemented)", [?CR], [?LF]],
+
+ MultiLineResultStr =
+ "214-The following commands are recognized:\r\n"
+ " USER EPRT STRU MAIL* ALLO CWD STAT* "
+ "XRMD \r\n"
+ " PASS LPRT MODE MSND* REST* XCWD HELP "
+ "PWD \r\n"
+ " ACCT* EPSV RETR MSOM* RNFR LIST NOOP "
+ "XPWD \r\n"
+ " REIN* LPSV STOR MSAM* RNTO NLST MKD "
+ "CDUP \r\n"
+ " QUIT PASV APPE MRSQ* ABOR SITE* XMKD "
+ "XCUP \r\n"
+ " PORT TYPE MLFL* MRCP* DELE SYST RMD "
+ "STOU \r\n"
+ "214 (*'s => unimplemented)\r\n",
+
+ MultiLineResultStr =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(MultiLineResultStr),
+
+ MultiLineResultStr = parse(ftp_response, parse_lines, [[], start],
+ FtpResponse1),
+
+ MultiLineResultStr = parse(ftp_response, parse_lines, [[], start],
+ FtpResponse2),
+ ok.
+
+ftp_other_status_codes(doc) ->
+ ["Check that other valid status codes, than the ones above, are handled"
+ "by ftp_response:interpret/1. Note there are som ftp status codes"
+ "that will not be received with the current ftp instruction support,"
+ "they are not included here."];
+ftp_other_status_codes(suite) ->
+ [];
+ftp_other_status_codes(Config) when is_list(Config) ->
+
+ %% 1XX
+ {pos_prel, _ } = ftp_response:interpret("120 Foobar\r\n"),
+
+ %% 2XX
+ {pos_compl, _ } = ftp_response:interpret("202 Foobar\r\n"),
+ {pos_compl, _ } = ftp_response:interpret("221 Foobar\r\n"),
+ {pos_compl, _ } = ftp_response:interpret("227 Foobar\r\n"),
+ {pos_compl, _ } = ftp_response:interpret("230 Foobar\r\n"),
+ {pos_compl, _ } = ftp_response:interpret("250 Foobar\r\n"),
+
+ %% 3XX
+ {pos_interm_acct, _ } = ftp_response:interpret("332 Foobar\r\n"),
+ {pos_interm, _ } = ftp_response:interpret("350 Foobar\r\n"),
+
+ %% 4XX
+ {trans_neg_compl, _ } = ftp_response:interpret("421 Foobar\r\n"),
+ {trans_neg_compl, _ } = ftp_response:interpret("426 Foobar\r\n"),
+ {trans_neg_compl, _ } = ftp_response:interpret("450 Foobar\r\n"),
+ {trans_neg_compl, _ } = ftp_response:interpret("451 Foobar\r\n"),
+ {etnospc, _ } = ftp_response:interpret("452 Foobar\r\n"),
+
+ %% 5XX
+ {perm_neg_compl, _ } = ftp_response:interpret("500 Foobar\r\n"),
+ {perm_neg_compl, _ } = ftp_response:interpret("501 Foobar\r\n"),
+ {perm_neg_compl, _ } = ftp_response:interpret("503 Foobar\r\n"),
+ {perm_neg_compl, _ } = ftp_response:interpret("504 Foobar\r\n"),
+ {perm_neg_compl, _ } = ftp_response:interpret("530 Foobar\r\n"),
+ {perm_neg_compl, _ } = ftp_response:interpret("532 Foobar\r\n"),
+ {epath, _ } = ftp_response:interpret("550 Foobar\r\n"),
+ {epnospc, _ } = ftp_response:interpret("552 Foobar\r\n"),
+ {efnamena, _ } = ftp_response:interpret("553 Foobar\r\n"),
+ ok.
+
+ftp_multipel_ctrl_messages(doc) ->
+ ["The ftp server may send more than one control message as a reply,"
+ "check that they are handled one at the time."];
+ftp_multipel_ctrl_messages(suite) ->
+ [];
+ftp_multipel_ctrl_messages(Config) when is_list(Config) ->
+ FtpResponse = ["200 PORT command successful.\r\n200 Foobar\r\n"],
+
+ {"200 PORT command successful.\r\n" = Msg, NextMsg} =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(Msg),
+ NewMsg = parse(ftp_response, parse_lines, [[], start], NextMsg),
+ {pos_compl, _} = ftp_response:interpret(NewMsg),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+format_error(doc) ->
+ [""];
+format_error(suite) ->
+ [];
+format_error(Config) when is_list(Config) ->
+ "Synchronisation error during chunk sending." =
+ ftp:formaterror(echunk),
+ "Session has been closed." = ftp:formaterror(eclosed),
+ "Connection to remote server prematurely closed." =
+ ftp:formaterror(econn),
+ "File or directory already exists." = ftp:formaterror(eexists),
+ "Host not found, FTP server not found, or connection rejected." =
+ ftp:formaterror(ehost),
+ "User not logged in." = ftp:formaterror(elogin),
+ "Term is not a binary." = ftp:formaterror(enotbinary),
+ "No such file or directory, already exists, or permission denied."
+ = ftp:formaterror(epath),
+ "No such type." = ftp:formaterror(etype),
+ "User name or password not valid." = ftp:formaterror(euser),
+ "Insufficient storage space in system." = ftp:formaterror(etnospc),
+ "Exceeded storage allocation (for current directory or dataset)."
+ = ftp:formaterror(epnospc),
+ "File name not allowed." = ftp:formaterror(efnamena),
+ "Unknown error: foobar" = ftp:formaterror({error, foobar}).
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+parse(Module, Function, Args, Bin) when is_binary(Bin) ->
+ parse(Module, Function, Args, [binary_to_list(Bin)]);
+
+parse(Module, Function, [AccLines, StatusCode], [Data | Rest]) ->
+ case Module:Function(list_to_binary(Data), AccLines, StatusCode) of
+ {ok, Result, <<>>} ->
+ Result;
+ {ok, Result, Next} ->
+ {Result, Next};
+ {continue, {NewData, NewAccLines, NewStatusCode}} ->
+ case Rest of
+ [] ->
+ test_server:fail({wrong_input, Data, Rest});
+ [_ | _] ->
+ parse(Module, Function, [NewAccLines, NewStatusCode],
+ [binary_to_list(NewData) ++ hd(Rest) | tl(Rest)])
+ end
+ end.
diff --git a/lib/inets/test/ftp_freebsd_x86_test.erl b/lib/inets/test/ftp_freebsd_x86_test.erl
new file mode 100644
index 0000000000..457e18ffbe
--- /dev/null
+++ b/lib/inets/test/ftp_freebsd_x86_test.erl
@@ -0,0 +1,153 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_freebsd_x86_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Freebsd x86 ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(freebsd_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_internal.hrl b/lib/inets/test/ftp_internal.hrl
new file mode 120000
index 0000000000..af57081f14
--- /dev/null
+++ b/lib/inets/test/ftp_internal.hrl
@@ -0,0 +1 @@
+../src/ftp/ftp_internal.hrl \ No newline at end of file
diff --git a/lib/inets/test/ftp_linux_ppc_test.erl b/lib/inets/test/ftp_linux_ppc_test.erl
new file mode 100644
index 0000000000..ad38137678
--- /dev/null
+++ b/lib/inets/test/ftp_linux_ppc_test.erl
@@ -0,0 +1,151 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_linux_ppc_test).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Linux ppc ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(linux_ppc, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
diff --git a/lib/inets/test/ftp_linux_x86_test.erl b/lib/inets/test/ftp_linux_x86_test.erl
new file mode 100644
index 0000000000..b9c88d121a
--- /dev/null
+++ b/lib/inets/test/ftp_linux_x86_test.erl
@@ -0,0 +1,160 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_linux_x86_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Linux x86 ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(linux_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [
+ open,
+ open_port,
+ passive,
+ active,
+ api_missuse,
+ not_owner,
+ progress_report
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_macosx_ppc_test.erl b/lib/inets/test/ftp_macosx_ppc_test.erl
new file mode 100644
index 0000000000..cf548a73c0
--- /dev/null
+++ b/lib/inets/test/ftp_macosx_ppc_test.erl
@@ -0,0 +1,152 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_macosx_ppc_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Macosx ppc ").
+
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(macosx_ppc, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(_X) -> {skipped,"unknown error"}.%?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(_X) -> {skipped,"unknown error"}.%%?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_macosx_x86_test.erl b/lib/inets/test/ftp_macosx_x86_test.erl
new file mode 100644
index 0000000000..c59a992421
--- /dev/null
+++ b/lib/inets/test/ftp_macosx_x86_test.erl
@@ -0,0 +1,152 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_macosx_x86_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Macosx x86 ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(macosx_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_netbsd_x86_test.erl b/lib/inets/test/ftp_netbsd_x86_test.erl
new file mode 100644
index 0000000000..a5711b7bde
--- /dev/null
+++ b/lib/inets/test/ftp_netbsd_x86_test.erl
@@ -0,0 +1,152 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_netbsd_x86_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Netbsd x86 ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(netbsd_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_openbsd_x86_test.erl b/lib/inets/test/ftp_openbsd_x86_test.erl
new file mode 100644
index 0000000000..4833b6332b
--- /dev/null
+++ b/lib/inets/test/ftp_openbsd_x86_test.erl
@@ -0,0 +1,151 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_openbsd_x86_test).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Openbsd x86 ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(openbsd_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
diff --git a/lib/inets/test/ftp_solaris10_sparc_test.erl b/lib/inets/test/ftp_solaris10_sparc_test.erl
new file mode 100644
index 0000000000..6066195f9b
--- /dev/null
+++ b/lib/inets/test/ftp_solaris10_sparc_test.erl
@@ -0,0 +1,154 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_solaris10_sparc_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Solaris 10 sparc ").
+
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(solaris10_sparc, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_solaris10_x86_test.erl b/lib/inets/test/ftp_solaris10_x86_test.erl
new file mode 100644
index 0000000000..3bd99fc3f2
--- /dev/null
+++ b/lib/inets/test/ftp_solaris10_x86_test.erl
@@ -0,0 +1,155 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_solaris10_x86_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD, ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_), ?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM, "Solaris 10 x86 ").
+
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(solaris10_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_solaris8_sparc_test.erl b/lib/inets/test/ftp_solaris8_sparc_test.erl
new file mode 100644
index 0000000000..9764071cd9
--- /dev/null
+++ b/lib/inets/test/ftp_solaris8_sparc_test.erl
@@ -0,0 +1,152 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_solaris8_sparc_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Solaris 8 sparc ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(solaris8_sparc, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_solaris9_sparc_test.erl b/lib/inets/test/ftp_solaris9_sparc_test.erl
new file mode 100644
index 0000000000..a9f77bbdac
--- /dev/null
+++ b/lib/inets/test/ftp_solaris9_sparc_test.erl
@@ -0,0 +1,151 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_solaris9_sparc_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Solaris 9 sparc ").
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(solaris9_sparc, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl
new file mode 100644
index 0000000000..75e1a5a7f9
--- /dev/null
+++ b/lib/inets/test/ftp_suite_lib.erl
@@ -0,0 +1,1593 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_suite_lib).
+
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("inets_test_lib.hrl").
+
+%% Test server specific exports
+% -export([init_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+
+-record(progress, {
+ current = 0,
+ total
+ }).
+
+
+
+-define(FTP_USER, "anonymous").
+-define(FTP_PASS, passwd()).
+-define(FTP_PORT, 21).
+
+-define(BAD_HOST, "badhostname").
+-define(BAD_USER, "baduser").
+-define(BAD_DIR, "baddirectory").
+
+-ifdef(ftp_debug_client).
+-define(ftp_open(Host, Flags),
+ do_ftp_open(Host, [debug, {timeout, timer:seconds(15)}] ++ Flags)).
+-else.
+-ifdef(ftp_trace_client).
+-define(ftp_open(Host, Flags),
+ do_ftp_open(Host, [trace, {timeout, timer:seconds(15)}] ++ Flags)).
+-else.
+-define(ftp_open(Host, Flags),
+ do_ftp_open(Host, [verbose, {timeout, timer:seconds(15)}] ++ Flags)).
+-endif.
+-endif.
+
+%% -- Tickets --
+
+tickets(doc) ->
+ "Test cases for reported bugs";
+tickets(suite) ->
+ [ticket_6035].
+
+%% --
+
+ftpd_init(FtpdTag, Config) ->
+ %% Get the host name(s) of FTP server
+ Hosts =
+ case ?config(ftpd_hosts, Config) of
+ undefined ->
+ ftpd_hosts(data_dir(Config));
+ H ->
+ H
+ end,
+ p("ftpd_init -> "
+ "~n Hosts: ~p"
+ "~n Config: ~p"
+ "~n FtpdTag: ~p", [Hosts, Config, FtpdTag]),
+ %% Get the first host that actually have a running FTP server
+ case lists:keysearch(FtpdTag, 1, Hosts) of
+ {value, {_, TagHosts}} when is_list(TagHosts) ->
+ inets:start(),
+ case (catch get_ftpd_host(TagHosts)) of
+ {ok, Host} ->
+ inets:stop(),
+ [{ftp_remote_host, Host}|Config];
+ _ ->
+ inets:stop(),
+ Reason = lists:flatten(
+ io_lib:format("Could not find a valid "
+ "FTP server for ~p (~p)",
+ [FtpdTag, TagHosts])),
+ {skip, Reason}
+ end;
+ _ ->
+ Reason = lists:flatten(
+ io_lib:format("No host(s) running FTPD server "
+ "for ~p", [FtpdTag])),
+ {skip, Reason}
+ end.
+
+ftpd_fin(Config) ->
+ lists:keydelete(ftp_remote_host, 1, Config).
+
+get_ftpd_host([]) ->
+ {error, no_host};
+get_ftpd_host([Host|Hosts]) ->
+ p("get_ftpd_host -> entry with"
+ "~n Host: ~p"
+ "~n", [Host]),
+ case (catch ftp:open({option_list,
+ [{host, Host}, {port, ?FTP_PORT},
+ {timeout, 20000}]})) of
+ {ok, Pid} ->
+ (catch ftp:close(Pid)),
+ {ok, Host};
+ _ ->
+ get_ftpd_host(Hosts)
+ end.
+
+
+%%--------------------------------------------------------------------
+
+dirty_select_ftpd_host(Config) ->
+ Hosts =
+ case ?config(ftpd_hosts, Config) of
+ undefined ->
+ ftpd_hosts(data_dir(Config));
+ H ->
+ H
+ end,
+ dirty_select_ftpd_host2(Hosts).
+
+dirty_select_ftpd_host2([]) ->
+ throw({error, not_found});
+dirty_select_ftpd_host2([{PlatformTag, Hosts} | PlatformHosts]) ->
+ case dirty_select_ftpd_host3(Hosts) of
+ none ->
+ dirty_select_ftpd_host2(PlatformHosts);
+ {ok, Host} ->
+ {PlatformTag, Host}
+ end.
+
+dirty_select_ftpd_host3([]) ->
+ none;
+dirty_select_ftpd_host3([Host|Hosts]) when is_list(Host) ->
+ case dirty_select_ftpd_host4(Host) of
+ true ->
+ {ok, Host};
+ false ->
+ dirty_select_ftpd_host3(Hosts)
+ end;
+dirty_select_ftpd_host3([_|Hosts]) ->
+ dirty_select_ftpd_host3(Hosts).
+
+%% This is a very simple and dirty test that there is a
+%% (FTP) deamon on the other end.
+dirty_select_ftpd_host4(Host) ->
+ Port = 21,
+ IpFam = inet,
+ Opts = [IpFam, binary, {packet, 0}, {active, false}],
+ Timeout = ?SECS(5),
+ case gen_tcp:connect(Host, Port, Opts, Timeout) of
+ {ok, Sock} ->
+ gen_tcp:close(Sock),
+ true;
+ _Error ->
+ false
+ end.
+
+
+%%--------------------------------------------------------------------
+
+test_filenames() ->
+ {ok, Host} = inet:gethostname(),
+ File = Host ++ "_ftp_test.txt",
+ NewFile = "new_" ++ File,
+ {File, NewFile}.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config)
+ when (Case =:= open) orelse (Case =:= open_port) ->
+ io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
+ inets:start(),
+ NewConfig = data_dir(Config),
+ watch_dog(NewConfig);
+
+init_per_testcase(Case, Config) ->
+ put(ftp_testcase, Case),
+ inets:enable_trace(max, io, ftpc),
+ do_init_per_testcase(Case, Config).
+
+do_init_per_testcase(Case, Config)
+ when (Case =:= passive_user) ->
+ io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE,Case]),
+ inets:start(),
+ NewConfig = close_connection(watch_dog(Config)),
+ Host = ftp_host(Config),
+ case (catch ?ftp_open(Host, [])) of
+ {ok, Pid} ->
+ [{ftp, Pid} | data_dir(NewConfig)];
+ {skip, _} = SKIP ->
+ SKIP
+ end;
+
+do_init_per_testcase(Case, Config)
+ when (Case =:= active_user) ->
+ io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
+ inets:start(),
+ NewConfig = close_connection(watch_dog(Config)),
+ Host = ftp_host(Config),
+ case (catch ?ftp_open(Host, [])) of
+ {ok, Pid} ->
+ ok = ftp:force_active(Pid),
+ [{ftp, Pid} | data_dir(NewConfig)];
+ {skip, _} = SKIP ->
+ SKIP
+ end;
+
+do_init_per_testcase(Case, Config)
+ when (Case =:= progress_report_send) orelse
+ (Case =:= progress_report_recv) ->
+ inets:start(),
+ io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
+ NewConfig = close_connection(watch_dog(Config)),
+ Host = ftp_host(Config),
+ Opts = [{host, Host},
+ {port, ?FTP_PORT},
+ {flags, [verbose]},
+ {progress, {?MODULE, progress, #progress{}}}],
+ case ftp:open({option_list, Opts}) of
+ {ok, Pid} ->
+ ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS),
+ [{ftp, Pid} | data_dir(NewConfig)];
+ {skip, _} = SKIP ->
+ SKIP
+ end;
+
+do_init_per_testcase(Case, Config) ->
+ io:format(user,"~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
+ inets:start(),
+ NewConfig = close_connection(watch_dog(Config)),
+ Host = ftp_host(Config),
+ Flags =
+ if
+ ((Case =:= passive_ip_v6_disabled) orelse
+ (Case =:= active_ip_v6_disabled)) ->
+ [ip_v6_disabled];
+ true ->
+ []
+ end,
+ case (catch ?ftp_open(Host, Flags)) of
+ {ok, Pid} ->
+ case string:tokens(atom_to_list(Case), [$_]) of
+ [_, "active"|_] ->
+ ok = ftp:force_active(Pid);
+ _ ->
+ ok
+ end,
+ ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS),
+ [{ftp, Pid} | data_dir(NewConfig)];
+ {skip, _} = SKIP ->
+ SKIP
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(_, Config) ->
+ NewConfig = close_connection(Config),
+ Dog = ?config(watchdog, NewConfig),
+ inets:stop(),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+%% Suites similar for all hosts.
+%%-------------------------------------------------------------------------
+
+passive(suite) ->
+ [
+ passive_user,
+ passive_pwd,
+ passive_cd,
+ passive_lcd,
+ passive_ls,
+ passive_nlist,
+ passive_rename,
+ passive_delete,
+ passive_mkdir,
+ passive_send,
+ passive_send_bin,
+ passive_send_chunk,
+ passive_append,
+ passive_append_bin,
+ passive_append_chunk,
+ passive_recv,
+ passive_recv_bin,
+ passive_recv_chunk,
+ passive_type,
+ passive_quote,
+ passive_ip_v6_disabled
+ ].
+
+active(suite) ->
+ [
+ active_user,
+ active_pwd,
+ active_cd,
+ active_lcd,
+ active_ls,
+ active_nlist,
+ active_rename,
+ active_delete,
+ active_mkdir,
+ active_send,
+ active_send_bin,
+ active_send_chunk,
+ active_append,
+ active_append_bin,
+ active_append_chunk,
+ active_recv,
+ active_recv_bin,
+ active_recv_chunk,
+ active_type,
+ active_quote,
+ active_ip_v6_disabled
+ ].
+
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+
+open(doc) ->
+ ["Open an ftp connection to a host and close the connection."
+ "Also check that !-messages does not disturbe the connection"];
+open(suite) ->
+ [];
+open(Config) when is_list(Config) ->
+ Host = ftp_host(Config),
+ (catch tc_open(Host)).
+
+tc_open(Host) ->
+ {ok, Pid} = ?ftp_open(Host, []),
+ ok = ftp:close(Pid),
+ {ok, Pid1} =
+ ftp:open({option_list, [{host,Host},
+ {port, ?FTP_PORT},
+ {flags, [verbose]},
+ {timeout, 30000}]}),
+ ok = ftp:close(Pid1),
+ {error, ehost} = ftp:open({option_list, [{port, ?FTP_PORT},
+ {flags, [verbose]}]}),
+ {ok, Pid2} = ftp:open(Host),
+ ok = ftp:close(Pid2),
+
+ {ok, NewHost} = inet:getaddr(Host, inet),
+ {ok, Pid3} = ftp:open(NewHost),
+ ftp:user(Pid3, ?FTP_USER, ?FTP_PASS),
+ Pid3 ! foobar,
+ test_server:sleep(5000),
+ {message_queue_len, 0} = process_info(self(), message_queue_len),
+ ["200" ++ _] = ftp:quote(Pid3, "NOOP"),
+ ok = ftp:close(Pid3),
+
+ %% Bad input that has default values are ignored and the defult
+ %% is used.
+ {ok, Pid4} =
+ ftp:open({option_list, [{host, Host}, {port, badarg},
+ {flags, [verbose]},
+ {timeout, 30000}]}),
+ test_server:sleep(100),
+ ok = ftp:close(Pid4),
+ {ok, Pid5} =
+ ftp:open({option_list, [{host, Host}, {port, ?FTP_PORT},
+ {flags, [verbose]},
+ {timeout, -42}]}),
+ test_server:sleep(100),
+ ok = ftp:close(Pid5),
+ {ok, Pid6} =
+ ftp:open({option_list, [{host, Host}, {port, ?FTP_PORT},
+ {flags, [verbose]},
+ {mode, cool}]}),
+ test_server:sleep(100),
+ ok = ftp:close(Pid6),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+open_port(doc) ->
+ ["Open an ftp connection to a host with given port number "
+ "and close the connection."]; % See also OTP-3892
+open_port(suite) ->
+ [];
+open_port(Config) when is_list(Config) ->
+ Host = ftp_host(Config),
+ {ok, Pid} = ftp:open(Host, ?FTP_PORT),
+ ok = ftp:close(Pid),
+ {error, ehost} = ftp:open(?BAD_HOST, []),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+passive_user(doc) ->
+ ["Open an ftp connection to a host, and logon as anonymous ftp."];
+passive_user(suite) ->
+ [];
+passive_user(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ io:format("Pid: ~p~n",[Pid]),
+ do_user(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_pwd(doc) ->
+ ["Test ftp:pwd/1 & ftp:lpwd/1"];
+passive_pwd(suite) ->
+ [];
+passive_pwd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_pwd(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_cd(doc) ->
+ ["Open an ftp connection, log on as anonymous ftp, and cd to the"
+ "directory \"/pub\" and the to the non-existent directory."];
+passive_cd(suite) ->
+ [];
+passive_cd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_cd(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_lcd(doc) ->
+ ["Test api function ftp:lcd/2"];
+passive_lcd(suite) ->
+ [];
+passive_lcd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ PrivDir = ?config(priv_dir, Config),
+ do_lcd(Pid, PrivDir).
+
+
+%%-------------------------------------------------------------------------
+
+passive_ls(doc) ->
+ ["Open an ftp connection; ls the current directory, and the "
+ "\"incoming\" directory. We assume that ls never fails, since "
+ "it's output is meant to be read by humans. "];
+passive_ls(suite) ->
+ [];
+passive_ls(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_ls(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_nlist(doc) ->
+ ["Open an ftp connection; nlist the current directory, and the "
+ "\"incoming\" directory. Nlist does not behave consistenly over "
+ "operating systems. On some it is an error to have an empty "
+ "directory."];
+passive_nlist(suite) ->
+ [];
+passive_nlist(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_nlist(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_rename(doc) ->
+ ["Transfer a file to the server, and rename it; then remove it."];
+passive_rename(suite) ->
+ [];
+passive_rename(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_rename(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_delete(doc) ->
+ ["Transfer a file to the server, and then delete it"];
+passive_delete(suite) ->
+ [];
+passive_delete(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_delete(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_mkdir(doc) ->
+ ["Make a remote directory, cd to it, go to parent directory, and "
+ "remove the directory."];
+passive_mkdir(suite) ->
+ [];
+passive_mkdir(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_mkdir(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_send(doc) ->
+ ["Create a local file in priv_dir; open an ftp connection to a host; "
+ "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
+ "priv_dir; send the file; get a directory listing and check that "
+ "the file is on the list;, delete the remote file; get another listing "
+ "and check that the file is not on the list; close the session; "
+ "delete the local file."];
+passive_send(suite) ->
+ [];
+passive_send(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_append(doc) ->
+ ["Create a local file in priv_dir; open an ftp connection to a host; "
+ "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
+ "priv_dir; append the file to a file at the remote side that not exits"
+ "this will create the file at the remote side. Then it append the file "
+ "again. When this is done it recive the remote file and control that"
+ "the content is doubled in it.After that it will remove the files"];
+passive_append(suite) ->
+ [];
+passive_append(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_send_bin(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "send a binary; remove file; close the connection."];
+passive_send_bin(suite) ->
+ [];
+passive_send_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send_bin(Pid, Config).
+
+%%-------------------------------------------------------------------------
+
+passive_append_bin(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "append a binary twice; get the file and compare the content"
+ "remove file; close the connection."];
+passive_append_bin(suite) ->
+ [];
+passive_append_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append_bin(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_send_chunk(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "send chunks; remove file; close the connection."];
+passive_send_chunk(suite) ->
+ [];
+passive_send_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_append_chunk(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "append chunks;control content remove file; close the connection."];
+passive_append_chunk(suite) ->
+ [];
+passive_append_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_recv(doc) ->
+ ["Create a local file and transfer it to the remote host into the "
+ "the \"incoming\" directory, remove "
+ "the local file. Then open a new connection; cd to \"incoming\", "
+ "lcd to the private directory; receive the file; delete the "
+ "remote file; close connection; check that received file is in "
+ "the correct directory; cleanup." ];
+passive_recv(suite) ->
+ [];
+passive_recv(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_recv_bin(doc) ->
+ ["Send a binary to the remote host; and retreive "
+ "the file; then remove the file."];
+passive_recv_bin(suite) ->
+ [];
+passive_recv_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv_bin(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_recv_chunk(doc) ->
+ ["Send a binary to the remote host; Connect again, and retreive "
+ "the file; then remove the file."];
+passive_recv_chunk(suite) ->
+ [];
+passive_recv_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_type(doc) ->
+ ["Test that we can change btween ASCCI and binary transfer mode"];
+passive_type(suite) ->
+ [];
+passive_type(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_type(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_quote(doc) ->
+ [""];
+passive_quote(suite) ->
+ [];
+passive_quote(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_quote(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_ip_v6_disabled(doc) ->
+ ["Test ipv4 command PASV"];
+passive_ip_v6_disabled(suite) ->
+ [];
+passive_ip_v6_disabled(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_user(doc) ->
+ ["Open an ftp connection to a host, and logon as anonymous ftp."];
+active_user(suite) ->
+ [];
+active_user(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_user(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_pwd(doc) ->
+ ["Test ftp:pwd/1 & ftp:lpwd/1"];
+active_pwd(suite) ->
+ [];
+active_pwd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_pwd(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_cd(doc) ->
+ ["Open an ftp connection, log on as anonymous ftp, and cd to the"
+ "directory \"/pub\" and to a non-existent directory."];
+active_cd(suite) ->
+ [];
+active_cd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_cd(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_lcd(doc) ->
+ ["Test api function ftp:lcd/2"];
+active_lcd(suite) ->
+ [];
+active_lcd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ PrivDir = ?config(priv_dir, Config),
+ do_lcd(Pid, PrivDir).
+
+
+%%-------------------------------------------------------------------------
+
+active_ls(doc) ->
+ ["Open an ftp connection; ls the current directory, and the "
+ "\"incoming\" directory. We assume that ls never fails, since "
+ "it's output is meant to be read by humans. "];
+active_ls(suite) ->
+ [];
+active_ls(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_ls(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_nlist(doc) ->
+ ["Open an ftp connection; nlist the current directory, and the "
+ "\"incoming\" directory. Nlist does not behave consistenly over "
+ "operating systems. On some it is an error to have an empty "
+ "directory."];
+active_nlist(suite) ->
+ [];
+active_nlist(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_nlist(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_rename(doc) ->
+ ["Transfer a file to the server, and rename it; then remove it."];
+active_rename(suite) ->
+ [];
+active_rename(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_rename(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_delete(doc) ->
+ ["Transfer a file to the server, and then delete it"];
+active_delete(suite) ->
+ [];
+active_delete(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_delete(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_mkdir(doc) ->
+ ["Make a remote directory, cd to it, go to parent directory, and "
+ "remove the directory."];
+active_mkdir(suite) ->
+ [];
+active_mkdir(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_mkdir(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_send(doc) ->
+ ["Create a local file in priv_dir; open an ftp connection to a host; "
+ "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
+ "priv_dir; send the file; get a directory listing and check that "
+ "the file is on the list;, delete the remote file; get another listing "
+ "and check that the file is not on the list; close the session; "
+ "delete the local file."];
+active_send(suite) ->
+ [];
+active_send(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_append(doc) ->
+ ["Create a local file in priv_dir; open an ftp connection to a host; "
+ "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
+ "priv_dir; append the file to a file at the remote side that not exits"
+ "this will create the file at the remote side. Then it append the file "
+ "again. When this is done it recive the remote file and control that"
+ "the content is doubled in it.After that it will remove the files"];
+active_append(suite) ->
+ [];
+active_append(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_send_bin(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "send a binary; remove file; close the connection."];
+active_send_bin(suite) ->
+ [];
+active_send_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send_bin(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_append_bin(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "append a binary twice; get the file and compare the content"
+ "remove file; close the connection."];
+active_append_bin(suite) ->
+ [];
+active_append_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append_bin(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_send_chunk(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "send chunks; remove file; close the connection."];
+active_send_chunk(suite) ->
+ [];
+active_send_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_append_chunk(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "append chunks;control content remove file; close the connection."];
+active_append_chunk(suite) ->
+ [];
+active_append_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_recv(doc) ->
+ ["Create a local file and transfer it to the remote host into the "
+ "the \"incoming\" directory, remove "
+ "the local file. Then open a new connection; cd to \"incoming\", "
+ "lcd to the private directory; receive the file; delete the "
+ "remote file; close connection; check that received file is in "
+ "the correct directory; cleanup." ];
+active_recv(suite) ->
+ [];
+active_recv(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_recv_bin(doc) ->
+ ["Send a binary to the remote host; and retreive "
+ "the file; then remove the file."];
+active_recv_bin(suite) ->
+ [];
+active_recv_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv_bin(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_recv_chunk(doc) ->
+ ["Send a binary to the remote host; Connect again, and retreive "
+ "the file; then remove the file."];
+active_recv_chunk(suite) ->
+ [];
+active_recv_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_type(doc) ->
+ ["Test that we can change btween ASCCI and binary transfer mode"];
+active_type(suite) ->
+ [];
+active_type(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_type(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_quote(doc) ->
+ [""];
+active_quote(suite) ->
+ [];
+active_quote(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_quote(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_ip_v6_disabled(doc) ->
+ ["Test ipv4 command PORT"];
+active_ip_v6_disabled(suite) ->
+ [];
+active_ip_v6_disabled(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+api_missuse(doc)->
+ ["Test that behaviour of the ftp process if the api is abused"];
+api_missuse(suite) -> [];
+api_missuse(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ Host = ftp_host(Config),
+
+ %% Serious programming fault, connetion will be shut down
+ {error, {connection_terminated, 'API_violation'}} =
+ gen_server:call(Pid, {self(), foobar, 10}, infinity),
+ test_server:sleep(500),
+ undefined = process_info(Pid, status),
+
+ {ok, Pid2} = ?ftp_open(Host, []),
+ %% Serious programming fault, connetion will be shut down
+ gen_server:cast(Pid2, {self(), foobar, 10}),
+ test_server:sleep(500),
+ undefined = process_info(Pid2, status),
+
+ {ok, Pid3} = ?ftp_open(Host, []),
+ %% Could be an innocent misstake the connection lives.
+ Pid3 ! foobar,
+ test_server:sleep(500),
+ {status, _} = process_info(Pid3, status),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+not_owner(doc) ->
+ ["Test what happens if a process that not owns the connection tries "
+ "to use it"];
+not_owner(suite) ->
+ [];
+not_owner(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ OtherPid = spawn_link(?MODULE, not_owner, [Pid, self()]),
+
+ receive
+ {OtherPid, ok} ->
+ {ok, _} = ftp:pwd(Pid)
+ end,
+ ok.
+
+not_owner(FtpPid, Pid) ->
+ {error, not_connection_owner} = ftp:pwd(FtpPid),
+ ftp:close(FtpPid),
+ test_server:sleep(100),
+ Pid ! {self(), ok}.
+
+
+%%-------------------------------------------------------------------------
+
+
+progress_report(doc) ->
+ ["Solaris 8 sparc test the option progress."];
+progress_report(suite) ->
+ [progress_report_send, progress_report_recv].
+
+
+%% --
+
+progress_report_send(doc) ->
+ ["Test the option progress for ftp:send/[2,3]"];
+progress_report_send(suite) ->
+ [];
+progress_report_send(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ ReportPid =
+ spawn_link(?MODULE, progress_report_receiver_init, [self(), 1]),
+ do_send(Pid, Config),
+ receive
+ {ReportPid, ok} ->
+ ok
+ end.
+
+
+%% --
+
+progress_report_recv(doc) ->
+ ["Test the option progress for ftp:recv/[2,3]"];
+progress_report_recv(suite) ->
+ [];
+progress_report_recv(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ ReportPid =
+ spawn_link(?MODULE, progress_report_receiver_init, [self(), 3]),
+ do_recv(Pid, Config),
+ receive
+ {ReportPid, ok} ->
+ ok
+ end,
+ ok.
+
+progress(#progress{} = Progress , _File, {file_size, Total}) ->
+ progress_report_receiver ! start,
+ Progress#progress{total = Total};
+progress(#progress{total = Total, current = Current}
+ = Progress, _File, {transfer_size, 0}) ->
+ progress_report_receiver ! finish,
+ case Total of
+ unknown ->
+ ok;
+ Current ->
+ ok;
+ _ ->
+ test_server:fail({error, {progress, {total, Total},
+ {current, Current}}})
+ end,
+ Progress;
+progress(#progress{current = Current} = Progress, _File,
+ {transfer_size, Size}) ->
+ progress_report_receiver ! update,
+ Progress#progress{current = Current + Size}.
+
+progress_report_receiver_init(Pid, N) ->
+ register(progress_report_receiver, self()),
+ receive
+ start ->
+ ok
+ end,
+ progress_report_receiver_loop(Pid, N-1).
+
+progress_report_receiver_loop(Pid, N) ->
+ receive
+ update ->
+ progress_report_receiver_loop(Pid, N);
+ finish when N =:= 0 ->
+ Pid ! {self(), ok};
+ finish ->
+ Pid ! {self(), ok},
+ receive
+ start ->
+ ok
+ end,
+ progress_report_receiver_loop(Pid, N-1)
+ end.
+
+
+%%-------------------------------------------------------------------------
+%% Ticket test cases
+%%-------------------------------------------------------------------------
+
+ticket_6035(doc) -> ["Test that owning process that exits with reason "
+ "'shutdown' does not cause an error message."];
+ticket_6035(suite) -> [];
+ticket_6035(Config) ->
+ p("ticket_6035 -> entry with"
+ "~n Config: ~p", [Config]),
+ PrivDir = ?config(priv_dir, Config),
+ LogFile = filename:join([PrivDir,"ticket_6035.log"]),
+ try
+ begin
+ Host = dirty_select_ftpd_host(Config),
+ Pid = spawn(?MODULE, open_wait_6035, [Host, self()]),
+ error_logger:logfile({open, LogFile}),
+ ok = kill_ftp_proc_6035(Pid,LogFile),
+ error_logger:logfile(close),
+ p("ticket_6035 -> done", []),
+ ok
+ end
+ catch
+ throw:{error, not_found} ->
+ {skip, "No available FTP servers"}
+ end.
+
+kill_ftp_proc_6035(Pid, LogFile) ->
+ p("kill_ftp_proc_6035 -> entry"),
+ receive
+ open ->
+ p("kill_ftp_proc_6035 -> received open: send shutdown"),
+ exit(Pid, shutdown),
+ kill_ftp_proc_6035(Pid, LogFile);
+ {open_failed, Reason} ->
+ p("kill_ftp_proc_6035 -> received open_failed"
+ "~n Reason: ~p", [Reason]),
+ exit({skip, {failed_openening_server_connection, Reason}})
+ after
+ 5000 ->
+ p("kill_ftp_proc_6035 -> timeout"),
+ is_error_report_6035(LogFile)
+ end.
+
+open_wait_6035(FtpServer, From) ->
+ p("open_wait_6035 -> try connect to ~s", [FtpServer]),
+ case ftp:open(FtpServer, [{timeout, timer:seconds(15)}]) of
+ {ok, Pid} ->
+ p("open_wait_6035 -> connected, now login"),
+ LoginResult = ftp:user(Pid,"anonymous","kldjf"),
+ p("open_wait_6035 -> login result: ~p", [LoginResult]),
+ From ! open,
+ receive
+ dummy ->
+ p("open_wait_6035 -> received dummy"),
+ ok
+ after
+ 10000 ->
+ p("open_wait_6035 -> timeout"),
+ ok
+ end,
+ p("open_wait_6035 -> done(ok)"),
+ ok;
+ {error, Reason} ->
+ p("open_wait_6035 -> open failed"
+ "~n Reason: ~p", [Reason]),
+ From ! {open_failed, {Reason, FtpServer}},
+ p("open_wait_6035 -> done(error)"),
+ ok
+ end.
+
+is_error_report_6035(LogFile) ->
+ p("is_error_report_6035 -> entry"),
+ Res =
+ case file:read_file(LogFile) of
+ {ok, Bin} ->
+ p("is_error_report_6035 -> logfile read"),
+ read_log_6035(binary_to_list(Bin));
+ _ ->
+ ok
+ end,
+ p("is_error_report_6035 -> logfile read result: "
+ "~n ~p", [Res]),
+ file:delete(LogFile),
+ Res.
+
+read_log_6035("=ERROR REPORT===="++_Rest) ->
+ error_report;
+read_log_6035([_H|T]) ->
+ read_log_6035(T);
+read_log_6035([]) ->
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+do_user(Pid) ->
+ {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS),
+ ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS),
+ ok.
+
+do_pwd(Pid) ->
+ {ok, "/"} = ftp:pwd(Pid),
+ {ok, Path} = ftp:lpwd(Pid),
+ {ok, Path} = file:get_cwd(),
+ ok.
+
+do_cd(Pid) ->
+ ok = ftp:cd(Pid, "/pub"),
+ {error, epath} = ftp:cd(Pid, ?BAD_DIR),
+ ok.
+
+do_lcd(Pid, Dir) ->
+ ok = ftp:lcd(Pid, Dir),
+ {error, epath} = ftp:lcd(Pid, ?BAD_DIR),
+ ok.
+
+
+do_ls(Pid) ->
+ {ok, _} = ftp:ls(Pid),
+ {ok, _} = ftp:ls(Pid, "incoming"),
+ %% neither nlist nor ls operates on a directory
+ %% they operate on a pathname, which *can* be a
+ %% directory, but can also be a filename or a group
+ %% of files (including wildcards).
+ {ok, _} = ftp:ls(Pid, "incom*"),
+ ok.
+
+do_nlist(Pid) ->
+ {ok, _} = ftp:nlist(Pid),
+ {ok, _} = ftp:nlist(Pid, "incoming"),
+ %% neither nlist nor ls operates on a directory
+ %% they operate on a pathname, which *can* be a
+ %% directory, but can also be a filename or a group
+ %% of files (including wildcards).
+ {ok, _} = ftp:nlist(Pid, "incom*"),
+%% {error, epath} = ftp:nlist(Pid, ?BAD_DIR),
+ ok.
+
+do_rename(Pid, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LFile = ?config(file, Config),
+ NewLFile = ?config(new_file, Config),
+ AbsLFile = filename:absname(LFile, PrivDir),
+ Contents = "ftp_SUITE test ...",
+ ok = file:write_file(AbsLFile, list_to_binary(Contents)),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:lcd(Pid, PrivDir),
+ ftp:delete(Pid, LFile), % reset
+ ftp:delete(Pid, NewLFile), % reset
+ ok = ftp:send(Pid, LFile),
+ {error, epath} = ftp:rename(Pid, NewLFile, LFile),
+ ok = ftp:rename(Pid, LFile, NewLFile),
+ ftp:delete(Pid, LFile), % cleanup
+ ftp:delete(Pid, NewLFile), % cleanup
+ ok.
+
+do_delete(Pid, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LFile = ?config(file, Config),
+ AbsLFile = filename:absname(LFile, PrivDir),
+ Contents = "ftp_SUITE test ...",
+ ok = file:write_file(AbsLFile, list_to_binary(Contents)),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:lcd(Pid, PrivDir),
+ ftp:delete(Pid,LFile), % reset
+ ok = ftp:send(Pid, LFile),
+ ok = ftp:delete(Pid,LFile),
+ ok.
+
+do_mkdir(Pid) ->
+ {A, B, C} = erlang:now(),
+ NewDir = "nisse_" ++ integer_to_list(A) ++ "_" ++
+ integer_to_list(B) ++ "_" ++ integer_to_list(C),
+ ok = ftp:cd(Pid, "incoming"),
+ {ok, CurrDir} = ftp:pwd(Pid),
+ ok = ftp:mkdir(Pid, NewDir),
+ ok = ftp:cd(Pid, NewDir),
+ ok = ftp:cd(Pid, CurrDir),
+ ok = ftp:rmdir(Pid, NewDir),
+ ok.
+
+do_send(Pid, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LFile = ?config(file, Config),
+ RFile = LFile ++ ".remote",
+ AbsLFile = filename:absname(LFile, PrivDir),
+ Contents = "ftp_SUITE test ...",
+ ok = file:write_file(AbsLFile, list_to_binary(Contents)),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:lcd(Pid, PrivDir),
+ ok = ftp:send(Pid, LFile, RFile),
+ {ok, RFilesString} = ftp:nlist(Pid),
+ RFiles = split(RFilesString),
+ true = lists:member(RFile, RFiles),
+ ok = ftp:delete(Pid, RFile),
+ case ftp:nlist(Pid) of
+ {error, epath} ->
+ ok; % No files
+ {ok, RFilesString1} ->
+ RFiles1 = split(RFilesString1),
+ false = lists:member(RFile, RFiles1)
+ end,
+ ok = file:delete(AbsLFile).
+
+do_append(Pid, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LFile = ?config(file, Config),
+ RFile = ?config(new_file, Config),
+ AbsLFile = filename:absname(LFile, PrivDir),
+ Contents = "ftp_SUITE test:appending\r\n",
+
+ ok = file:write_file(AbsLFile, list_to_binary(Contents)),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:lcd(Pid, PrivDir),
+
+ %% remove files from earlier failed test case
+ ftp:delete(Pid, RFile),
+ ftp:delete(Pid, LFile),
+
+ ok = ftp:append(Pid, LFile, RFile),
+ ok = ftp:append(Pid, LFile, RFile),
+ ok = ftp:append(Pid, LFile),
+
+ %% Control the contents of the file
+ {ok, Bin1} = ftp:recv_bin(Pid, RFile),
+ ok = ftp:delete(Pid, RFile),
+ ok = file:delete(AbsLFile),
+ ok = check_content(binary_to_list(Bin1), Contents, double),
+
+ {ok, Bin2} = ftp:recv_bin(Pid, LFile),
+ ok = ftp:delete(Pid, LFile),
+ ok = check_content(binary_to_list(Bin2), Contents, singel),
+ ok.
+
+do_send_bin(Pid, Config) ->
+ File = ?config(file, Config),
+ Contents = "ftp_SUITE test ...",
+ Bin = list_to_binary(Contents),
+ ok = ftp:cd(Pid, "incoming"),
+ {error, enotbinary} = ftp:send_bin(Pid, Contents, File),
+ ok = ftp:send_bin(Pid, Bin, File),
+ {ok, RFilesString} = ftp:nlist(Pid),
+ RFiles = split(RFilesString),
+ true = lists:member(File, RFiles),
+ ok = ftp:delete(Pid, File),
+ ok.
+
+do_append_bin(Pid, Config) ->
+ File = ?config(file, Config),
+ Contents = "ftp_SUITE test ...",
+ Bin = list_to_binary(Contents),
+ ok = ftp:cd(Pid, "incoming"),
+ {error, enotbinary} = ftp:append_bin(Pid, Contents, File),
+ ok = ftp:append_bin(Pid, Bin, File),
+ ok = ftp:append_bin(Pid, Bin, File),
+ %% Control the contents of the file
+ {ok, Bin2} = ftp:recv_bin(Pid, File),
+ ok = ftp:delete(Pid,File),
+ ok = check_content(binary_to_list(Bin2),binary_to_list(Bin), double).
+
+do_send_chunk(Pid, Config) ->
+ File = ?config(file, Config),
+ Contents = "ftp_SUITE test ...",
+ Bin = list_to_binary(Contents),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:send_chunk_start(Pid, File),
+ {error, echunk} = ftp:cd(Pid, "incoming"),
+ {error, enotbinary} = ftp:send_chunk(Pid, Contents),
+ ok = ftp:send_chunk(Pid, Bin),
+ ok = ftp:send_chunk(Pid, Bin),
+ ok = ftp:send_chunk_end(Pid),
+ {ok, RFilesString} = ftp:nlist(Pid),
+ RFiles = split(RFilesString),
+ true = lists:member(File, RFiles),
+ ok = ftp:delete(Pid, File),
+ ok.
+
+do_append_chunk(Pid, Config) ->
+ File = ?config(file, Config),
+ Contents = ["ER","LE","RL"],
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:append_chunk_start(Pid, File),
+ {error, enotbinary} = ftp:append_chunk(Pid, lists:nth(1,Contents)),
+ ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(1,Contents))),
+ ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(2,Contents))),
+ ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(3,Contents))),
+ ok = ftp:append_chunk_end(Pid),
+ %%Control the contents of the file
+ {ok, Bin2} = ftp:recv_bin(Pid, File),
+ ok = check_content(binary_to_list(Bin2),"ERL", double),
+ ok = ftp:delete(Pid, File),
+ ok.
+
+do_recv(Pid, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ File = ?config(file, Config),
+ Newfile = ?config(new_file, Config),
+ AbsFile = filename:absname(File, PrivDir),
+ Contents = "ftp_SUITE:recv test ...",
+ ok = file:write_file(AbsFile, list_to_binary(Contents)),
+ ok = ftp:cd(Pid, "incoming"),
+ ftp:delete(Pid, File), % reset
+ ftp:lcd(Pid, PrivDir),
+ ok = ftp:send(Pid, File),
+ ok = file:delete(AbsFile), % cleanup
+ test_server:sleep(100),
+ ok = ftp:lcd(Pid, PrivDir),
+ ok = ftp:recv(Pid, File),
+ {ok, Files} = file:list_dir(PrivDir),
+ true = lists:member(File, Files),
+ ok = file:delete(AbsFile), % cleanup
+ ok = ftp:recv(Pid, File, Newfile),
+ ok = ftp:delete(Pid, File), % cleanup
+ ok.
+
+do_recv_bin(Pid, Config) ->
+ File = ?config(file, Config),
+ Contents1 = "ftp_SUITE test ...",
+ Bin1 = list_to_binary(Contents1),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:send_bin(Pid, Bin1, File),
+ test_server:sleep(100),
+ {ok, Bin2} = ftp:recv_bin(Pid, File),
+ ok = ftp:delete(Pid, File), % cleanup
+ Contents2 = binary_to_list(Bin2),
+ Contents1 = Contents2,
+ ok.
+
+do_recv_chunk(Pid, Config) ->
+ File = ?config(file, Config),
+ Data = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
+ "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
+ "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
+ "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG"
+ "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
+ "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII",
+
+ Contents1 = lists:flatten(lists:duplicate(10, Data)),
+ Bin1 = list_to_binary(Contents1),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:type(Pid, binary),
+ ok = ftp:send_bin(Pid, Bin1, File),
+ test_server:sleep(100),
+ {error, "ftp:recv_chunk_start/2 not called"} = recv_chunk(Pid, <<>>),
+ ok = ftp:recv_chunk_start(Pid, File),
+ {ok, Contents2} = recv_chunk(Pid, <<>>),
+ ok = ftp:delete(Pid, File), % cleanup
+ ok = find_diff(Contents2, Contents1, 1),
+ ok.
+
+do_type(Pid) ->
+ ok = ftp:type(Pid, ascii),
+ ok = ftp:type(Pid, binary),
+ ok = ftp:type(Pid, ascii),
+ {error, etype} = ftp:type(Pid, foobar),
+ ok.
+
+do_quote(Pid) ->
+ ["257 \"/\""++_Rest] = ftp:quote(Pid, "pwd"), %% 257
+ [_| _] = ftp:quote(Pid, "help"),
+ %% This negativ test causes some ftp servers to hang. This test
+ %% is not important for the client, so we skip it for now.
+ %%["425 Can't build data connection: Connection refused."]
+ %% = ftp:quote(Pid, "list"),
+ ok.
+
+ watch_dog(Config) ->
+ Dog = test_server:timetrap(inets_test_lib:minutes(1)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ [{watchdog, Dog} | NewConfig].
+
+ close_connection(Config) ->
+ case ?config(ftp, Config) of
+ Pid when is_pid(Pid) ->
+ ok = ftp:close(Pid),
+ lists:delete({ftp, Pid}, Config);
+ _ ->
+ Config
+ end.
+
+ftp_host(Config) ->
+ case ?config(ftp_remote_host, Config) of
+ undefined ->
+ exit({skip, "No host specified"});
+ Host ->
+ Host
+ end.
+
+check_content(RContent, LContent, Amount) ->
+ LContent2 = case Amount of
+ double ->
+ LContent ++ LContent;
+ singel ->
+ LContent
+ end,
+ case string:equal(RContent, LContent2) of
+ true ->
+ ok;
+ false ->
+ %% Find where the diff is
+ Where = find_diff(RContent, LContent2, 1),
+ Where
+ end.
+
+find_diff(A, A, _) ->
+ ok;
+find_diff([H|T1], [H|T2], Pos) ->
+ find_diff(T1, T2, Pos+1);
+find_diff(RC, LC, Pos) ->
+ {error, {diff, Pos, RC, LC}}.
+
+recv_chunk(Pid, Acc) ->
+ case ftp:recv_chunk(Pid) of
+ ok ->
+ {ok, binary_to_list(Acc)};
+ {ok, Bin} ->
+ recv_chunk(Pid, <<Acc/binary, Bin/binary>>);
+ Error ->
+ Error
+ end.
+
+split(Cs) ->
+ split(Cs, [], []).
+
+split([$\r, $\n| Cs], I, Is) ->
+ split(Cs, [], [lists:reverse(I)| Is]);
+split([C| Cs], I, Is) ->
+ split(Cs, [C| I], Is);
+split([], I, Is) ->
+ lists:reverse([lists:reverse(I)| Is]).
+
+do_ftp_open(Host, Flags) ->
+ io:format("do_ftp_open -> entry with"
+ "~n Host: ~p"
+ "~n Flags: ~p", [Host, Flags]),
+ case ftp:open(Host, Flags) of
+ {ok, _} = OK ->
+ OK;
+ {error, Reason} ->
+ Str =
+ lists:flatten(
+ io_lib:format("Unable to reach test FTP server ~p (~p)",
+ [Host, Reason])),
+ throw({skip, Str})
+ end.
+
+
+passwd() ->
+ Host =
+ case inet:gethostname() of
+ {ok, H} ->
+ H;
+ _ ->
+ "localhost"
+ end,
+ "ftp_SUITE@" ++ Host.
+
+ftpd_hosts(Config) ->
+ DataDir = ?config(data_dir, Config),
+ FileName = filename:join([DataDir, "../ftp_SUITE_data/", ftpd_hosts]),
+ io:format("FileName: ~p~n", [FileName]),
+ case file:consult(FileName) of
+ {ok, [Hosts]} when is_list(Hosts) ->
+ Hosts;
+ _ ->
+ []
+ end.
+
+wrapper(Prefix,doc,Func) ->
+ Prefix++Func(doc);
+wrapper(_,X,Func) ->
+ Func(X).
+
+data_dir(Config) ->
+ case ?config(data_dir, Config) of
+ List when (length(List) > 0) ->
+ PathList = filename:split(List),
+ {NewPathList,_} = lists:split((length(PathList)-1), PathList),
+ DataDir = filename:join(NewPathList ++ [ftp_SUITE_data]),
+ NewConfig =
+ lists:keyreplace(data_dir,1,Config, {data_dir,DataDir}),
+ NewConfig;
+ _ -> Config
+ end.
+
+
+
+p(F) ->
+ p(F, []).
+
+p(F, A) ->
+ case get(ftp_testcase) of
+ undefined ->
+ io:format("~w [~w] " ++ F ++ "~n", [?MODULE, self() | A]);
+ TC when is_atom(TC) ->
+ io:format("~w [~w] ~w:" ++ F ++ "~n", [?MODULE, self(), TC | A])
+ end.
diff --git a/lib/inets/test/ftp_ticket_test.erl b/lib/inets/test/ftp_ticket_test.erl
new file mode 100644
index 0000000000..6748df03bb
--- /dev/null
+++ b/lib/inets/test/ftp_ticket_test.erl
@@ -0,0 +1,51 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_ticket_test).
+
+-compile(export_all).
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Solaris 8 sparc ").
+
+
+%% Test server callbacks
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+
+all(suite) ->
+ {conf,init,tickets(),fin}.
+
+init(Config) ->
+ ?LIB_MOD:ftpd_init(ticket_test, Config).
+
+tickets() ->
+ [ticket_6035].
+
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+ticket_6035(X) -> ?LIB_MOD:ticket_6035(X).
diff --git a/lib/inets/test/ftp_windows_2003_server_test.erl b/lib/inets/test/ftp_windows_2003_server_test.erl
new file mode 100644
index 0000000000..d24318d04f
--- /dev/null
+++ b/lib/inets/test/ftp_windows_2003_server_test.erl
@@ -0,0 +1,152 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_windows_2003_server_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Windows 2003 server ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(windows_2003_server, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_windows_xp_test.erl b/lib/inets/test/ftp_windows_xp_test.erl
new file mode 100644
index 0000000000..bc161e4f6a
--- /dev/null
+++ b/lib/inets/test/ftp_windows_xp_test.erl
@@ -0,0 +1,150 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_windows_xp_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Windows xp ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(windows_xp, NewConfig).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl
new file mode 100644
index 0000000000..9559317640
--- /dev/null
+++ b/lib/inets/test/http_format_SUITE.erl
@@ -0,0 +1,585 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(http_format_SUITE).
+-author('[email protected]').
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("http_internal.hrl").
+
+%% Test server specific exports
+-export([all/1, init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases must be exported.
+-export([chunk/1, chunk_decode/1, chunk_encode/1,
+ chunk_extensions_otp_6005/1, chunk_decode_otp_6264/1,
+ chunk_decode_empty_chunk_otp_6511/1,
+ chunk_decode_trailer/1,
+ http_response/1, http_request/1, validate_request_line/1, script/1,
+ esi_parse_headers/1, cgi_parse_headers/1,
+ is_absolut_uri/1, convert_netscapecookie_date/1]).
+
+all(doc) ->
+ ["Test library functions to the http client and server."];
+all(suite) ->
+ [chunk,
+ http_response, http_request, validate_request_line,
+ script, is_absolut_uri, convert_netscapecookie_date].
+
+init_per_testcase(_, Config) ->
+ Dog = test_server:timetrap(?t:minutes(1)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ [{watchdog, Dog} | NewConfig].
+
+end_per_testcase(_, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+script(doc) ->
+ ["Test header parsing in esi/cgi functionality."];
+script(suite) ->
+ [esi_parse_headers, cgi_parse_headers].
+
+chunk(doc) ->
+ ["Test chunk encoding"];
+chunk(suite) ->
+ [chunk_decode, chunk_encode, chunk_extensions_otp_6005,
+ chunk_decode_otp_6264, chunk_decode_empty_chunk_otp_6511,
+ chunk_decode_trailer].
+
+%%-------------------------------------------------------------------------
+chunk_decode(doc) ->
+ ["Test http_chunk:decode/3"];
+chunk_decode(suite) ->
+ [];
+chunk_decode(Config) when is_list(Config) ->
+ ReqHeaders = #http_request_h{'transfer-encoding' = "chunked"},
+ ChunkedBody = "A" ++ ?CRLF ++ "1234567890" ++ ?CRLF ++ "4" ++
+ ?CRLF ++ "HEJ!" ++ ?CRLF ++ "0" ++ ?CRLF ++ ?CRLF,
+ {ok, {Headers, Body}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+ "1234567890HEJ!" = binary_to_list(Body),
+ %% When the "chunked" is removed by the decoding the header
+ %% will become empty in this case i.e. undefined!
+ NewReqHeaders = http_chunk:handle_headers(ReqHeaders, Headers),
+ undefined = NewReqHeaders#http_request_h.'transfer-encoding',
+
+ NewChunkedBody = ["A" ++ [?CR], [?LF] ++ "12345", "67890" ++ ?CRLF ++ "4"
+ ++ ?CRLF ++ "HEJ!" ++ ?CRLF ++ "0" ++ [?CR],
+ [?LF, ?CR, ?LF]],
+
+ {Module, Function, Args} =
+ http_chunk:decode(list_to_binary(hd(NewChunkedBody)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, Body} = parse(Module, Function, Args, tl(NewChunkedBody)),
+ "1234567890HEJ!" = binary_to_list(Body),
+
+ ok.
+
+%%-------------------------------------------------------------------------
+chunk_extensions_otp_6005(doc) ->
+ ["Make sure so called extensions are ignored"];
+chunk_extensions_otp_6005(suite) ->
+ [];
+chunk_extensions_otp_6005(Config) when is_list(Config)->
+ ChunkedBody = "A;ignore this" ++ ?CRLF ++ "1234567890" ++
+ ?CRLF ++ "4" ++ ?CRLF ++ "HEJ!"++ ?CRLF ++ "0" ++
+ ";extensionname=extensionvalue;foo=bar" ++ ?CRLF ++ ?CRLF,
+ {ok, {["content-length:14"], Body}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+ "1234567890HEJ!" = binary_to_list(Body),
+
+ ChunkedBody1 = ["A;", "ignore this" ++ [?CR], [?LF] ++ "1234567890" ++
+ ?CRLF ++ "4" ++ ?CRLF ++ "HEJ!"++ ?CRLF ++ "0" ++
+ ";extensionname=extensionvalue;foo=bar" ++ ?CRLF ++ ?CRLF],
+
+ {Module1, Function1, Args1} =
+ http_chunk:decode(list_to_binary(hd(ChunkedBody1)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, NewBody} = parse(Module1, Function1, Args1, tl(ChunkedBody1)),
+ "1234567890HEJ!" = binary_to_list(NewBody),
+ ok.
+
+%%-------------------------------------------------------------------------
+chunk_decode_otp_6264(doc) ->
+ ["Check that 0 in the body does not count as the last chunk"];
+chunk_decode_otp_6264(suite) ->
+ [];
+chunk_decode_otp_6264(Config) when is_list(Config)->
+ ChunkedBody = "A;ignore this" ++ ?CRLF ++ "1234567890" ++
+ ?CRLF ++ "4" ++ ?CRLF ++ "0123"++ ?CRLF ++ "0" ++
+ ";extensionname=extensionvalue;foo=bar" ++ ?CRLF ++ ?CRLF,
+ {ok, {["content-length:14"], Body}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+ "12345678900123" = binary_to_list(Body),
+
+ NewChunkedBody = ["A" ++ [?CR], [?LF] ++ "12345", "67890" ++ ?CRLF ++ "1"
+ ++ ?CRLF ++ "0" ++ ?CRLF ++ "0" ++ [?CR],
+ [?LF, ?CR, ?LF]],
+
+ {Module, Function, Args} =
+ http_chunk:decode(list_to_binary(hd(NewChunkedBody)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, NewBody} = parse(Module, Function, Args, tl(NewChunkedBody)),
+ "12345678900" = binary_to_list(NewBody),
+
+ NewChunkedBody1 = ["A" ++ [?CR], [?LF] ++ "12345", "67890" ++ ?CRLF ++ "1"
+ ++ ?CRLF ++ "0", ?CRLF ++ "0", [?CR], [?LF],
+ [?CR], [?LF]],
+
+ {Module1, Function1, Args1} =
+ http_chunk:decode(list_to_binary(hd(NewChunkedBody1)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, NewBody} = parse(Module1, Function1, Args1, tl(NewChunkedBody1)),
+ "12345678900" = binary_to_list(NewBody),
+
+ ok.
+%%-------------------------------------------------------------------------
+chunk_decode_empty_chunk_otp_6511(doc) ->
+ [""];
+chunk_decode_empty_chunk_otp_6511(suite) ->
+ [];
+chunk_decode_empty_chunk_otp_6511(Config) when is_list(Config) ->
+ ChunkedBody = "0" ++ ?CRLF ++ ?CRLF,
+ {ok,{["content-length:0"],<<>>}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+ ok.
+
+%%-------------------------------------------------------------------------
+chunk_decode_trailer(doc) ->
+ ["Make sure trailers are handled correctly. Trailers should"
+ "become new headers"];
+chunk_decode_trailer(suite) ->
+ [];
+chunk_decode_trailer(Config) when is_list(Config)->
+ ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+
+ {ok, {Headers, Body}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ %% There is no guaranteed order of headers.
+ true = lists:member("content-length:42", Headers),
+ true = lists:member("some-footer:some-value", Headers),
+ true = lists:member("another-footer:another-value", Headers),
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(Body),
+
+ ChunkedBody1 = "1a" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF ++ ?CRLF,
+
+ {ok, {Headers1, Body1}} =
+ http_chunk:decode(list_to_binary(ChunkedBody1),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ true = lists:member("content-length:42", Headers1),
+ true = lists:member("some-footer:some-value", Headers1),
+ false = lists:member("another-footer:another-value", Headers1),
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(Body1),
+
+
+ ChunkedBody2 = ["1a", ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0", ";",
+ "ignore stuff here=foobar", ?CRLF ++
+ "some-footer:some-value", ?CRLF, ?CRLF],
+
+ {Module, Function, Args} =
+ http_chunk:decode(list_to_binary(hd(ChunkedBody2)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, NewBody} = parse(Module, Function, Args, tl(ChunkedBody2)),
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(NewBody),
+
+ ChunkedBody3 = ["1a", ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz", ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value", [?CR], [?LF] , ?CRLF],
+
+ {Module1, Function1, Args1} =
+ http_chunk:decode(list_to_binary(hd(ChunkedBody3)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, NewBody} = parse(Module1, Function1, Args1, tl(ChunkedBody3)),
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(NewBody),
+
+ ok.
+
+%%-------------------------------------------------------------------------
+chunk_encode(doc) ->
+ ["Test http_chunk:encode/1 & http_chunk:encode_last/0"];
+chunk_encode(suite) ->
+ [];
+chunk_encode(Config) when is_list(Config) ->
+ <<54, ?CR, ?LF, 102,111,111,98,97,114, ?CR, ?LF>> =
+ http_chunk:encode(list_to_binary("foobar")),
+ ["6", ?CR, ?LF,"foobar", ?CR, ?LF] = http_chunk:encode("foobar"),
+ <<$0, ?CR, ?LF, ?CR, ?LF >> = http_chunk:encode_last(),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+http_response(doc) ->
+ ["Test httpc_response:parse*. This test case will simulate that the "
+ "message will be recived a little at the time on a socket and the "
+ "package may be broken up into smaller parts at arbitrary point."];
+http_response(suite) ->
+ [];
+http_response(Config) when is_list(Config) ->
+
+ HttpHead1 = ["HTTP", "/1.1 ", "20", "0 ", "ok", [?CR, ?LF],
+ "content-length:83" ++ ?CRLF ++ "content", "-type:",
+ "text/html" ++ ?CRLF ++
+ "date:Thu, 28 Oct 2004 07:57:43 GMT" ++
+ [?CR], [?LF, ?CR, ?LF]],
+ {"HTTP/1.1",
+ 200,
+ "ok",
+ #http_response_h{'content-length' = "83",
+ 'content-type' = "text/html",
+ date = "Thu, 28 Oct 2004 07:57:43 GMT"},
+ <<>>} =
+ parse(httpc_response, parse, [?HTTP_MAX_HEADER_SIZE, false],
+ HttpHead1),
+
+ HttpHead2 = ["HTTP/1.1 200", " ok", [?CR], [?LF] ++
+ "content-length:83" ++ ?CRLF ++ "content-type:",
+ "text/html" ++ ?CRLF ++
+ "date:" ++ "Thu, 28 Oct 2004 07:57:43 GMT" ++
+ ?CRLF, ?CRLF],
+ {"HTTP/1.1",
+ 200,
+ "ok",
+ #http_response_h{'content-length' = "83",
+ 'content-type' = "text/html",
+ date = "Thu, 28 Oct 2004 07:57:43 GMT"},
+ <<>>} =
+ parse(httpc_response, parse, [?HTTP_MAX_HEADER_SIZE, false],
+ HttpHead2),
+
+ HttpHead3 = ["HTTP/1.1 200 ", "ok", ?CRLF ++
+ "content-length:83" ++ ?CRLF ++ "content-type:",
+ "text/html" ++ ?CRLF ++
+ "date:" ++ "Thu, 28 Oct 2004 07:57:43 GMT" ++
+ [?CR, ?LF,?CR], [?LF]],
+ {"HTTP/1.1",
+ 200,
+ "ok",
+ #http_response_h{'content-length' = "83",
+ 'content-type' = "text/html",
+ date = "Thu, 28 Oct 2004 07:57:43 GMT"},
+ <<>>} =
+ parse(httpc_response, parse, [?HTTP_MAX_HEADER_SIZE, false],
+ HttpHead3),
+
+ HttpBody = ["<HTML>\n<HEAD>\n<TITLE> dummy </TITLE>\n</HEAD>\n<BODY>\n",
+ "<H1>dummy</H1>\n</BODY>\n</HTML>\n"],
+
+ NewBody = lists:flatten(HttpBody),
+ Length = length(NewBody),
+ NewBody =
+ binary_to_list(parse
+ (httpc_response, whole_body, [<<>>,Length],
+ HttpBody)),
+
+ HttpBody1 = ["<HTML", ">\n<HEAD>", "\n<TITLE> dummy </TITLE>\n</HEAD>\n",
+ "<BODY>\n", "<H1>du", "mmy</H1>\n</BODY>\n</HTML>\n"],
+
+ NewBody1 = lists:flatten(HttpBody1),
+ Length1 = length(NewBody1),
+ NewBody1 = binary_to_list(parse
+ (httpc_response, whole_body,
+ [<<>>,Length1], HttpBody1)),
+ ok.
+%%-------------------------------------------------------------------------
+http_request(doc) ->
+ ["Test httpd_request:parse* This test case will simulate that the "
+ "message will be recived a little at the time on a socket and the "
+ "package may be broken up into smaller parts at arbitrary point."];
+http_request(suite) ->
+ [];
+http_request(Config) when is_list(Config) ->
+
+ HttpHead = ["GE", "T ", "http://www.erlang", ".org ", "HTTP",
+ "/1.1" ++ ?CRLF ++ "host:",
+ "www.erlang.org" ++ [?CR],
+ [?LF] ++ "te: " ++ ?CRLF, ?CRLF],
+ {"GET",
+ "http://www.erlang.org",
+ "HTTP/1.1",
+ {#http_request_h{host = "www.erlang.org", te = []},
+ ["te: ","host:www.erlang.org"]}, <<>>} =
+ parse(httpd_request, parse, [?HTTP_MAX_HEADER_SIZE], HttpHead),
+
+ HttpHead1 = ["GET http://www.erlang.org HTTP/1.1" ++
+ [?CR], [?LF, ?CR, ?LF]],
+ {"GET",
+ "http://www.erlang.org",
+ "HTTP/1.1",
+ {#http_request_h{}, []}, <<>>} =
+ parse(httpd_request, parse, [?HTTP_MAX_HEADER_SIZE], HttpHead1),
+
+
+ HttpHead2 = ["GET http://www.erlang.org HTTP/1.1" ++
+ [?CR, ?LF, ?CR], [?LF]],
+ {"GET",
+ "http://www.erlang.org",
+ "HTTP/1.1",
+ {#http_request_h{}, []}, <<>>} =
+ parse(httpd_request, parse, [?HTTP_MAX_HEADER_SIZE], HttpHead2),
+
+ %% Note the following body is not related to the headers above
+ HttpBody = ["<HTML>\n<HEAD>\n<TITLE> dummy </TITLE>\n</HEAD>\n<BODY>\n",
+ "<H1>dummy</H1>\n</BODY>\n</HTML>\n"],
+
+ NewBody = lists:flatten(HttpBody),
+ Length = length(NewBody),
+ NewBody =
+ binary_to_list(parse
+ (httpd_request, whole_body, [<<>>,Length], HttpBody)),
+
+ HttpBody1 = ["<HTML", ">\n<HEAD>", "\n<TITLE> dummy </TITLE>\n</HEAD>\n",
+ "<BODY>\n", "<H1>du", "mmy</H1>\n</BODY>\n</HTML>\n"],
+
+ NewBody1 = lists:flatten(HttpBody1),
+ Length1 = length(NewBody1),
+ NewBody1 =
+ binary_to_list(parse
+ (httpd_request, whole_body,
+ [<<>>, Length1], HttpBody1)),
+ ok.
+%%-------------------------------------------------------------------------
+validate_request_line(doc) ->
+ ["Test httpd_request:validate/3. Makes sure you can not get past"
+ " the server_root and that the request is recognized by the server"
+ " and protcol version." ];
+validate_request_line(suite) ->
+ [];
+validate_request_line(Config) when is_list(Config) ->
+
+ %% HTTP/0.9 only has GET requests
+ ok =
+ httpd_request:validate("GET", "http://www.erlang/org", "HTTP/0.9"),
+ {error, {not_supported,
+ {"HEAD", "http://www.erlang/org", "HTTP/0.9"}}} =
+ httpd_request:validate("HEAD", "http://www.erlang/org", "HTTP/0.9"),
+ {error, {not_supported,
+ {"TRACE", "http://www.erlang/org", "HTTP/0.9"}}} =
+ httpd_request:validate("TRACE", "http://www.erlang/org", "HTTP/0.9"),
+ {error, {not_supported,
+ {"POST", "http://www.erlang/org", "HTTP/0.9"}}} =
+ httpd_request:validate("POST", "http://www.erlang/org", "HTTP/0.9"),
+
+ %% HTTP/1.*
+ ok = httpd_request:validate("HEAD", "http://www.erlang/org",
+ "HTTP/1.1"),
+ ok = httpd_request:validate("GET", "http://www.erlang/org",
+ "HTTP/1.1"),
+ ok = httpd_request:validate("POST","http://www.erlang/org",
+ "HTTP/1.1"),
+ ok = httpd_request:validate("TRACE","http://www.erlang/org",
+ "HTTP/1.1"),
+ {error, {not_supported,
+ {"FOOBAR", "http://www.erlang/org", "HTTP/1.1"}}} =
+ httpd_request:validate("FOOBAR", "http://www.erlang/org",
+ "HTTP/1.1"),
+
+ %% Attempts to get outside of server_root directory by relative links
+ ForbiddenUri = "http://127.0.0.1:8888/../../../../../etc/passwd",
+ {error, {bad_request, {forbidden, ForbiddenUri}}} =
+ httpd_request:validate("GET", ForbiddenUri, "HTTP/1.1"),
+
+ ForbiddenUri2 =
+ "http://127.0.0.1:8888/././././././../../../../../etc/passwd",
+ {error, {bad_request, {forbidden, ForbiddenUri2}}} =
+ httpd_request:validate("GET", ForbiddenUri2, "HTTP/1.1"),
+
+ HexForbiddenUri = "http://127.0.0.1:8888/%2e%2e/%2e%2e/%2e%2e/"
+ "home/ingela/test.html",
+ {error, {bad_request, {forbidden, HexForbiddenUri}}} =
+ httpd_request:validate("GET", HexForbiddenUri, "HTTP/1.1"),
+
+ NewForbiddenUri =
+ "http://127.0.0.1:8888/foobar/../../../home/ingela/test.html",
+ {error, {bad_request, {forbidden, NewForbiddenUri}}} =
+ httpd_request:validate("GET", NewForbiddenUri, "HTTP/1.1"),
+
+ NewForbiddenUri1 =
+ "http://127.0.0.1:8888/../home/ingela/test.html",
+ {error, {bad_request, {forbidden, NewForbiddenUri1}}} =
+ httpd_request:validate("GET", NewForbiddenUri1, "HTTP/1.1"),
+
+ ok.
+%%-------------------------------------------------------------------------
+esi_parse_headers(doc) ->
+ ["Test httpd_esi:*. All header values are received in the same"
+ " erlang message."];
+esi_parse_headers(suite) ->
+ [];
+esi_parse_headers(Config) when is_list(Config) ->
+
+ ESIResult = "content-type:text/html\r\ndate:Thu, 28 Oct 2004 07:57:43 "
+ "GMT\r\nstatus:200 OK\r\n\r\nFoobar",
+
+ {"content-type:text/html\r\ndate:Thu, 28 Oct 2004 07:57:43 GMT\r\nst"
+ "atus:200 OK\r\n" = Headers,
+ "Foobar"} = httpd_esi:parse_headers(ESIResult),
+
+ {ok,[{"date","Thu, 28 Oct 2004 07:57:43 GMT"},
+ {"content-type","text/html"}], 200} =
+ httpd_esi:handle_headers(Headers),
+
+ ESIResult2 =
+ "location:http://foo.bar.se\r\ndate:Thu, 28 Oct 2004 07:57:43 "
+ "GMT\r\n\r\n",
+
+ {"location:http://foo.bar.se\r\ndate:Thu, 28 Oct 2004 07:57:43 GMT\r\n" =
+ Headers2,[]}
+ = httpd_esi:parse_headers(ESIResult2),
+
+ {ok,[{"date","Thu, 28 Oct 2004 07:57:43 GMT"},
+ {"location","http://foo.bar.se"}], 302} =
+ httpd_esi:handle_headers(Headers2),
+
+ {proceed,"/foo/bar.html"} =
+ httpd_esi:handle_headers("location:/foo/bar.html\r\n"),
+ ok.
+
+%%--------------------------------------------------------------------
+cgi_parse_headers(doc) ->
+ ["Test httpd_cgi:*. This test case will simulate that the "
+ "message will be recived a little at the time on a socket and the "
+ "package may be broken up into smaller parts at arbitrary point."];
+cgi_parse_headers(suite) ->
+ [];
+cgi_parse_headers(Config) when is_list(Config) ->
+
+ CGIResult = ["content-type:text", "/html\ndate:Thu, 28 Oct 2004 07:57:43 "
+ "GMT\nst", "atus:200 OK\n", "\nFoobar"],
+
+ {Headers, Body} =
+ parse(httpd_cgi, parse_headers, [<<>>, [], []], CGIResult),
+
+ "Foobar" = binary_to_list(Body),
+
+ {ok,[{"content-type","text/html"},
+ {"date","Thu, 28 Oct 2004 07:57:43 GMT"}], {200,"OK"}} =
+ httpd_cgi:handle_headers(Headers),
+
+ CGIResult2 = ["location:http://foo.bar.se\ndate:Thu, 28 Oct 2004"
+ " 07:57:43 GMT\n\n"],
+ {Headers2, _} = parse(httpd_cgi, parse_headers,
+ [<<>>, [], []], CGIResult2),
+
+ {ok,[{"location","http://foo.bar.se"},
+ {"date","Thu, 28 Oct 2004 07:57:43 GMT"}], {302,"Redirect"}} =
+ httpd_cgi:handle_headers(Headers2),
+
+ {proceed,"/foo/bar.html"} =
+ httpd_cgi:handle_headers(["location:/foo/bar.html\n"]),
+
+ CGIHTTPResult = ["Content-Type:text", "/html\n", "Connection:close\r\n",
+ "Content-Language:en\r\nAge:", "4711\r\n\r\n\nfoobar"],
+
+ {Headers3, _} = parse(httpd_cgi, parse_headers,
+ [<<>>, [], []], CGIHTTPResult),
+
+ {ok,[{"content-type","text/html"},
+ {"connection","close"},
+ {"content-language","en"},
+ {"age","4711"}], {200,"ok"}} = httpd_cgi:handle_headers(Headers3),
+
+ ok.
+
+%%-------------------------------------------------------------------------
+is_absolut_uri(doc) ->
+ ["Test http_request:is_absolut_uri/1."];
+is_absolut_uri(suite) ->
+ [];
+is_absolut_uri(Config) when is_list(Config) ->
+ true = http_request:is_absolut_uri("http://www.erlang.org"),
+ true = http_request:is_absolut_uri("https://www.erlang.org"),
+ false = http_request:is_absolut_uri("index.html").
+
+
+%%-------------------------------------------------------------------------
+convert_netscapecookie_date(doc) ->
+ ["Test http_util:convert_netscapecookie_date/1."];
+convert_netscapecookie_date(suite) ->
+ [];
+convert_netscapecookie_date(Config) when is_list(Config) ->
+ {{2006,1,6},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Mon, 06-Jan-2006 08:59:38 GMT"),
+ {{2006,2, 7},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Tue, 07-Feb-2006 08:59:38 GMT"),
+ {{2006,3,8},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Wdy, 08-Mar-2006 08:59:38 GMT"),
+ {{2006,4,9},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Thu, 09-Apr-2006 08:59:38 GMT"),
+ {{2006,5,10},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Fri, 10-May-2006 08:59:38 GMT"),
+ {{2006,6,11},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sat, 11-Jun-2006 08:59:38 GMT"),
+ {{2006,7,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Jul-2006 08:59:38 GMT"),
+ {{2006,8,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Aug-2006 08:59:38 GMT"),
+ {{2006,9,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Sep-2006 08:59:38 GMT"),
+ {{2006,10,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Oct-2006 08:59:38 GMT"),
+ {{2006,11,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Nov-2006 08:59:38 GMT"),
+ {{2006,12,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Dec-2006 08:59:38 GMT"),
+ ok.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+parse(Module, Function, Args, [Data | Rest]) ->
+ case Module:Function([list_to_binary(Data) | Args]) of
+ {ok, Result} ->
+ Result;
+ {NewModule, NewFunction, NewArgs} ->
+ parse(NewModule, NewFunction, NewArgs, Rest)
+ end.
+
+
+
diff --git a/lib/inets/test/http_internal.hrl b/lib/inets/test/http_internal.hrl
new file mode 120000
index 0000000000..a4600a09f7
--- /dev/null
+++ b/lib/inets/test/http_internal.hrl
@@ -0,0 +1 @@
+../src/http_lib/http_internal.hrl \ No newline at end of file
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
new file mode 100644
index 0000000000..96099c49fd
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -0,0 +1,2954 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+%%
+%% ts:run(inets, httpc_SUITE, [batch]).
+%%
+
+-module(httpc_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+-include_lib("kernel/include/file.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+%% Test server specific exports
+-define(PROXY_URL, "http://www.erlang.org").
+-define(PROXY, "www-proxy.ericsson.se").
+-define(PROXY_PORT, 8080).
+-define(IP_PORT, 8998).
+-define(SSL_PORT, 8999).
+-define(NOT_IN_USE_PORT, 8997).
+-define(LOCAL_HOST, {127,0,0,1}).
+-define(IPV6_LOCAL_HOST, "0:0:0:0:0:0:0:1").
+-define(URL_START, "http://localhost:").
+-define(SSL_URL_START, "https://localhost:").
+-define(CR, $\r).
+-define(LF, $\n).
+-define(HTTP_MAX_HEADER_SIZE, 10240).
+
+
+%%--------------------------------------------------------------------
+%% all(Arg) -> [Doc] | [Case] | {skip, Comment}
+%% Arg - doc | suite
+%% Doc - string()
+%% Case - atom()
+%% Name of a test case function.
+%% Comment - string()
+%% Description: Returns documentation/test cases in this test suite
+%% or a skip tuple if the platform is not supported.
+%%--------------------------------------------------------------------
+
+all(doc) ->
+ ["Test the http client in the intes application."];
+all(suite) ->
+ [
+ proxy_options,
+ proxy_head,
+ proxy_get,
+ proxy_trace,
+ proxy_post,
+ proxy_put,
+ proxy_delete,
+ proxy_auth,
+ proxy_headers,
+ proxy_emulate_lower_versions,
+ http_options,
+ http_head,
+ http_get,
+ http_post,
+ http_dummy_pipe,
+ http_inets_pipe,
+ http_trace,
+ http_async,
+ http_save_to_file,
+ http_save_to_file_async,
+ http_headers,
+ http_headers_dummy,
+ http_bad_response,
+ ssl_head,
+ ssl_get,
+ ssl_trace,
+ http_redirect,
+ http_redirect_loop,
+ http_internal_server_error,
+ http_userinfo,
+ http_cookie,
+ http_server_does_not_exist,
+ http_invalid_http,
+ http_emulate_lower_versions,
+ http_relaxed,
+ page_does_not_exist,
+ proxy_page_does_not_exist,
+ proxy_https_not_supported,
+ http_stream,
+ http_stream_once,
+ proxy_stream,
+ parse_url,
+ options,
+ ipv6,
+ headers_as_is,
+ tickets
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ DataDir = ?config(data_dir, Config),
+ ServerRoot = filename:join(PrivDir, "server_root"),
+ DocRoot = filename:join(ServerRoot, "htdocs"),
+ IpConfFile = integer_to_list(?IP_PORT) ++ ".conf",
+ SslConfFile = integer_to_list(?SSL_PORT) ++ ".conf",
+
+ setup_server_dirs(ServerRoot, DocRoot, DataDir),
+ create_config(IpConfFile, ip_comm, ?IP_PORT, PrivDir, ServerRoot,
+ DocRoot, DataDir),
+ create_config(SslConfFile, ssl, ?SSL_PORT, PrivDir, ServerRoot,
+ DocRoot, DataDir),
+
+ Cgi = case test_server:os_type() of
+ {win32, _} ->
+ filename:join([ServerRoot, "cgi-bin", "cgi_echo.exe"]);
+ _ ->
+ filename:join([ServerRoot, "cgi-bin", "cgi_echo"])
+ end,
+
+ {ok, FileInfo} = file:read_file_info(Cgi),
+ ok = file:write_file_info(Cgi, FileInfo#file_info{mode = 8#00755}),
+
+ [{server_root, ServerRoot},
+ {doc_root, DocRoot},
+ {local_port, ?IP_PORT},
+ {local_ssl_port, ?SSL_PORT} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ inets_test_lib:del_dirs(PrivDir),
+ application:stop(inets),
+ application:stop(ssl),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_testcase(otp_8154_1 = Case, Config) ->
+ init_per_testcase(Case, 5, Config);
+init_per_testcase(Case, Config) ->
+ init_per_testcase(Case, 2, Config).
+
+init_per_testcase(Case, Timeout, Config) ->
+ io:format(user, "~n~n*** INIT ~w:~w[~w] ***~n~n",
+ [?MODULE, Timeout, Case]),
+ PrivDir = ?config(priv_dir, Config),
+ application:stop(inets),
+ Dog = test_server:timetrap(inets_test_lib:minutes(Timeout)),
+ TmpConfig = lists:keydelete(watchdog, 1, Config),
+ IpConfFile = integer_to_list(?IP_PORT) ++ ".conf",
+ SslConfFile = integer_to_list(?SSL_PORT) ++ ".conf",
+
+ NewConfig =
+ case atom_to_list(Case) of
+ "ssl" ++ _ ->
+ application:stop(ssl),
+ TmpConfig2 =
+ lists:keydelete(local_ssl_server, 1, TmpConfig),
+ %% Will start inets
+ Server =
+ inets_test_lib:start_http_server(
+ filename:join(PrivDir, SslConfFile)),
+ [{watchdog, Dog}, {local_ssl_server, Server} | TmpConfig2];
+ "proxy" ++ Rest ->
+ case Rest of
+ "_https_not_supported" ->
+ inets:start(),
+ case (catch application:start(ssl)) of
+ ok ->
+ [{watchdog, Dog} | TmpConfig];
+ _ ->
+ [{skip,
+ "SSL does not seem to be supported"}
+ | TmpConfig]
+ end;
+ _ ->
+ case is_proxy_available(?PROXY, ?PROXY_PORT) of
+ true ->
+ inets:start(),
+ [{watchdog, Dog} | TmpConfig];
+ false ->
+ [{skip, "Failed to contact proxy"} |
+ TmpConfig]
+ end
+ end;
+ _ ->
+ TmpConfig2 = lists:keydelete(local_server, 1, TmpConfig),
+ Server =
+ %% Will start inets
+ inets_test_lib:start_http_server(
+ filename:join(PrivDir, IpConfFile)),
+ [{watchdog, Dog}, {local_server, Server} | TmpConfig2]
+ end,
+
+ http:set_options([{proxy, {{?PROXY, ?PROXY_PORT},
+ ["localhost", ?IPV6_LOCAL_HOST]}}]),
+ inets:enable_trace(max, io, httpc),
+ %% inets:enable_trace(max, io, all),
+ %% snmp:set_trace([gen_tcp, inet_tcp, prim_inet]),
+ NewConfig.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(http_save_to_file, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ FullPath = filename:join(PrivDir, "dummy.html"),
+ file:delete(FullPath),
+ finish(Config);
+
+end_per_testcase(_, Config) ->
+ finish(Config).
+
+finish(Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+
+tickets(doc) ->
+ ["."];
+tickets(suite) ->
+ [
+ hexed_query_otp_6191,
+ empty_body_otp_6243,
+ empty_response_header_otp_6830,
+ transfer_encoding_otp_6807,
+ proxy_not_modified_otp_6821,
+ no_content_204_otp_6982,
+ missing_CR_otp_7304,
+ otp_7883,
+ otp_8154,
+ otp_8106,
+ otp_8056,
+ otp_8352,
+ otp_8371
+ ].
+
+
+%%-------------------------------------------------------------------------
+
+http_options(doc) ->
+ ["Test http options request against local server."];
+http_options(suite) ->
+ [];
+http_options(Config) when is_list(Config) ->
+ {skip, "Not supported by httpd"}.
+
+http_head(doc) ->
+ ["Test http head request against local server."];
+http_head(suite) ->
+ [];
+http_head(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ case http:request(head, {URL, []}, [], []) of
+ {ok, {{_,200,_}, [_ | _], []}} ->
+ ok;
+ {ok, WrongReply} ->
+ tsf({wrong_reply, WrongReply});
+ Error ->
+ tsf({failed, Error})
+ end;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+%%-------------------------------------------------------------------------
+http_get(doc) ->
+ ["Test http get request against local server"];
+http_get(suite) ->
+ [];
+http_get(Config) when is_list(Config) ->
+ tsp("http_get -> entry with"
+ "~n Config: ~p", [Config]),
+ case ?config(local_server, Config) of
+ ok ->
+ tsp("local-server running"),
+ Method = get,
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ Timeout = timer:seconds(1),
+ ConnTimeout = Timeout + timer:seconds(1),
+ HttpOptions1 = [{timeout, Timeout}, {connect_timeout, ConnTimeout}],
+ Options1 = [],
+ Body =
+ case http:request(Method, Request, HttpOptions1, Options1) of
+ {ok, {{_,200,_}, [_ | _], ReplyBody = [_ | _]}} ->
+ ReplyBody;
+ {ok, UnexpectedReply1} ->
+ tsf({unexpected_reply, UnexpectedReply1});
+ {error, _} = Error1 ->
+ tsf({bad_reply, Error1})
+ end,
+
+ %% eqvivivalent to http:request(get, {URL, []}, [], []),
+ inets_test_lib:check_body(Body),
+
+ HttpOptions2 = [],
+ Options2 = [{body_format, binary}],
+ case http:request(Method, Request, HttpOptions2, Options2) of
+ {ok, {{_,200,_}, [_ | _], Bin}} when is_binary(Bin) ->
+ ok;
+ {ok, {{_,200,_}, [_ | _], BadBin}} ->
+ tsf({body_format_not_binary, BadBin});
+ {ok, UnexpectedReply2} ->
+ tsf({unexpected_reply, UnexpectedReply2});
+ {error, _} = Error2 ->
+ tsf({bad_reply, Error2})
+ end;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+%%-------------------------------------------------------------------------
+http_post(doc) ->
+ ["Test http post request against local server. We do in this case"
+ " only care about the client side of the the post. The server"
+ " script will not actually use the post data."];
+http_post(suite) ->
+ [];
+http_post(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+
+ URL = case test_server:os_type() of
+ {win32, _} ->
+ ?URL_START ++ integer_to_list(Port) ++
+ "/cgi-bin/cgi_echo.exe";
+ _ ->
+ ?URL_START ++ integer_to_list(Port) ++
+ "/cgi-bin/cgi_echo"
+
+ end,
+ %% Cgi-script expects the body length to be 100
+ Body = lists:duplicate(100, "1"),
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(post, {URL, [{"expect","100-continue"}],
+ "text/plain", Body}, [], []),
+
+ {ok, {{_,504,_}, [_ | _], []}} =
+ http:request(post, {URL, [{"expect","100-continue"}],
+ "text/plain", "foobar"}, [], []);
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+%%-------------------------------------------------------------------------
+http_emulate_lower_versions(doc) ->
+ ["Perform request as 0.9 and 1.0 clients."];
+http_emulate_lower_versions(suite) ->
+ [];
+http_emulate_lower_versions(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, Body0} =
+ http:request(get, {URL, []}, [{version, "HTTP/0.9"}], []),
+ inets_test_lib:check_body(Body0),
+ {ok, {{"HTTP/1.0", 200, _}, [_ | _], Body1 = [_ | _]}} =
+ http:request(get, {URL, []}, [{version, "HTTP/1.0"}], []),
+ inets_test_lib:check_body(Body1),
+ {ok, {{"HTTP/1.1", 200, _}, [_ | _], Body2 = [_ | _]}} =
+ http:request(get, {URL, []}, [{version, "HTTP/1.1"}], []),
+ inets_test_lib:check_body(Body2);
+ _->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+
+http_relaxed(doc) ->
+ ["Test relaxed mode"];
+http_relaxed(suite) ->
+ [];
+http_relaxed(Config) when is_list(Config) ->
+ ok = http:set_options([{ipv6, disabled}]), % also test the old option
+ %% ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++
+ "/missing_reason_phrase.html",
+
+ {error, Reason} =
+ http:request(get, {URL, []}, [{relaxed, false}], []),
+
+ test_server:format("Not relaxed: ~p~n", [Reason]),
+
+ {ok, {{_, 200, _}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, []}, [{relaxed, true}], []),
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipv6, enabled}]),
+ %% ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+http_dummy_pipe(doc) ->
+ ["Test pipelining code."];
+http_dummy_pipe(suite) ->
+ [];
+http_dummy_pipe(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/foobar.html",
+
+ test_pipeline(URL),
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+http_inets_pipe(doc) ->
+ ["Test pipelining code."];
+http_inets_pipe(suite) ->
+ [];
+http_inets_pipe(Config) when is_list(Config) ->
+
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ test_pipeline(URL);
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+test_pipeline(URL) ->
+ p("test_pipeline -> entry with"
+ "~n URL: ~p", [URL]),
+
+ http:set_options([{pipeline_timeout, 50000}]),
+
+ p("test_pipeline -> issue (async) request 1"),
+ {ok, RequestId1} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ test_server:format("RequestId1: ~p~n", [RequestId1]),
+ p("test_pipeline -> RequestId1: ~p", [RequestId1]),
+
+ %% Make sure pipeline is initiated
+ p("test_pipeline -> sleep some", []),
+ test_server:sleep(4000),
+
+ p("test_pipeline -> issue (async) request 2"),
+ {ok, RequestId2} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ tsp("RequestId2: ~p", [RequestId2]),
+ p("test_pipeline -> RequestId2: ~p", [RequestId2]),
+
+ p("test_pipeline -> issue (sync) request 3"),
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, []}, [], []),
+
+ p("test_pipeline -> expect reply for (async) request 1 or 2"),
+ receive
+ {http, {RequestId1, {{_, 200, _}, _, _}}} ->
+ p("test_pipeline -> received reply for (async) request 1 - now wait for 2"),
+ receive
+ {http, {RequestId2, {{_, 200, _}, _, _}}} ->
+ p("test_pipeline -> received reply for (async) request 2"),
+ ok;
+ {http, Msg1} ->
+ test_server:fail(Msg1)
+ end;
+ {http, {RequestId2, {{_, 200, _}, _, _}}} ->
+ io:format("test_pipeline -> received reply for (async) request 2 - now wait for 1"),
+ receive
+ {http, {RequestId1, {{_, 200, _}, _, _}}} ->
+ io:format("test_pipeline -> received reply for (async) request 1"),
+ ok;
+ {http, Msg2} ->
+ test_server:fail(Msg2)
+ end;
+ {http, Msg3} ->
+ test_server:fail(Msg3)
+ after 60000 ->
+ receive Any1 ->
+ tsp("received crap after timeout: ~n ~p", [Any1]),
+ test_server:fail({error, {timeout, Any1}})
+ end
+ end,
+
+ p("test_pipeline -> sleep some"),
+ test_server:sleep(4000),
+
+ p("test_pipeline -> issue (async) request 4"),
+ {ok, RequestId3} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ tsp("RequestId3: ~p", [RequestId3]),
+ p("test_pipeline -> RequestId3: ~p", [RequestId3]),
+
+ p("test_pipeline -> issue (async) request 5"),
+ {ok, RequestId4} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ tsp("RequestId4: ~p~n", [RequestId4]),
+ p("test_pipeline -> RequestId4: ~p", [RequestId4]),
+
+ p("test_pipeline -> cancel (async) request 4"),
+ ok = http:cancel_request(RequestId3),
+
+ p("test_pipeline -> expect *no* reply for cancelled (async) request 4 (for 3 secs)"),
+ receive
+ {http, {RequestId3, _}} ->
+ test_server:fail(http_cancel_request_failed)
+ after 3000 ->
+ ok
+ end,
+
+ p("test_pipeline -> expect reply for (async) request 4"),
+ Body =
+ receive
+ {http, {RequestId4, {{_, 200, _}, _, BinBody4}}} = Res ->
+ p("test_pipeline -> received reply for (async) request 5"),
+ tsp("Receive : ~p", [Res]),
+ BinBody4;
+ {http, Msg4} ->
+ test_server:fail(Msg4)
+ after 60000 ->
+ receive Any2 ->
+ tsp("received crap after timeout: ~n ~p", [Any2]),
+ test_server:fail({error, {timeout, Any2}})
+ end
+ end,
+
+ p("test_pipeline -> check reply for (async) request 5"),
+ inets_test_lib:check_body(binary_to_list(Body)),
+
+ p("test_pipeline -> ensure no unexpected incomming"),
+ receive
+ {http, Any} ->
+ test_server:fail({unexpected_message, Any})
+ after 500 ->
+ ok
+ end,
+
+ p("test_pipeline -> done"),
+ ok.
+
+
+
+%%-------------------------------------------------------------------------
+http_trace(doc) ->
+ ["Perform a TRACE request that goes through a proxy."];
+http_trace(suite) ->
+ [];
+http_trace(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ case http:request(trace, {URL, []}, [], []) of
+ {ok, {{_,200,_}, [_ | _], "TRACE /dummy.html" ++ _}} ->
+ ok;
+ {ok, {{_,200,_}, [_ | _], WrongBody}} ->
+ test_server:fail({wrong_body, WrongBody});
+ {ok, WrongReply} ->
+ test_server:fail({wrong_reply, WrongReply});
+ Error ->
+ test_server:fail({failed, Error})
+ end;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+%%-------------------------------------------------------------------------
+http_async(doc) ->
+ ["Test an asynchrony http request."];
+http_async(suite) ->
+ [];
+http_async(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, RequestId} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+
+ Body =
+ receive
+ {http, {RequestId, {{_, 200, _}, _, BinBody}}} ->
+ BinBody;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
+
+ inets_test_lib:check_body(binary_to_list(Body)),
+
+ {ok, NewRequestId} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ ok = http:cancel_request(NewRequestId),
+ receive
+ {http, {NewRequestId, _NewResult}} ->
+ test_server:fail(http_cancel_request_failed)
+ after 3000 ->
+ ok
+ end;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+%%-------------------------------------------------------------------------
+http_save_to_file(doc) ->
+ ["Test to save the http body to a file"];
+http_save_to_file(suite) ->
+ [];
+http_save_to_file(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ PrivDir = ?config(priv_dir, Config),
+ FilePath = filename:join(PrivDir, "dummy.html"),
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, saved_to_file}
+ = http:request(get, {URL, []}, [], [{stream, FilePath}]),
+ {ok, Bin} = file:read_file(FilePath),
+ {ok, {{_,200,_}, [_ | _], Body}} = http:request(URL),
+ Bin == Body;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+http_save_to_file_async(doc) ->
+ ["Test to save the http body to a file"];
+http_save_to_file_async(suite) ->
+ [];
+http_save_to_file_async(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ PrivDir = ?config(priv_dir, Config),
+ FilePath = filename:join(PrivDir, "dummy.html"),
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, RequestId} = http:request(get, {URL, []}, [],
+ [{stream, FilePath},
+ {sync, false}]),
+ receive
+ {http, {RequestId, saved_to_file}} ->
+ ok;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
+
+ {ok, Bin} = file:read_file(FilePath),
+ {ok, {{_,200,_}, [_ | _], Body}} = http:request(URL),
+ Bin == Body;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+%%-------------------------------------------------------------------------
+http_headers(doc) ->
+ ["Use as many request headers as possible not used in proxy_headers"];
+http_headers(suite) ->
+ [];
+http_headers(Config) when is_list(Config) ->
+
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ DocRoot = ?config(doc_root, Config),
+ {ok, FileInfo} =
+ file:read_file_info(filename:join([DocRoot,"dummy.html"])),
+ CreatedSec =
+ calendar:datetime_to_gregorian_seconds(
+ FileInfo#file_info.mtime),
+
+ Mod = httpd_util:rfc1123_date(
+ calendar:gregorian_seconds_to_datetime(
+ CreatedSec-1)),
+
+ Date = httpd_util:rfc1123_date({date(), time()}),
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, [{"If-Modified-Since",
+ Mod},
+ {"From","[email protected]"},
+ {"Date", Date}
+ ]}, [], []),
+
+ Mod1 = httpd_util:rfc1123_date(
+ calendar:gregorian_seconds_to_datetime(
+ CreatedSec+1)),
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, [{"If-UnModified-Since",
+ Mod1}
+ ]}, [], []),
+
+ Tag = httpd_util:create_etag(FileInfo),
+
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, [{"If-Match",
+ Tag}
+ ]}, [], []),
+
+ {ok, {{_,200,_}, [_ | _], _}} =
+ http:request(get, {URL, [{"If-None-Match",
+ "NotEtag,NeihterEtag"},
+ {"Connection", "Close"}
+ ]}, [], []),
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+%%-------------------------------------------------------------------------
+http_headers_dummy(doc) ->
+ ["Test the code for handling headers we do not want/can send "
+ "to a real server. Note it is not logical to send"
+ "all of these headers together, we only want to test that"
+ "the code for handling headers will not crash."];
+http_headers_dummy(suite) ->
+ [];
+http_headers_dummy(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy_headers.html",
+
+ Foo = http_chunk:encode("foobar") ++
+ binary_to_list(http_chunk:encode_last()),
+ FooBar = Foo ++ "\r\n\r\nOther:inets_test\r\n\r\n",
+
+ UserPasswd = base64:encode_to_string("Alladin:Sesame"),
+ Auth = "Basic " ++ UserPasswd,
+
+ %% The dummy server will ignore the headers, we only want to test
+ %% that the client header-handling code. This would not
+ %% be a vaild http-request!
+ {ok, {{_,200,_}, [_ | _], [_|_]}} =
+ http:request(post,
+ {URL,
+ [{"Via",
+ "1.0 fred, 1.1 nowhere.com (Apache/1.1)"},
+ {"Warning","1#pseudonym foobar"},
+ {"Vary","*"},
+ {"Upgrade","HTTP/2.0"},
+ {"Pragma", "1#no-cache"},
+ {"Cache-Control", "no-cache"},
+ {"Connection", "close"},
+ {"Date", "Sat, 29 Oct 1994 19:43:31 GMT"},
+ {"Accept", " text/plain; q=0.5, text/html"},
+ {"Accept-Language", "en"},
+ {"Accept-Encoding","chunked"},
+ {"Accept-Charset", "ISO8859-1"},
+ {"Authorization", Auth},
+ {"Expect", "1#100-continue"},
+ {"User-Agent","inets"},
+ {"Transfer-Encoding","chunked"},
+ {"Range", " bytes=0-499"},
+ {"If-Range", "Sat, 29 Oct 1994 19:43:31 GMT"},
+ {"If-Match", "*"},
+ {"Content-Type", "text/plain"},
+ {"Content-Encoding", "chunked"},
+ {"Content-Length", "6"},
+ {"Content-Language", "en"},
+ {"Content-Location", "http://www.foobar.se"},
+ {"Content-MD5",
+ "104528739076276072743283077410617235478"},
+ {"Content-Range", "bytes 0-499/1234"},
+ {"Allow", "GET"},
+ {"Proxy-Authorization", Auth},
+ {"Expires", "Sat, 29 Oct 1994 19:43:31 GMT"},
+ {"Upgrade", "HTTP/2.0"},
+ {"Last-Modified", "Sat, 29 Oct 1994 19:43:31 GMT"},
+ {"Trailer","1#User-Agent"}
+ ], "text/plain", FooBar},
+ [], []),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+http_bad_response(doc) ->
+ ["Test what happens when the server does not follow the protocol"];
+http_bad_response(suite) ->
+ [];
+http_bad_response(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_crlf.html",
+
+ URL1 = ?URL_START ++ integer_to_list(Port) ++ "/wrong_statusline.html",
+
+ {error, timeout} = http:request(get, {URL, []}, [{timeout, 400}], []),
+
+ {error, Reason} = http:request(URL1),
+
+ test_server:format("Wrong Statusline: ~p~n", [Reason]),
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+ssl_head(doc) ->
+ ["Same as http_head/1 but over ssl sockets."];
+ssl_head(suite) ->
+ [];
+ssl_head(Config) when is_list(Config) ->
+ case ?config(local_ssl_server, Config) of
+ ok ->
+ DataDir = ?config(data_dir, Config),
+ Port = ?config(local_ssl_port, Config),
+ URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ CertFile = filename:join(DataDir, "ssl_client_cert.pem"),
+ SSLOptions = [{certfile, CertFile}, {keyfile, CertFile}],
+ {ok, {{_,200, _}, [_ | _], []}} =
+ http:request(head, {URL, []}, [{ssl, SSLOptions}], []);
+ {ok, _} ->
+ {skip, "Failed to start local http-server"};
+ _ ->
+ {skip, "Failed to start SSL"}
+ end.
+%%-------------------------------------------------------------------------
+ssl_get(doc) ->
+ ["Same as http_get/1 but over ssl sockets."];
+ssl_get(suite) ->
+ [];
+ssl_get(Config) when is_list(Config) ->
+ case ?config(local_ssl_server, Config) of
+ ok ->
+ DataDir = ?config(data_dir, Config),
+ Port = ?config(local_ssl_port, Config),
+ URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ CertFile = filename:join(DataDir, "ssl_client_cert.pem"),
+ SSLOptions = [{certfile, CertFile}, {keyfile, CertFile}],
+ {ok, {{_,200, _}, [_ | _], Body = [_ | _]}} =
+ http:request(get, {URL, []}, [{ssl, SSLOptions}], []),
+ inets_test_lib:check_body(Body);
+ {ok, _} ->
+ {skip, "Failed to start local http-server"};
+ _ ->
+ {skip, "Failed to start SSL"}
+ end.
+%%-------------------------------------------------------------------------
+ssl_trace(doc) ->
+ ["Same as http_trace/1 but over ssl sockets."];
+ssl_trace(suite) ->
+ [];
+ssl_trace(Config) when is_list(Config) ->
+ case ?config(local_ssl_server, Config) of
+ ok ->
+ DataDir = ?config(data_dir, Config),
+ Port = ?config(local_ssl_port, Config),
+ URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ CertFile = filename:join(DataDir, "ssl_client_cert.pem"),
+ SSLOptions = [{certfile, CertFile}, {keyfile, CertFile}],
+ case http:request(trace, {URL, []}, [{ssl, SSLOptions}], []) of
+ {ok, {{_,200, _}, [_ | _], "TRACE /dummy.html" ++ _}} ->
+ ok;
+ {ok, {{_,200,_}, [_ | _], WrongBody}} ->
+ test_server:fail({wrong_body, WrongBody});
+ {ok, WrongReply} ->
+ test_server:fail({wrong_reply, WrongReply});
+ Error ->
+ test_server:fail({failed, Error})
+ end;
+ {ok, _} ->
+ {skip, "Failed to start local http-server"};
+ _ ->
+ {skip, "Failed to start SSL"}
+ end.
+%%-------------------------------------------------------------------------
+http_redirect(doc) ->
+ ["Test redirect with dummy server as httpd does not implement"
+ " server redirect"];
+http_redirect(suite) ->
+ [];
+http_redirect(Config) when is_list(Config) ->
+ tsp("http_redirect -> entry with"
+ "~n Config: ~p", [Config]),
+ case ?config(local_server, Config) of
+ ok ->
+ tsp("http_redirect -> set ipfamily option to inet"),
+ ok = http:set_options([{ipfamily, inet}]),
+
+ tsp("http_redirect -> start dummy server inet"),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ tsp("http_redirect -> server port = ~p", [Port]),
+
+ URL300 = ?URL_START ++ integer_to_list(Port) ++ "/300.html",
+
+ tsp("http_redirect -> issue request 1: "
+ "~n ~p", [URL300]),
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URL300, []}, [], []),
+
+ tsp("http_redirect -> issue request 2: "
+ "~n ~p", [URL300]),
+ {ok, {{_,300,_}, [_ | _], _}} =
+ http:request(get, {URL300, []}, [{autoredirect, false}], []),
+
+ URL301 = ?URL_START ++ integer_to_list(Port) ++ "/301.html",
+
+ tsp("http_redirect -> issue request 3: "
+ "~n ~p", [URL301]),
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URL301, []}, [], []),
+
+ tsp("http_redirect -> issue request 4: "
+ "~n ~p", [URL301]),
+ {ok, {{_,200,_}, [_ | _], []}}
+ = http:request(head, {URL301, []}, [], []),
+
+ tsp("http_redirect -> issue request 5: "
+ "~n ~p", [URL301]),
+ {ok, {{_,301,_}, [_ | _], [_|_]}}
+ = http:request(post, {URL301, [],"text/plain", "foobar"},
+ [], []),
+
+ URL302 = ?URL_START ++ integer_to_list(Port) ++ "/302.html",
+
+ tsp("http_redirect -> issue request 6: "
+ "~n ~p", [URL302]),
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URL302, []}, [], []),
+ case http:request(get, {URL302, []}, [], []) of
+ {ok, Reply7} ->
+ case Reply7 of
+ {{_,200,_}, [_ | _], [_|_]} ->
+ tsp("http_redirect -> "
+ "expected reply for request 7"),
+ ok;
+ {StatusLine, Headers, Body} ->
+ tsp("http_redirect -> "
+ "unexpected reply for request 7: "
+ "~n StatusLine: ~p"
+ "~n Headers: ~p"
+ "~n Body: ~p",
+ [StatusLine, Headers, Body]),
+ tsf({unexpected_reply, Reply7})
+ end;
+ Error7 ->
+ tsp("http_redirect -> "
+ "unexpected result for request 7: "
+ "~n Error7: ~p",
+ [Error7]),
+ tsf({unexpected_result, Error7})
+ end,
+
+ tsp("http_redirect -> issue request 7: "
+ "~n ~p", [URL302]),
+ {ok, {{_,200,_}, [_ | _], []}}
+ = http:request(head, {URL302, []}, [], []),
+
+ tsp("http_redirect -> issue request 8: "
+ "~n ~p", [URL302]),
+ {ok, {{_,302,_}, [_ | _], [_|_]}}
+ = http:request(post, {URL302, [],"text/plain", "foobar"},
+ [], []),
+
+ URL307 = ?URL_START ++ integer_to_list(Port) ++ "/307.html",
+
+ tsp("http_redirect -> issue request 9: "
+ "~n ~p", [URL307]),
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URL307, []}, [], []),
+
+ tsp("http_redirect -> issue request 10: "
+ "~n ~p", [URL307]),
+ {ok, {{_,200,_}, [_ | _], []}}
+ = http:request(head, {URL307, []}, [], []),
+
+ tsp("http_redirect -> issue request 11: "
+ "~n ~p", [URL307]),
+ {ok, {{_,307,_}, [_ | _], [_|_]}}
+ = http:request(post, {URL307, [],"text/plain", "foobar"},
+ [], []),
+
+ tsp("http_redirect -> stop dummy server"),
+ DummyServerPid ! stop,
+ tsp("http_redirect -> reset ipfamily option (to inet6fb4)"),
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ tsp("http_redirect -> done"),
+ ok;
+
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+
+%%-------------------------------------------------------------------------
+http_redirect_loop(doc) ->
+ ["Test redirect loop detection"];
+http_redirect_loop(suite) ->
+ [];
+http_redirect_loop(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/redirectloop.html",
+
+ {ok, {{_,300,_}, [_ | _], _}}
+ = http:request(get, {URL, []}, [], []),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+%%-------------------------------------------------------------------------
+http_internal_server_error(doc) ->
+ ["Test 50X codes"];
+http_internal_server_error(suite) ->
+ [];
+http_internal_server_error(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL500 = ?URL_START ++ integer_to_list(Port) ++ "/500.html",
+
+ {ok, {{_,500,_}, [_ | _], _}}
+ = http:request(get, {URL500, []}, [], []),
+
+
+ URL503 = ?URL_START ++ integer_to_list(Port) ++ "/503.html",
+
+ %% Used to be able to make the service available after retry.
+ ets:new(unavailable, [named_table, public, set]),
+ ets:insert(unavailable, {503, unavailable}),
+
+ {ok, {{_,200, _}, [_ | _], [_|_]}} =
+ http:request(get, {URL503, []}, [], []),
+
+ ets:insert(unavailable, {503, long_unavailable}),
+
+ {ok, {{_,503, _}, [_ | _], [_|_]}} =
+ http:request(get, {URL503, []}, [], []),
+
+ ets:delete(unavailable),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+http_userinfo(doc) ->
+ ["Test user info e.i. http://user:passwd@host:port/"];
+http_userinfo(suite) ->
+ [];
+http_userinfo(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URLAuth = "http://alladin:sesame@localhost:"
+ ++ integer_to_list(Port) ++ "/userinfo.html",
+
+ {ok, {{_,200,_}, [_ | _], _}}
+ = http:request(get, {URLAuth, []}, [], []),
+
+ URLUnAuth = "http://alladin:foobar@localhost:"
+ ++ integer_to_list(Port) ++ "/userinfo.html",
+
+ {ok, {{_,401, _}, [_ | _], _}} =
+ http:request(get, {URLUnAuth, []}, [], []),
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+http_cookie(doc) ->
+ ["Test cookies."];
+http_cookie(suite) ->
+ [];
+http_cookie(Config) when is_list(Config) ->
+ ok = http:set_options([{cookies, enabled}, {ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URLStart = ?URL_START
+ ++ integer_to_list(Port),
+
+ URLCookie = URLStart ++ "/cookie.html",
+
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URLCookie, []}, [], []),
+
+ ets:new(cookie, [named_table, public, set]),
+ ets:insert(cookie, {cookies, true}),
+
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URLStart ++ "/", []}, [], []),
+
+ ets:delete(cookie),
+
+ ok = http:set_options([{cookies, disabled}, {ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6************
+ ok.
+
+%%-------------------------------------------------------------------------
+proxy_options(doc) ->
+ ["Perform a OPTIONS request that goes through a proxy."];
+proxy_options(suite) ->
+ [];
+proxy_options(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ case http:request(options, {?PROXY_URL, []}, [], []) of
+ {ok, {{_,200,_}, Headers, _}} ->
+ case lists:keysearch("allow", 1, Headers) of
+ {value, {"allow", _}} ->
+ ok;
+ _ ->
+ test_server:fail(http_options_request_failed)
+ end;
+ Unexpected ->
+ test_server:fail({unexpected_result, Unexpected})
+ end;
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+proxy_head(doc) ->
+ ["Perform a HEAD request that goes through a proxy."];
+proxy_head(suite) ->
+ [];
+proxy_head(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ case http:request(head, {?PROXY_URL, []}, [], []) of
+ {ok, {{_,200, _}, [_ | _], []}} ->
+ ok;
+ Unexpected ->
+ test_server:fail({unexpected_result, Unexpected})
+ end;
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+proxy_get(doc) ->
+ ["Perform a GET request that goes through a proxy."];
+proxy_get(suite) ->
+ [];
+proxy_get(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ case http:request(get, {?PROXY_URL, []}, [], []) of
+ {ok, {{_,200,_}, [_ | _], Body = [_ | _]}} ->
+ inets_test_lib:check_body(Body);
+ Unexpected ->
+ test_server:fail({unexpected_result, Unexpected})
+ end;
+ Reason ->
+ {skip, Reason}
+ end.
+
+%%-------------------------------------------------------------------------
+proxy_emulate_lower_versions(doc) ->
+ ["Perform requests as 0.9 and 1.0 clients."];
+proxy_emulate_lower_versions(suite) ->
+ [];
+proxy_emulate_lower_versions(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ Result09 = pelv_get("HTTP/0.9"),
+ case Result09 of
+ {ok, [_| _] = Body0} ->
+ inets_test_lib:check_body(Body0),
+ ok;
+ _ ->
+ tsf({unexpected_result, "HTTP/0.9", Result09})
+ end,
+
+ %% We do not check the version here as many servers
+ %% do not behave according to the rfc and send
+ %% 1.1 in its response.
+ Result10 = pelv_get("HTTP/1.0"),
+ case Result10 of
+ {ok,{{_, 200, _}, [_ | _], Body1 = [_ | _]}} ->
+ inets_test_lib:check_body(Body1),
+ ok;
+ _ ->
+ tsf({unexpected_result, "HTTP/1.0", Result10})
+ end,
+
+ Result11 = pelv_get("HTTP/1.1"),
+ case Result11 of
+ {ok, {{"HTTP/1.1", 200, _}, [_ | _], Body2 = [_ | _]}} ->
+ inets_test_lib:check_body(Body2);
+ _ ->
+ tsf({unexpected_result, "HTTP/1.1", Result11})
+ end;
+
+ Reason ->
+ {skip, Reason}
+ end.
+
+pelv_get(Version) ->
+ http:request(get, {?PROXY_URL, []}, [{version, Version}], []).
+
+%%-------------------------------------------------------------------------
+proxy_trace(doc) ->
+ ["Perform a TRACE request that goes through a proxy."];
+proxy_trace(suite) ->
+ [];
+proxy_trace(Config) when is_list(Config) ->
+ %%{ok, {{_,200,_}, [_ | _], "TRACE " ++ _}} =
+ %% http:request(trace, {?PROXY_URL, []}, [], []),
+ {skip, "HTTP TRACE is no longer allowed on the ?PROXY_URL server due "
+ "to security reasons"}.
+
+
+%%-------------------------------------------------------------------------
+proxy_post(doc) ->
+ ["Perform a POST request that goes through a proxy. Note the server"
+ " will reject the request this is a test of the sending of the"
+ " request."];
+proxy_post(suite) ->
+ [];
+proxy_post(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ case http:request(post, {?PROXY_URL, [],
+ "text/plain", "foobar"}, [],[]) of
+ {ok, {{_,405,_}, [_ | _], [_ | _]}} ->
+ ok;
+ Unexpected ->
+ test_server:fail({unexpected_result, Unexpected})
+ end;
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+proxy_put(doc) ->
+ ["Perform a PUT request that goes through a proxy. Note the server"
+ " will reject the request this is a test of the sending of the"
+ " request."];
+proxy_put(suite) ->
+ [];
+proxy_put(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ case http:request(put, {"http://www.erlang.org/foobar.html", [],
+ "html", "<html> <body><h1> foo </h1>"
+ "<p>bar</p> </body></html>"}, [], []) of
+ {ok, {{_,405,_}, [_ | _], [_ | _]}} ->
+ ok;
+ Unexpected ->
+ test_server:fail({unexpected_result, Unexpected})
+ end;
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+proxy_delete(doc) ->
+ ["Perform a DELETE request that goes through a proxy. Note the server"
+ " will reject the request this is a test of the sending of the"
+ " request. But as the file does not exist the return code will"
+ " be 404 not found."];
+proxy_delete(suite) ->
+ [];
+proxy_delete(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ URL = ?PROXY_URL ++ "/foobar.html",
+ case http:request(delete, {URL, []}, [], []) of
+ {ok, {{_,404,_}, [_ | _], [_ | _]}} ->
+ ok;
+ Unexpected ->
+ test_server:fail({unexpected_result, Unexpected})
+ end;
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+proxy_headers(doc) ->
+ ["Use as many request headers as possible"];
+proxy_headers(suite) ->
+ [];
+proxy_headers(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ {ok, {{_,200,_}, [_ | _], [_ | _]}}
+ = http:request(get, {?PROXY_URL,
+ [
+ {"Accept",
+ "text/*, text/html,"
+ " text/html;level=1,"
+ " */*"},
+ {"Accept-Charset",
+ "iso-8859-5, unicode-1-1;"
+ "q=0.8"},
+ {"Accept-Encoding", "*"},
+ {"Accept-Language",
+ "sv, en-gb;q=0.8,"
+ " en;q=0.7"},
+ {"User-Agent", "inets"},
+ {"Max-Forwards","5"},
+ {"Referer",
+ "http://otp.ericsson.se:8000"
+ "/product/internal"}
+ ]}, [], []),
+ ok;
+ Reason ->
+ {skip, Reason}
+ end.
+
+%%-------------------------------------------------------------------------
+proxy_auth(doc) ->
+ ["Test the code for sending of proxy authorization."];
+proxy_auth(suite) ->
+ [];
+proxy_auth(Config) when is_list(Config) ->
+ %% Our proxy seems to ignore the header, however our proxy
+ %% does not requirer an auth header, but we want to know
+ %% atleast the code for sending the header does not crash!
+ case ?config(skip, Config) of
+ undefined ->
+ case http:request(get, {?PROXY_URL, []},
+ [{proxy_auth, {"foo", "bar"}}], []) of
+ {ok, {{_,200, _}, [_ | _], [_|_]}} ->
+ ok;
+ Unexpected ->
+ test_server:fail({unexpected_result, Unexpected})
+ end;
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+http_server_does_not_exist(doc) ->
+ ["Test that we get an error message back when the server "
+ "does note exist."];
+http_server_does_not_exist(suite) ->
+ [];
+http_server_does_not_exist(Config) when is_list(Config) ->
+ {error, _} =
+ http:request(get, {"http://localhost:" ++
+ integer_to_list(?NOT_IN_USE_PORT)
+ ++ "/", []},[], []),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+page_does_not_exist(doc) ->
+ ["Test that we get a 404 when the page is not found."];
+page_does_not_exist(suite) ->
+ [];
+page_does_not_exist(Config) when is_list(Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/doesnotexist.html",
+ {ok, {{_,404,_}, [_ | _], [_ | _]}}
+ = http:request(get, {URL, []}, [], []),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+proxy_page_does_not_exist(doc) ->
+ ["Test that we get a 404 when the page is not found."];
+proxy_page_does_not_exist(suite) ->
+ [];
+proxy_page_does_not_exist(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ URL = ?PROXY_URL ++ "/doesnotexist.html",
+ {ok, {{_,404,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, []}, [], []),
+ ok;
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+proxy_https_not_supported(doc) ->
+ [];
+proxy_https_not_supported(suite) ->
+ [];
+proxy_https_not_supported(Config) when is_list(Config) ->
+ {error, {failed_connecting, https_through_proxy_is_not_currently_supported}} =
+ http:request(get, {"https://login.yahoo.com", []}, [], []),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+http_stream(doc) ->
+ ["Test the option stream for asynchrony requests"];
+http_stream(suite) ->
+ [];
+http_stream(Config) when is_list(Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, {{_,200,_}, [_ | _], Body}} =
+ http:request(get, {URL, []}, [], []),
+
+ {ok, RequestId} =
+ http:request(get, {URL, []}, [], [{sync, false},
+ {stream, self}]),
+
+ receive
+ {http, {RequestId, stream_start, _Headers}} ->
+ ok;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
+
+ StreamedBody = receive_streamed_body(RequestId, <<>>),
+
+ Body == binary_to_list(StreamedBody).
+
+
+%%-------------------------------------------------------------------------
+http_stream_once(doc) ->
+ ["Test the option stream for asynchrony requests"];
+http_stream_once(suite) ->
+ [];
+http_stream_once(Config) when is_list(Config) ->
+ p("http_stream_once -> entry with"
+ "~n Config: ~p", [Config]),
+
+ p("http_stream_once -> set ipfamily to inet", []),
+ ok = http:set_options([{ipfamily, inet}]),
+ p("http_stream_once -> start dummy server", []),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ PortStr = integer_to_list(Port),
+ p("http_stream_once -> once", []),
+ once(?URL_START ++ PortStr ++ "/once.html"),
+ p("http_stream_once -> once_chunked", []),
+ once(?URL_START ++ PortStr ++ "/once_chunked.html"),
+ p("http_stream_once -> dummy", []),
+ once(?URL_START ++ PortStr ++ "/dummy.html"),
+
+ p("http_stream_once -> stop dummy server", []),
+ DummyServerPid ! stop,
+ p("http_stream_once -> set ipfamily to inet6fb4", []),
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ p("http_stream_once -> done", []),
+ ok.
+
+once(URL) ->
+ p("once -> issue sync request for ~p", [URL]),
+ {ok, {{_,200,_}, [_ | _], Body}} =
+ http:request(get, {URL, []}, [], []),
+
+ p("once -> issue async (self stream) request for ~p", [URL]),
+ {ok, RequestId} =
+ http:request(get, {URL, []}, [], [{sync, false},
+ {stream, {self, once}}]),
+
+ p("once -> await stream_start reply for (async) request ~p", [RequestId]),
+ NewPid =
+ receive
+ {http, {RequestId, stream_start, _Headers, Pid}} ->
+ p("once -> received stream_start reply for (async) request ~p: ~p",
+ [RequestId, Pid]),
+ Pid;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
+
+ tsp("once -> request handler: ~p", [NewPid]),
+
+ p("once -> await stream reply for (async) request ~p", [RequestId]),
+ BodyPart =
+ receive
+ {http, {RequestId, stream, BinBodyPart}} ->
+ p("once -> received stream reply for (async) request ~p: "
+ "~n~p", [RequestId, binary_to_list(BinBodyPart)]),
+ BinBodyPart
+ end,
+
+ tsp("once -> first body part '~p' received", [binary_to_list(BodyPart)]),
+
+ StreamedBody = receive_streamed_body(RequestId, BinBodyPart, NewPid),
+
+ Body = binary_to_list(StreamedBody),
+
+ p("once -> done when Bode: ~p", [Body]),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+proxy_stream(doc) ->
+ ["Test the option stream for asynchrony requests"];
+proxy_stream(suite) ->
+ [];
+proxy_stream(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ {ok, {{_,200,_}, [_ | _], Body}} =
+ http:request(get, {?PROXY_URL, []}, [], []),
+
+ {ok, RequestId} =
+ http:request(get, {?PROXY_URL, []}, [],
+ [{sync, false}, {stream, self}]),
+
+ receive
+ {http, {RequestId, stream_start, _Headers}} ->
+ ok;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
+
+ StreamedBody = receive_streamed_body(RequestId, <<>>),
+
+ Body == binary_to_list(StreamedBody);
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+parse_url(doc) ->
+ ["Test that an url is parsed correctly"];
+parse_url(suite) ->
+ [];
+parse_url(Config) when is_list(Config) ->
+ %% ipv6
+ {http,[],"2010:836B:4179::836B:4179",80,"/foobar.html",[]}
+ = http_uri:parse("http://[2010:836B:4179::836B:4179]/foobar.html"),
+ {error,
+ {malformed_url,"http://2010:836B:4179::836B:4179/foobar.html"}} =
+ http_uri:parse("http://2010:836B:4179::836B:4179/foobar.html"),
+
+ %% ipv4
+ {http,[],"127.0.0.1",80,"/foobar.html",[]} =
+ http_uri:parse("http://127.0.0.1/foobar.html"),
+
+ %% host
+ {http,[],"localhost",8888,"/foobar.html",[]} =
+ http_uri:parse("http://localhost:8888/foobar.html"),
+
+ %% Userinfo
+ {http,"nisse:foobar","localhost",8888,"/foobar.html",[]} =
+ http_uri:parse("http://nisse:foobar@localhost:8888/foobar.html"),
+
+ %% Scheme error
+ {error,no_scheme} = http_uri:parse("localhost/foobar.html"),
+ {error,{not_supported_scheme,localhost}} =
+ http_uri:parse("localhost:8888/foobar.html"),
+
+ %% Query
+ {http,[],"localhost",8888,"/foobar.html","?foo=bar&foobar=42"} =
+ http_uri:parse("http://localhost:8888/foobar.html?foo=bar&foobar=42"),
+
+ %% Esc chars
+ {http,[],"www.somedomain.com",80,"/%2Eabc",[]} =
+ http_uri:parse("http://www.somedomain.com/%2Eabc"),
+ {http,[],"www.somedomain.com",80,"/%252Eabc",[]} =
+ http_uri:parse("http://www.somedomain.com/%252Eabc"),
+ {http,[],"www.somedomain.com",80,"/%25abc",[]} =
+ http_uri:parse("http://www.somedomain.com/%25abc"),
+ {http,[],"www.somedomain.com",80,"/%25abc", "?foo=bar"} =
+ http_uri:parse("http://www.somedomain.com/%25abc?foo=bar"),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+ipv6(doc) ->
+ ["Test ipv6."];
+ipv6(suite) ->
+ [];
+ipv6(Config) when is_list(Config) ->
+ {ok, Hostname} = inet:gethostname(),
+
+ case lists:member(list_to_atom(Hostname),
+ ?config(ipv6_hosts, Config)) of
+ true ->
+ {DummyServerPid, Port} = dummy_server(self(), ipv6),
+
+ URL = "http://[" ++ ?IPV6_LOCAL_HOST ++ "]:" ++
+ integer_to_list(Port) ++ "/foobar.html",
+ {ok, {{_,200,_}, [_ | _], [_|_]}} =
+ http:request(get, {URL, []}, [], []),
+
+ DummyServerPid ! stop,
+ ok;
+ false ->
+ {skip, "Host does not support IPv6"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+headers_as_is(doc) ->
+ ["Test the option headers_as_is"];
+headers_as_is(suite) ->
+ [];
+headers_as_is(Config) when is_list(Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, {{_,200,_}, [_|_], [_|_]}} =
+ http:request(get, {URL, [{"Host", "localhost"},{"Te", ""}]},
+ [], [{headers_as_is, true}]),
+
+ {ok, {{_,400,_}, [_|_], [_|_]}} =
+ http:request(get, {URL, [{"Te", ""}]},[], [{headers_as_is, true}]),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+options(doc) ->
+ ["Test the option parameters."];
+options(suite) ->
+ [];
+options(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, {{_,200,_}, [_ | _], Bin}}
+ = http:request(get, {URL, []}, [{foo, bar}],
+ %% Ignore unknown options
+ [{body_format, binary}, {foo, bar}]),
+
+ true = is_binary(Bin),
+ {ok, {200, [_|_]}}
+ = http:request(get, {URL, []}, [{timeout, infinity}],
+ [{full_result, false}]);
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+http_invalid_http(doc) ->
+ ["Test parse error"];
+http_invalid_http(suite) ->
+ [];
+http_invalid_http(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/invalid_http.html",
+
+ {error, {could_not_parse_as_http, _} = Reason} =
+ http:request(get, {URL, []}, [], []),
+
+ test_server:format("Parse error: ~p ~n", [Reason]),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+hexed_query_otp_6191(doc) ->
+ [];
+hexed_query_otp_6191(suite) ->
+ [];
+hexed_query_otp_6191(Config) when is_list(Config) ->
+ Google = "www.google.com",
+ GoogleSearch = "http://" ++ Google ++ "/search",
+ Search1 = "?hl=en&q=a%D1%85%D1%83%D0%B9&btnG=Google+Search",
+ URI1 = GoogleSearch ++ Search1,
+ Search2 = "?hl=en&q=%25%25",
+ URI2 = GoogleSearch ++ Search2,
+ Search3 = "?hl=en&q=%foo",
+ URI3 = GoogleSearch ++ Search3,
+
+ {http, [], Google, 80, "/search", _} = http_uri:parse(URI1),
+ {http, [], Google, 80, "/search", _} = http_uri:parse(URI2),
+ {http, [], Google, 80, "/search", _} = http_uri:parse(URI3),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+empty_body_otp_6243(doc) ->
+ ["An empty body was not returned directly. There was a delay for several"
+ "seconds."];
+empty_body_otp_6243(suite) ->
+ [];
+empty_body_otp_6243(Config) when is_list(Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/empty.html",
+ {ok, {{_,200,_}, [_ | _], []}} =
+ http:request(get, {URL, []}, [{timeout, 500}], []).
+
+
+%%-------------------------------------------------------------------------
+
+transfer_encoding_otp_6807(doc) ->
+ ["Transfer encoding is case insensitive"];
+transfer_encoding_otp_6807(suite) ->
+ [];
+transfer_encoding_otp_6807(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++
+ "/capital_transfer_encoding.html",
+ {ok, {{_,200,_}, [_|_], [_ | _]}} = http:request(URL),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+proxy_not_modified_otp_6821(doc) ->
+ ["If unmodified no body should be returned"];
+proxy_not_modified_otp_6821(suite) ->
+ [];
+proxy_not_modified_otp_6821(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ provocate_not_modified_bug(?PROXY_URL);
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+
+empty_response_header_otp_6830(doc) ->
+ ["Test the case that the HTTP server does not send any headers"];
+empty_response_header_otp_6830(suite) ->
+ [];
+empty_response_header_otp_6830(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/no_headers.html",
+ {ok, {{_,200,_}, [], [_ | _]}} = http:request(URL),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+no_content_204_otp_6982(doc) ->
+ ["Test the case that the HTTP 204 no content header"];
+no_content_204_otp_6982(suite) ->
+ [];
+no_content_204_otp_6982(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/no_content.html",
+ {ok, {{_,204,_}, [], []}} = http:request(URL),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+missing_CR_otp_7304(doc) ->
+ ["Test the case that the HTTP server uses only LF instead of CRLF"
+ "as delimitor"];
+missing_CR_otp_7304(suite) ->
+ [];
+missing_CR_otp_7304(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_CR.html",
+ {ok, {{_,200,_}, _, [_ | _]}} = http:request(URL),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+otp_7883(suite) ->
+ [otp_7883_1, otp_7883_2].
+
+otp_7883_1(doc) ->
+ ["OTP-7883-sync"];
+otp_7883_1(suite) ->
+ [];
+otp_7883_1(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html",
+ {error, socket_closed_remotely} = http:request(URL),
+ DummyServerPid ! stop,
+
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+otp_7883_2(doc) ->
+ ["OTP-7883-async"];
+otp_7883_2(suite) ->
+ [];
+otp_7883_2(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html",
+ Method = get,
+ Request = {URL, []},
+ HttpOptions = [],
+ Options = [{sync, false}],
+ Profile = http:default_profile(),
+ {ok, RequestId} =
+ http:request(Method, Request, HttpOptions, Options, Profile),
+ ok =
+ receive
+ {http, {RequestId, {error, socket_closed_remotely}}} ->
+ ok
+ end,
+ DummyServerPid ! stop,
+
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+otp_8154(suite) ->
+ [otp_8154_1].
+
+otp_8154_1(doc) ->
+ ["OTP-8154"];
+otp_8154_1(suite) ->
+ [];
+otp_8154_1(Config) when is_list(Config) ->
+ start_inets(),
+ ReqSeqNumServer = start_sequence_number_server(),
+ RespSeqNumServer = start_sequence_number_server(),
+ {ok, Server, Port} = start_slow_server(RespSeqNumServer),
+ Clients = run_clients(105, Port, ReqSeqNumServer),
+ %% ok = wait_for_clients(Clients),
+ ok = wait4clients(Clients, timer:minutes(3)),
+ Server ! shutdown,
+ RespSeqNumServer ! shutdown,
+ ReqSeqNumServer ! shutdown,
+ ok.
+
+start_inets() ->
+ inets:start(),
+ ok.
+
+
+%% -----------------------------------------------------
+%% A sequence number handler
+%% The purpose is to be able to pair requests with responses.
+
+start_sequence_number_server() ->
+ proc_lib:spawn(fun() -> loop_sequence_number(1) end).
+
+loop_sequence_number(N) ->
+ receive
+ shutdown ->
+ ok;
+ {From, get_next} ->
+ From ! {next_is, N},
+ loop_sequence_number(N + 1)
+ end.
+
+get_next_sequence_number(SeqNumServer) ->
+ SeqNumServer ! {self(), get_next},
+ receive {next_is, N} -> N end.
+
+%% -----------------------------------------------------
+%% Client part
+%% Sends requests randomly parallel
+
+run_clients(NumClients, ServerPort, SeqNumServer) ->
+ io:format("start clients when"
+ "~n NumClients: ~w"
+ "~n ServerPort: ~w"
+ "~n SeqNumServer: ~w"
+ "~n", [NumClients, ServerPort, SeqNumServer]),
+ set_random_seed(),
+ lists:map(
+ fun(Id) ->
+ io:format("starting client ~w~n", [Id]),
+ Req = f("req~3..0w", [get_next_sequence_number(SeqNumServer)]),
+ Url = f(?URL_START ++ "~w/~s", [ServerPort, Req]),
+ Pid = proc_lib:spawn(
+ fun() ->
+ io:format("[~w] client started - "
+ "issue request~n", [Id]),
+ case http:request(Url) of
+ {ok, {{_,200,_}, _, Resp}} ->
+ io:format("[~w] 200 response: "
+ "~p~n", [Id, Resp]),
+ case lists:prefix(Req++"->", Resp) of
+ true -> exit(normal);
+ false -> exit({bad_resp,Req,Resp})
+ end;
+ {ok, {{_,EC,Reason},_,Resp}} ->
+ io:format("[~w] ~w response: "
+ "~s~n~s~n",
+ [Id, EC, Reason, Resp]),
+ exit({bad_resp,Req,Resp});
+ Crap ->
+ io:format("[~w] bad response: ~p",
+ [Id, Crap]),
+ exit({bad_resp, Req, Crap})
+ end
+ end),
+ MRef = erlang:monitor(process, Pid),
+ timer:sleep(10 + random:uniform(1334)),
+ {Id, Pid, MRef}
+
+ end,
+ lists:seq(1, NumClients)).
+
+%% wait_for_clients(Clients) ->
+%% lists:foreach(
+%% fun({Id, Pid, MRef}) ->
+%% io:format("waiting for client ~w termination~n", [Id]),
+%% receive
+%% {'DOWN', MRef, process, Pid, normal} ->
+%% io:format("waiting for clients: "
+%% "normal exit from ~w (~p)~n",
+%% [Id, Pid]),
+%% ok;
+%% {'DOWN', MRef, process, Pid, Reason} ->
+%% io:format("waiting for clients: "
+%% "unexpected exit from ~w (~p):"
+%% "~n Reason: ~p"
+%% "~n", [Id, Pid, Reason]),
+%% erlang:error(Reason)
+%% end
+%% end,
+%% Clients).
+
+
+wait4clients([], _Timeout) ->
+ ok;
+wait4clients(Clients, Timeout) when Timeout > 0 ->
+ io:format("wait4clients -> entry with"
+ "~n length(Clients): ~w"
+ "~n Timeout: ~w"
+ "~n", [length(Clients), Timeout]),
+ T = t(),
+ receive
+ {'DOWN', _MRef, process, Pid, normal} ->
+ case lists:keysearch(Pid, 2, Clients) of
+ {value, {Id, _, _}} ->
+ io:format("receive normal exit message "
+ "from client ~p (~p)", [Id, Pid]),
+ NewClients =
+ lists:keydelete(Id, 1, Clients),
+ wait4clients(NewClients,
+ Timeout - (t() - T));
+ false ->
+ io:format("receive normal exit message "
+ "from unknown process: ~p", [Pid]),
+ wait4clients(Clients, Timeout - (t() - T))
+ end;
+
+ {'DOWN', _MRef, process, Pid, Reason} ->
+ case lists:keysearch(Pid, 2, Clients) of
+ {value, {Id, _, _}} ->
+ io:format("receive bad exit message "
+ "from client ~p (~p):"
+ "~n ~p", [Id, Pid, Reason]),
+ erlang:error({bad_client_termination, Id, Reason});
+ false ->
+ io:format("receive normal exit message "
+ "from unknown process: ~p", [Pid]),
+ wait4clients(Clients, Timeout - (t() - T))
+ end
+
+ after Timeout ->
+ erlang:error({client_timeout, Clients})
+ end;
+wait4clients(Clients, _) ->
+ erlang:error({client_timeout, Clients}).
+
+
+%% Time in milli seconds
+t() ->
+ {A,B,C} = erlang:now(),
+ A*1000000000+B*1000+(C div 1000).
+
+
+%% -----------------------------------------------------
+%% Webserver part:
+%% Implements a web server that sends responses one character
+%% at a time, with random delays between the characters.
+
+start_slow_server(SeqNumServer) ->
+ io:format("start slow server when"
+ "~n SeqNumServer: ~w"
+ "~n", [SeqNumServer]),
+ proc_lib:start(
+ erlang, apply, [fun() -> init_slow_server(SeqNumServer) end, []]).
+
+init_slow_server(SeqNumServer) ->
+ io:format("[webserver ~w] init slow server"
+ "~n", [SeqNumServer]),
+ {ok, LSock} = gen_tcp:listen(0, [binary, {packet,0}, {active,true},
+ {backlog, 100}]),
+ io:format("[webserver ~w] LSock: ~p"
+ "~n", [SeqNumServer, LSock]),
+ {ok, {_IP, Port}} = inet:sockname(LSock),
+ io:format("[webserver ~w] Port: ~w"
+ "~n", [SeqNumServer, Port]),
+ proc_lib:init_ack({ok, self(), Port}),
+ loop_slow_server(LSock, SeqNumServer).
+
+loop_slow_server(LSock, SeqNumServer) ->
+ io:format("[webserver ~w] entry with"
+ "~n LSock: ~p"
+ "~n", [SeqNumServer, LSock]),
+ Master = self(),
+ Acceptor = proc_lib:spawn(
+ fun() -> client_handler(Master, LSock, SeqNumServer) end),
+ io:format("[webserver ~w] acceptor started"
+ "~n Acceptor: ~p"
+ "~n", [SeqNumServer, Acceptor]),
+ receive
+ {accepted, Acceptor} ->
+ io:format("[webserver ~w] accepted"
+ "~n", [SeqNumServer]),
+ loop_slow_server(LSock, SeqNumServer);
+ shutdown ->
+ gen_tcp:close(LSock),
+ exit(Acceptor, kill)
+ end.
+
+
+%% Handle one client connection
+client_handler(Master, LSock, SeqNumServer) ->
+ io:format("[acceptor ~w] await accept"
+ "~n", [SeqNumServer]),
+ {ok, CSock} = gen_tcp:accept(LSock),
+ io:format("[acceptor ~w] accepted"
+ "~n CSock: ~p"
+ "~n", [SeqNumServer, CSock]),
+ Master ! {accepted, self()},
+ set_random_seed(),
+ loop_client(1, CSock, SeqNumServer).
+
+loop_client(N, CSock, SeqNumServer) ->
+ %% Await request, don't bother parsing it too much,
+ %% assuming the entire request arrives in one packet.
+ io:format("[acceptor ~w] await request"
+ "~n N: ~p"
+ "~n", [SeqNumServer, N]),
+ receive
+ {tcp, CSock, Req} ->
+ ReqNum = parse_req_num(Req),
+ RespSeqNum = get_next_sequence_number(SeqNumServer),
+ Response = f("~s->resp~3..0w/~2..0w", [ReqNum, RespSeqNum, N]),
+ Txt = f("Slow server (~p) got ~p, answering with ~p",
+ [self(), Req, Response]),
+ io:format("~s...~n", [Txt]),
+ slowly_send_response(CSock, Response),
+ case parse_connection_type(Req) of
+ keep_alive ->
+ io:format("~s...done~n", [Txt]),
+ loop_client(N+1, CSock, SeqNumServer);
+ close ->
+ io:format("~s...done (closing)~n", [Txt]),
+ gen_tcp:close(CSock)
+ end
+ end.
+
+slowly_send_response(CSock, Answer) ->
+ Response = f("HTTP/1.1 200 OK\r\nContent-Length: ~w\r\n\r\n~s",
+ [length(Answer), Answer]),
+ lists:foreach(
+ fun(Char) ->
+ timer:sleep(random:uniform(500)),
+ gen_tcp:send(CSock, <<Char>>)
+ end,
+ Response).
+
+parse_req_num(Request) ->
+ Opts = [caseless,{capture,all_but_first,list}],
+ {match, [ReqNum]} = re:run(Request, "GET /(.*) HTTP", Opts),
+ ReqNum.
+
+parse_connection_type(Request) ->
+ Opts = [caseless,{capture,all_but_first,list}],
+ {match,[CType]} = re:run(Request, "connection: *(keep-alive|close)", Opts),
+ case string:to_lower(CType) of
+ "close" -> close;
+ "keep-alive" -> keep_alive
+ end.
+
+
+set_random_seed() ->
+ {_, _, Micros} = now(),
+ A = erlang:phash2([make_ref(), self(), Micros]),
+ random:seed(A, A, A).
+
+f(F, A) -> lists:flatten(io_lib:format(F,A)).
+
+
+
+
+%%-------------------------------------------------------------------------
+
+otp_8106(suite) ->
+ [
+ otp_8106_pid,
+ otp_8106_fun,
+ otp_8106_mfa
+ ].
+
+
+otp_8106_pid(doc) ->
+ ["OTP-8106 - deliver reply info using \"other\" pid"];
+otp_8106_pid(suite) ->
+ [];
+otp_8106_pid(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ ReceiverPid = create_receiver(pid),
+ Receiver = ReceiverPid,
+
+ otp8106(ReceiverPid, Receiver, Config),
+
+ stop_receiver(ReceiverPid),
+
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+otp_8106_fun(doc) ->
+ ["OTP-8106 - deliver reply info using fun"];
+otp_8106_fun(suite) ->
+ [];
+otp_8106_fun(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ ReceiverPid = create_receiver(function),
+ Receiver = otp_8106_deliver_fun(ReceiverPid),
+
+ otp8106(ReceiverPid, Receiver, Config),
+
+ stop_receiver(ReceiverPid),
+
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+otp_8106_mfa(doc) ->
+ ["OTP-8106 - deliver reply info using mfa callback"];
+otp_8106_mfa(suite) ->
+ [];
+otp_8106_mfa(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ ReceiverPid = create_receiver(mfa),
+ Receiver = {?MODULE, otp_8106_deliver, [mfa, ReceiverPid]},
+
+ otp8106(ReceiverPid, Receiver, Config),
+
+ stop_receiver(ReceiverPid),
+
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+ otp8106(ReceiverPid, Receiver, Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ HTTPOptions = [],
+ Options = [{sync, false}, {receiver, Receiver}],
+
+ {ok, RequestId} =
+ httpc:request(get, Request, HTTPOptions, Options),
+
+ Body =
+ receive
+ {reply, ReceiverPid, {RequestId, {{_, 200, _}, _, B}}} ->
+ B;
+ {reply, ReceiverPid, Msg} ->
+ tsf(Msg);
+ {bad_reply, ReceiverPid, Msg} ->
+ tsf(Msg)
+ end,
+
+ inets_test_lib:check_body(binary_to_list(Body)),
+ ok.
+
+
+create_receiver(Type) ->
+ Parent = self(),
+ Receiver = fun() -> receiver(Type, Parent) end,
+ spawn_link(Receiver).
+
+stop_receiver(Pid) ->
+ Pid ! {stop, self()}.
+
+receiver(Type, Parent) ->
+ receive
+ {stop, Parent} ->
+ exit(normal);
+
+ {http, ReplyInfo} when (Type =:= pid) ->
+ Parent ! {reply, self(), ReplyInfo},
+ receiver(Type, Parent);
+
+ {Type, ReplyInfo} ->
+ Parent ! {reply, self(), ReplyInfo},
+ receiver(Type, Parent);
+
+ Crap ->
+ Parent ! {reply, self(), {bad_reply, Crap}},
+ receiver(Type, Parent)
+ end.
+
+
+otp_8106_deliver_fun(ReceiverPid) ->
+ fun(ReplyInfo) -> otp_8106_deliver(ReplyInfo, function, ReceiverPid) end.
+
+otp_8106_deliver(ReplyInfo, Type, ReceiverPid) ->
+ ReceiverPid ! {Type, ReplyInfo},
+ ok.
+
+
+
+%%-------------------------------------------------------------------------
+
+otp_8056(doc) ->
+ "OTP-8056";
+otp_8056(suite) ->
+ [];
+otp_8056(Config) when is_list(Config) ->
+ Method = get,
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ HTTPOptions = [],
+ Options1 = [{sync, true}, {stream, {self, once}}],
+ Options2 = [{sync, true}, {stream, self}],
+ {error, streaming_error} = httpc:request(Method, Request,
+ HTTPOptions, Options1),
+ tsp("request 1 failed as expected"),
+ {error, streaming_error} = httpc:request(Method, Request,
+ HTTPOptions, Options2),
+ tsp("request 2 failed as expected"),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+otp_8352(doc) ->
+ "OTP-8352";
+otp_8352(suite) ->
+ [];
+otp_8352(Config) when is_list(Config) ->
+ tsp("otp_8352 -> entry with"
+ "~n Config: ~p", [Config]),
+ case ?config(local_server, Config) of
+ ok ->
+ tsp("local-server running"),
+
+ tsp("initial profile info(1): ~p", [httpc:info()]),
+
+ MaxSessions = 5,
+ MaxKeepAlive = 10,
+ KeepAliveTimeout = timer:minutes(2),
+ ConnOptions = [{max_sessions, MaxSessions},
+ {max_keep_alive_length, MaxKeepAlive},
+ {keep_alive_timeout, KeepAliveTimeout}],
+ http:set_options(ConnOptions),
+
+ Method = get,
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ Timeout = timer:seconds(1),
+ ConnTimeout = Timeout + timer:seconds(1),
+ HttpOptions1 = [{timeout, Timeout}, {connect_timeout, ConnTimeout}],
+ Options1 = [{socket_opts, [{tos, 87},
+ {recbuf, 16#FFFF},
+ {sndbuf, 16#FFFF}]}],
+ case http:request(Method, Request, HttpOptions1, Options1) of
+ {ok, {{_,200,_}, [_ | _], ReplyBody1 = [_ | _]}} ->
+ %% equivaliant to http:request(get, {URL, []}, [], []),
+ inets_test_lib:check_body(ReplyBody1);
+ {ok, UnexpectedReply1} ->
+ tsf({unexpected_reply, UnexpectedReply1});
+ {error, _} = Error1 ->
+ tsf({bad_reply, Error1})
+ end,
+
+ tsp("profile info (2): ~p", [httpc:info()]),
+
+ HttpOptions2 = [],
+ Options2 = [{socket_opts, [{tos, 84},
+ {recbuf, 32#1FFFF},
+ {sndbuf, 32#1FFFF}]}],
+ case http:request(Method, Request, HttpOptions2, Options2) of
+ {ok, {{_,200,_}, [_ | _], ReplyBody2 = [_ | _]}} ->
+ %% equivaliant to http:request(get, {URL, []}, [], []),
+ inets_test_lib:check_body(ReplyBody2);
+ {ok, UnexpectedReply2} ->
+ tsf({unexpected_reply, UnexpectedReply2});
+ {error, _} = Error2 ->
+ tsf({bad_reply, Error2})
+ end,
+ tsp("profile info (3): ~p", [httpc:info()]),
+ ok;
+
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+
+otp_8371(doc) ->
+ ["OTP-8371"];
+otp_8371(suite) ->
+ [];
+otp_8371(Config) when is_list(Config) ->
+ ok = http:set_options([{ipv6, disabled}]), % also test the old option
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++
+ "/ensure_host_header_with_port.html",
+
+ case http:request(get, {URL, []}, [], []) of
+ {ok, Result} ->
+ case Result of
+ {{_, 200, _}, _Headers, Body} ->
+ tsp("expected response with"
+ "~n Body: ~p", [Body]),
+ ok;
+ {StatusLine, Headers, Body} ->
+ tsp("expected response with"
+ "~n StatusLine: ~p"
+ "~n Headers: ~p"
+ "~n Body: ~p", [StatusLine, Headers, Body]),
+ tsf({unexpected_result,
+ [{status_line, StatusLine},
+ {headers, Headers},
+ {body, Body}]});
+ _ ->
+ tsf({unexpected_result, Result})
+ end;
+ Error ->
+ tsf({request_failed, Error})
+ end,
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipv6, enabled}]),
+ ok.
+
+
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+setup_server_dirs(ServerRoot, DocRoot, DataDir) ->
+ ConfDir = filename:join(ServerRoot, "conf"),
+ CgiDir = filename:join(ServerRoot, "cgi-bin"),
+ ok = file:make_dir(ServerRoot),
+ ok = file:make_dir(DocRoot),
+ ok = file:make_dir(ConfDir),
+ ok = file:make_dir(CgiDir),
+
+ {ok, Files} = file:list_dir(DataDir),
+
+ lists:foreach(fun(File) -> case lists:suffix(".html", File) of
+ true ->
+ inets_test_lib:copy_file(File,
+ DataDir,
+ DocRoot);
+ false ->
+ ok
+ end
+ end, Files),
+
+ Cgi = case test_server:os_type() of
+ {win32, _} ->
+ "cgi_echo.exe";
+ _ ->
+ "cgi_echo"
+ end,
+
+ inets_test_lib:copy_file(Cgi, DataDir, CgiDir),
+ inets_test_lib:copy_file("mime.types", DataDir, ConfDir).
+
+create_config(FileName, ComType, Port, PrivDir, ServerRoot, DocRoot,
+ SSLDir) ->
+ MaxHdrSz = io_lib:format("~p", [256]),
+ MaxHdrAct = io_lib:format("~p", [close]),
+ SSL =
+ case ComType of
+ ssl ->
+ [cline(["SSLCertificateFile ",
+ filename:join(SSLDir, "ssl_server_cert.pem")]),
+ cline(["SSLCertificateKeyFile ",
+ filename:join(SSLDir, "ssl_server_cert.pem")]),
+ cline(["SSLVerifyClient 0"])];
+ _ ->
+ []
+ end,
+
+ Mod_order = "Modules mod_alias mod_auth mod_esi mod_actions mod_cgi"
+ " mod_include mod_dir mod_get mod_head"
+ " mod_log mod_disk_log mod_trace",
+
+ HttpConfig = [
+ cline(["Port ", integer_to_list(Port)]),
+ cline(["ServerName ", "httpc_test"]),
+ cline(["SocketType ", atom_to_list(ComType)]),
+ cline([Mod_order]),
+ cline(["ServerRoot ", ServerRoot]),
+ cline(["DocumentRoot ", DocRoot]),
+ cline(["MaxHeaderSize ",MaxHdrSz]),
+ cline(["MaxHeaderAction ",MaxHdrAct]),
+ cline(["DirectoryIndex ", "index.html "]),
+ cline(["DefaultType ", "text/plain"]),
+ cline(["ScriptAlias /cgi-bin/ ",
+ filename:join(ServerRoot, "cgi-bin"), "/"]),
+ SSL],
+ ConfigFile = filename:join([PrivDir,FileName]),
+ {ok, Fd} = file:open(ConfigFile, [write]),
+ ok = file:write(Fd, lists:flatten(HttpConfig)),
+ ok = file:close(Fd).
+
+cline(List) ->
+ lists:flatten([List, "\r\n"]).
+
+is_proxy_available(Proxy, Port) ->
+ case gen_tcp:connect(Proxy, Port, []) of
+ {ok, Socket} ->
+ gen_tcp:close(Socket),
+ true;
+ _ ->
+ false
+ end.
+
+receive_streamed_body(RequestId, Body) ->
+ receive
+ {http, {RequestId, stream, BinBodyPart}} ->
+ receive_streamed_body(RequestId,
+ <<Body/binary, BinBodyPart/binary>>);
+ {http, {RequestId, stream_end, _Headers}} ->
+ Body;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end.
+
+receive_streamed_body(RequestId, Body, Pid) ->
+ http:stream_next(Pid),
+ test_server:format("~p:receive_streamed_body -> requested next stream ~n", [?MODULE]),
+ receive
+ {http, {RequestId, stream, BinBodyPart}} ->
+ receive_streamed_body(RequestId,
+ <<Body/binary, BinBodyPart/binary>>,
+ Pid);
+ {http, {RequestId, stream_end, _Headers}} ->
+ Body;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end.
+
+
+
+dummy_server(Caller, IpV) ->
+ Pid = spawn(httpc_SUITE, dummy_server_init, [Caller, IpV]),
+ receive
+ {port, Port} ->
+ {Pid, Port}
+ end.
+
+dummy_server_init(Caller, IpV) ->
+ {ok, ListenSocket} =
+ case IpV of
+ ipv4 ->
+ gen_tcp:listen(0, [binary, inet, {packet, 0},
+ {reuseaddr,true},
+ {active, false}]);
+ ipv6 ->
+ gen_tcp:listen(0, [binary, inet6, {packet, 0},
+ {reuseaddr,true},
+ {active, false}])
+ end,
+ {ok, Port} = inet:port(ListenSocket),
+ tsp("dummy_server_init -> Port: ~p", [Port]),
+ Caller ! {port, Port},
+ dummy_server_loop({httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]},
+ [], ListenSocket).
+
+dummy_server_loop(MFA, Handlers, ListenSocket) ->
+ receive
+ stop ->
+ lists:foreach(fun(Handler) -> Handler ! stop end, Handlers)
+ after 0 ->
+ {ok, Socket} = gen_tcp:accept(ListenSocket),
+ HandlerPid = dummy_request_handler(MFA, Socket),
+ gen_tcp:controlling_process(Socket, HandlerPid),
+ HandlerPid ! controller,
+ dummy_server_loop(MFA, [HandlerPid | Handlers],
+ ListenSocket)
+ end.
+
+dummy_request_handler(MFA, Socket) ->
+ spawn(httpc_SUITE, dummy_request_handler_init, [MFA, Socket]).
+
+dummy_request_handler_init(MFA, Socket) ->
+ receive
+ controller ->
+ inet:setopts(Socket, [{active, true}])
+ end,
+ dummy_request_handler_loop(MFA, Socket).
+
+dummy_request_handler_loop({Module, Function, Args}, Socket) ->
+ tsp("dummy_request_handler_loop -> entry with"
+ "~n Module: ~p"
+ "~n Function: ~p"
+ "~n Args: ~p", [Module, Function, Args]),
+ receive
+ {tcp, _, Data} ->
+ tsp("dummy_request_handler_loop -> Data ~p", [Data]),
+ case handle_request(Module, Function, [Data | Args], Socket) of
+ stop ->
+ gen_tcp:close(Socket);
+ NewMFA ->
+ dummy_request_handler_loop(NewMFA, Socket)
+ end;
+ stop ->
+ gen_tcp:close(Socket)
+ end.
+
+handle_request(Module, Function, Args, Socket) ->
+ tsp("handle_request -> entry with"
+ "~n Module: ~p"
+ "~n Function: ~p"
+ "~n Args: ~p", [Module, Function, Args]),
+ case Module:Function(Args) of
+ {ok, Result} ->
+ tsp("handle_request -> ok"
+ "~n Result: ~p", [Result]),
+ case (catch handle_http_msg(Result, Socket)) of
+ stop ->
+ stop;
+ <<>> ->
+ tsp("handle_request -> empty data"),
+ {httpd_request, parse, [[<<>>, ?HTTP_MAX_HEADER_SIZE]]};
+ Data ->
+ handle_request(httpd_request, parse,
+ [Data |[?HTTP_MAX_HEADER_SIZE]], Socket)
+ end;
+ NewMFA ->
+ tsp("handle_request -> "
+ "~n NewMFA: ~p", [NewMFA]),
+ NewMFA
+ end.
+
+handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) ->
+ tsp("handle_http_msg -> entry with: "
+ "~n RelUri: ~p"
+ "~n Headers: ~p"
+ "~n Body: ~p", [RelUri, Headers, Body]),
+ NextRequest =
+ case RelUri of
+ "/dummy_headers.html" ->
+ <<>>;
+ "/no_headers.html" ->
+ stop;
+ "/just_close.html" ->
+ stop;
+ _ ->
+ ContentLength = content_length(Headers),
+ case size(Body) - ContentLength of
+ 0 ->
+ <<>>;
+ _ ->
+ <<_BodyThisReq:ContentLength/binary,
+ Next/binary>> = Body,
+ Next
+ end
+ end,
+
+ tsp("handle_http_msg -> NextRequest: ~p", [NextRequest]),
+ case (catch ets:lookup(cookie, cookies)) of
+ [{cookies, true}]->
+ tsp("handle_http_msg -> check cookies ~p", []),
+ check_cookie(Headers);
+ _ ->
+ ok
+ end,
+
+ DefaultResponse = "HTTP/1.1 200 ok\r\n" ++
+ "Content-Length:32\r\n\r\n"
+ "<HTML><BODY>foobar</BODY></HTML>",
+
+ Msg =
+ case RelUri of
+ "/just_close.html" ->
+ close;
+ "/no_content.html" ->
+ "HTTP/1.0 204 No Content\r\n\r\n";
+ "/no_headers.html" ->
+ "HTTP/1.0 200 OK\r\n\r\nTEST";
+ "/ensure_host_header_with_port.html" ->
+ %% tsp("handle_http_msg -> validate host with port"),
+ case ensure_host_header_with_port(Headers) of
+ true ->
+ B =
+ "<HTML><BODY>" ++
+ "host with port" ++
+ "</BODY></HTML>",
+ Len = integer_to_list(length(B)),
+ "HTTP/1.1 200 ok\r\n" ++
+ "Content-Length:" ++ Len ++ "\r\n\r\n" ++ B;
+ false ->
+ B =
+ "<HTML><BODY>" ++
+ "Internal Server Error - host without port" ++
+ "</BODY></HTML>",
+ Len = integer_to_list(length(B)),
+ "HTTP/1.1 500 Internal Server Error\r\n" ++
+ "Content-Length:" ++ Len ++ "\r\n\r\n" ++ B
+ end;
+ "/300.html" ->
+ NewUri = ?URL_START ++
+ integer_to_list(?IP_PORT) ++ "/dummy.html",
+ "HTTP/1.1 300 Multiple Choices\r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:0\r\n\r\n";
+ "/301.html" ->
+ NewUri = ?URL_START ++
+ integer_to_list(?IP_PORT) ++ "/dummy.html",
+ "HTTP/1.1 301 Moved Permanently\r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:80\r\n\r\n" ++
+ "<HTML><BODY><a href=" ++ NewUri ++
+ ">New place</a></BODY></HTML>";
+ "/302.html" ->
+ NewUri = ?URL_START ++
+ integer_to_list(?IP_PORT) ++ "/dummy.html",
+ "HTTP/1.1 302 Found \r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:80\r\n\r\n" ++
+ "<HTML><BODY><a href=" ++ NewUri ++
+ ">New place</a></BODY></HTML>";
+ "/307.html" ->
+ NewUri = ?URL_START ++
+ integer_to_list(?IP_PORT) ++ "/dummy.html",
+ "HTTP/1.1 307 Temporary Rediect \r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:80\r\n\r\n" ++
+ "<HTML><BODY><a href=" ++ NewUri ++
+ ">New place</a></BODY></HTML>";
+ "/500.html" ->
+ "HTTP/1.1 500 Internal Server Error\r\n" ++
+ "Content-Length:47\r\n\r\n" ++
+ "<HTML><BODY>Internal Server Error</BODY></HTML>";
+ "/503.html" ->
+ case ets:lookup(unavailable, 503) of
+ [{503, unavailable}] ->
+ ets:insert(unavailable, {503, available}),
+ "HTTP/1.1 503 Service Unavailable\r\n" ++
+ "Retry-After:5\r\n" ++
+ "Content-Length:47\r\n\r\n" ++
+ "<HTML><BODY>Internal Server Error</BODY></HTML>";
+ [{503, available}] ->
+ DefaultResponse;
+ [{503, long_unavailable}] ->
+ "HTTP/1.1 503 Service Unavailable\r\n" ++
+ "Retry-After:120\r\n" ++
+ "Content-Length:47\r\n\r\n" ++
+ "<HTML><BODY>Internal Server Error</BODY></HTML>"
+ end;
+ "/redirectloop.html" -> %% Create a potential endless loop!
+ {ok, Port} = inet:port(Socket),
+ NewUri = ?URL_START ++
+ integer_to_list(Port) ++ "/redirectloop.html",
+ "HTTP/1.1 300 Multiple Choices\r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:0\r\n\r\n";
+ "/userinfo.html" ->
+ Challange = "HTTP/1.1 401 Unauthorized \r\n" ++
+ "WWW-Authenticate:Basic" ++"\r\n" ++
+ "Content-Length:0\r\n\r\n",
+ case auth_header(Headers) of
+ {ok, Value} ->
+ handle_auth(Value, Challange, DefaultResponse);
+ _ ->
+ Challange
+ end;
+ "/dummy_headers.html" ->
+ %% The client will only care about the Transfer-Encoding
+ %% header the rest of these headers are left to the
+ %% user to evaluate. This is not a valid response
+ %% it only tests that the header handling code works.
+ Head = "HTTP/1.1 200 ok\r\n" ++
+ "Content-Length:32\r\n" ++
+ "Pragma:1#no-cache\r\n" ++
+ "Via:1.0 fred, 1.1 nowhere.com (Apache/1.1)\r\n" ++
+ "Warning:1#pseudonym foobar\r\n" ++
+ "Vary:*\r\n" ++
+ "Trailer:Other:inets_test\r\n" ++
+ "Upgrade:HTTP/2.0\r\n" ++
+ "Age:4711\r\n" ++
+ "Transfer-Encoding:chunked\r\n" ++
+ "Content-Encoding:foo\r\n" ++
+ "Content-Language:en\r\n" ++
+ "Content-Location:http://www.foobar.se\r\n" ++
+ "Content-MD5:104528739076276072743283077410617235478\r\n"
+ ++
+ "Content-Range:Sat, 29 Oct 1994 19:43:31 GMT\r\n" ++
+ "Expires:Sat, 29 Oct 1994 19:43:31 GMT\r\n" ++
+ "Proxy-Authenticate:#1Basic" ++
+ "\r\n\r\n",
+ gen_tcp:send(Socket, Head),
+ gen_tcp:send(Socket, http_chunk:encode("<HTML><BODY>fo")),
+ gen_tcp:send(Socket, http_chunk:encode("obar</BODY></HTML>")),
+ http_chunk:encode_last();
+ "/capital_transfer_encoding.html" ->
+ Head = "HTTP/1.1 200 ok\r\n" ++
+ "Transfer-Encoding:Chunked\r\n\r\n",
+ gen_tcp:send(Socket, Head),
+ gen_tcp:send(Socket, http_chunk:encode("<HTML><BODY>fo")),
+ gen_tcp:send(Socket, http_chunk:encode("obar</BODY></HTML>")),
+ http_chunk:encode_last();
+ "/cookie.html" ->
+ "HTTP/1.1 200 ok\r\n" ++
+ "set-cookie:" ++ "test_cookie=true; path=/;" ++
+ "max-age=60000\r\n" ++
+ "Content-Length:32\r\n\r\n"++
+ "<HTML><BODY>foobar</BODY></HTML>";
+ "/missing_crlf.html" ->
+ "HTTP/1.1 200 ok" ++
+ "Content-Length:32\r\n" ++
+ "<HTML><BODY>foobar</BODY></HTML>";
+ "/wrong_statusline.html" ->
+ "ok 200 HTTP/1.1\r\n\r\n" ++
+ "Content-Length:32\r\n\r\n" ++
+ "<HTML><BODY>foobar</BODY></HTML>";
+ "/once_chunked.html" ->
+ Head = "HTTP/1.1 200 ok\r\n" ++
+ "Transfer-Encoding:Chunked\r\n\r\n",
+ gen_tcp:send(Socket, Head),
+ gen_tcp:send(Socket, http_chunk:encode("<HTML><BODY>fo")),
+ gen_tcp:send(Socket,
+ http_chunk:encode("obar</BODY></HTML>")),
+ http_chunk:encode_last();
+ "/once.html" ->
+ Head = "HTTP/1.1 200 ok\r\n" ++
+ "Content-Length:32\r\n\r\n",
+ gen_tcp:send(Socket, Head),
+ gen_tcp:send(Socket, "<HTML><BODY>fo"),
+ test_server:sleep(1000),
+ gen_tcp:send(Socket, "ob"),
+ test_server:sleep(1000),
+ gen_tcp:send(Socket, "ar</BODY></HTML>");
+ "/invalid_http.html" ->
+ "HTTP/1.1 301\r\nDate:Sun, 09 Dec 2007 13:04:18 GMT\r\n" ++
+ "Transfer-Encoding:chunked\r\n\r\n";
+ "/missing_reason_phrase.html" ->
+ "HTTP/1.1 200\r\n" ++
+ "Content-Length: 32\r\n\r\n"
+ "<HTML><BODY>foobar</BODY></HTML>";
+ "/missing_CR.html" ->
+ "HTTP/1.1 200 ok\n" ++
+ "Content-Length:32\r\n\n"
+ "<HTML><BODY>foobar</BODY></HTML>";
+ _ ->
+ DefaultResponse
+ end,
+
+ tsp("handle_http_msg -> Msg: ~p", [Msg]),
+ case Msg of
+ ok ->
+ %% Previously, this resulted in an {error, einval}. Now what?
+ ok;
+ close ->
+ %% Nothing to send, just close
+ gen_tcp:close(Socket);
+ _ when is_list(Msg) orelse is_binary(Msg) ->
+ gen_tcp:send(Socket, Msg)
+ end,
+ tsp("handle_http_msg -> done"),
+ NextRequest.
+
+ensure_host_header_with_port([]) ->
+ false;
+ensure_host_header_with_port(["host: " ++ Host| _]) ->
+ case string:tokens(Host, [$:]) of
+ [ActualHost, Port] ->
+ tsp("ensure_host_header_with_port -> "
+ "~n ActualHost: ~p"
+ "~n Port: ~p", [ActualHost, Port]),
+ true;
+ _ ->
+ false
+ end;
+ensure_host_header_with_port([_|T]) ->
+ ensure_host_header_with_port(T).
+
+auth_header([]) ->
+ auth_header_not_found;
+auth_header(["authorization:" ++ Value | _]) ->
+ {ok, string:strip(Value)};
+auth_header([_ | Tail]) ->
+ auth_header(Tail).
+
+handle_auth("Basic " ++ UserInfo, Challange, DefaultResponse) ->
+ case string:tokens(base64:decode_to_string(UserInfo), ":") of
+ ["alladin", "sesame"] = Auth ->
+ test_server:format("Auth: ~p~n", [Auth]),
+ DefaultResponse;
+ Other ->
+ test_server:format("UnAuth: ~p~n", [Other]),
+ Challange
+ end.
+
+check_cookie([]) ->
+ test_server:fail(no_cookie_header);
+check_cookie(["cookie:" ++ _Value | _]) ->
+ ok;
+check_cookie([_Head | Tail]) ->
+ check_cookie(Tail).
+
+content_length([]) ->
+ 0;
+content_length(["content-length:" ++ Value | _]) ->
+ list_to_integer(string:strip(Value));
+content_length([_Head | Tail]) ->
+ content_length(Tail).
+
+provocate_not_modified_bug(Url) ->
+ Timeout = 15000, %% 15s should be plenty
+
+ {ok, {{_, 200, _}, ReplyHeaders, _Body}} =
+ http:request(get, {Url, []}, [{timeout, Timeout}], []),
+ Etag = pick_header(ReplyHeaders, "ETag"),
+ Last = pick_header(ReplyHeaders, "last-modified"),
+
+ case http:request(get, {Url, [{"If-None-Match", Etag},
+ {"If-Modified-Since", Last}]},
+ [{timeout, 15000}],
+ []) of
+ {ok, {{_, 304, _}, _, _}} -> %% The expected reply
+ page_unchanged;
+ {ok, {{_, 200, _}, _, _}} ->
+ %% If the page has changed since the
+ %% last request we retry to
+ %% trigger the bug
+ provocate_not_modified_bug(Url);
+ {error, timeout} ->
+ %% Not what we expected. Tcpdump can be used to
+ %% verify that we receive the complete http-reply
+ %% but still time out.
+ incorrect_result
+ end.
+
+pick_header(Headers, Name) ->
+ case lists:keysearch(string:to_lower(Name), 1,
+ [{string:to_lower(X), Y} || {X, Y} <- Headers]) of
+ false ->
+ [];
+ {value, {_Key, Val}} ->
+ Val
+ end.
+
+
+not_implemented_yet() ->
+ exit(not_implemented_yet).
+
+
+p(F) ->
+ p(F, []).
+
+p(F, A) ->
+ io:format("~p ~w:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
diff --git a/lib/inets/test/httpc_SUITE_data/Makefile.src b/lib/inets/test/httpc_SUITE_data/Makefile.src
new file mode 120000
index 0000000000..ad6e7bf9c8
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/Makefile.src
@@ -0,0 +1 @@
+../httpd_SUITE_data/Makefile.src \ No newline at end of file
diff --git a/lib/inets/test/httpc_SUITE_data/cgi_echo.c b/lib/inets/test/httpc_SUITE_data/cgi_echo.c
new file mode 120000
index 0000000000..38e06fe0d2
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/cgi_echo.c
@@ -0,0 +1 @@
+../httpd_SUITE_data/cgi_echo.c \ No newline at end of file
diff --git a/lib/inets/test/httpc_SUITE_data/dummy.html b/lib/inets/test/httpc_SUITE_data/dummy.html
new file mode 100644
index 0000000000..9a960ecc8a
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/dummy.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>Dummy</title>
+</head>
+
+<body>
+<h1>Dummy</h1>
+
+<p>This is a dummy html file! </p>
+</body>
+</html>
diff --git a/system/doc/images/.gitignore b/lib/inets/test/httpc_SUITE_data/empty.html
index e69de29bb2..e69de29bb2 100644
--- a/system/doc/images/.gitignore
+++ b/lib/inets/test/httpc_SUITE_data/empty.html
diff --git a/lib/inets/test/httpc_SUITE_data/mime.types b/lib/inets/test/httpc_SUITE_data/mime.types
new file mode 100644
index 0000000000..d2f81e4e5e
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/mime.types
@@ -0,0 +1,465 @@
+# This is a comment. I love comments.
+
+# MIME type Extension
+application/EDI-Consent
+application/EDI-X12
+application/EDIFACT
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atomicmail
+application/batch-SMTP
+application/beep+xml
+application/cals-1840
+application/commonground
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/eshop
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/font-tdpfr
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathematica-old
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll
+application/oda oda
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/qsig
+application/remote-printing
+application/riscos
+application/rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/smil smi smil
+application/timestamp-query
+application/timestamp-reply
+application/vemmi
+application/vnd.3M.Post-it-Notes
+application/vnd.FloGraphIt
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.aether.imp
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.businessobjects
+application/vnd.bmi
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.comsocaller
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.ctc-posml
+application/vnd.cybank
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hhe.lesson-player
+application/vnd.hp-HPGL
+application/vnd.hp-PCL
+application/vnd.hp-PCLXL
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.MiniPay
+application/vnd.ibm.modcap
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.koan
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.EDM
+application/vnd.novadigm.EDX
+application/vnd.novadigm.EXT
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-xhtml-print+xml
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.tve-trigger
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.vividence.scriptfile
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yellowriver-custom-menu
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xml
+application/xml-dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/basic au snd
+audio/g.722.1
+audio/l16
+audio/midi mid midi kar
+audio/mp4a-latm
+audio/mpa-robust
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/prs.sid
+audio/telephone-event
+audio/tone
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-mpegurl m3u
+audio/x-pn-realaudio ram rm
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/tiff tiff tif
+image/vnd.cns.inf2
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.mix
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar
+text/css css
+text/directory
+text/enriched
+text/html html htm
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/tab-separated-values tsv
+text/t140
+text/uri-list
+text/vnd.DMClientScript
+text/vnd.IPTC.NITF
+text/vnd.IPTC.NewsML
+text/vnd.abc
+text/vnd.curl
+text/vnd.flatland.3dml
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-setext etx
+text/x-server-parsed-html shtml
+text/xml xml xsl
+text/xml-external-parsed-entity
+video/mp4v-es
+video/mpeg mpeg mpg mpe
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu
+video/vnd.mts
+video/vnd.nokia.interleaved-multimedia
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+
+
+
diff --git a/lib/inets/test/httpc_SUITE_data/redirect.html b/lib/inets/test/httpc_SUITE_data/redirect.html
new file mode 100644
index 0000000000..7034461ed6
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/redirect.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<meta http-eqviv="Refresh", content="10;URL=http://localhost:8888/dummy.html">
+<title>Redirect</title>
+
+</head>
+
+<body>
+<p> You will be redirected</p>
+</body> </html>
diff --git a/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem b/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem
new file mode 100644
index 0000000000..f274d2021d
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBANz7eFvORmJDi1XJMM2U3uHC5wmp/DXTLMw08XaEvtZ73wgVg84E
+V0oyX3Kh1thRE3Hch9AyrHjgpizCj9/Ra38CAwEAAQJACzpz2SZYCTIpaEh6xFdm
+I86FcsZCXHHIeu/NvRntoHQ+nfM7Np379+z6XNJWIcWh/QgG/jNJalR1BO+eyc6/
+YQIhAP3m8M0LDxJwSgHFtGAGatQqaqw9l48Kq5xdMFqvdpiHAiEA3s7lld6yCJYu
+6q7fZjTH+eKUwgg0vpgJutP7Fsok60kCIHHesQBEhW3vjkFdOZgXSLH+k/jLZr1w
+O6bU5GrHZpjhAiEAyTvGYcjDtTunXjDY9l+fadK6FlEBCk8ZIpNIiTnDhHkCIQDr
+QxxLLuNHRj8iWNbuVVZ99SJy8zC33pMgPFaFKaZesQ==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIB7jCCAZgCAQAwDQYJKoZIhvcNAQEEBQAwgYExCzAJBgNVBAYTAlNFMRIwEAYD
+VQQHEwlTdG9ja2hvbG0xETAPBgNVBAoTCEVyaWNzc29uMQwwCgYDVQQLEwNFVFgx
+FjAUBgNVBAMTDUhlbGVuIEFpcml5YW4xJTAjBgkqhkiG9w0BCQEWFmhlbGVuQGVy
+aXguZXJpY3Nzb24uc2UwHhcNOTcwNzI4MDcxNDI1WhcNOTgxMjEwMDcxNDI1WjCB
+gTELMAkGA1UEBhMCU0UxEjAQBgNVBAcTCVN0b2NraG9sbTERMA8GA1UEChMIRXJp
+Y3Nzb24xDDAKBgNVBAsTA0VUWDEWMBQGA1UEAxMNSGVsZW4gQWlyaXlhbjElMCMG
+CSqGSIb3DQEJARYWaGVsZW5AZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEB
+AQUAA0sAMEgCQQDc+3hbzkZiQ4tVyTDNlN7hwucJqfw10yzMNPF2hL7We98IFYPO
+BFdKMl9yodbYURNx3IfQMqx44KYswo/f0Wt/AgMBAAEwDQYJKoZIhvcNAQEEBQAD
+QQC2++hLIaQJ4ChCjFE9UCfXO9cZ3Vq/FT9VjE+G4MRBDo4LQ5mBKNXcPF6EFZmi
+7XrlvopXkVPlRguTi2SLRPkY
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem b/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem
new file mode 100644
index 0000000000..f01b6c992b
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOQIBAAJBAMe2WhP6s+JeKOwWPEjI9susfN4Vjn2dd1X4QUlOETcWVLoF916m
+M4JU+ms7+ciMR8GRNCsIeqZGY8/GSqm74ccCAwEAAQJAF08YKlbLYfM9cXiS5qfV
+7iWemUkIzW5wfC8yZ3zeE4Cp6R9ViUfs/dadQ/23Cw0Bpo2t8UdTUdCa4KpmqOem
+cQIhAOnxTWZ5eo6h6PXDp7L5FZUACg8+wT3qf5f2is2mbSZPAiEA2orUY8JZDTSk
+Rm7q9WxLiLNtORsXdTCmnCWhqBOYpwkCIErdowRxScxNekz0IT3AQqzdR1rbnWHg
+IpcSGhd39CQ3AiA1XvQxjLP8wp9fyBS/bPwhXVhOOuyGpSP7PEF3b5m3KQIgGQWc
+/a5wuWx3pc3mLx0ILwNoJr2ubFEuW1PJPsPJPv0=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIB7jCCAZgCAQAwDQYJKoZIhvcNAQEEBQAwgYExCzAJBgNVBAYTAlNFMRIwEAYD
+VQQHEwlTdG9ja2hvbG0xETAPBgNVBAoTCEVyaWNzc29uMQwwCgYDVQQLEwNFVFgx
+FjAUBgNVBAMTDUhlbGVuIEFpcml5YW4xJTAjBgkqhkiG9w0BCQEWFmhlbGVuQGVy
+aXguZXJpY3Nzb24uc2UwHhcNOTcwNzI4MDcyMTAwWhcNOTgxMjEwMDcyMTAwWjCB
+gTELMAkGA1UEBhMCU0UxEjAQBgNVBAcTCVN0b2NraG9sbTERMA8GA1UEChMIRXJp
+Y3Nzb24xDDAKBgNVBAsTA0VUWDEWMBQGA1UEAxMNSGVsZW4gQWlyaXlhbjElMCMG
+CSqGSIb3DQEJARYWaGVsZW5AZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEB
+AQUAA0sAMEgCQQDHtloT+rPiXijsFjxIyPbLrHzeFY59nXdV+EFJThE3FlS6Bfde
+pjOCVPprO/nIjEfBkTQrCHqmRmPPxkqpu+HHAgMBAAEwDQYJKoZIhvcNAQEEBQAD
+QQCnU1TkxmfbLdUwjdECb5x9QHCevAR7AmTms4Csn2oOEyPX+bgF2d94xhrV1sxO
+Rs0yigk1PtN17Ci0Dey0LYkR
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpc_cookie_SUITE.erl b/lib/inets/test/httpc_cookie_SUITE.erl
new file mode 100644
index 0000000000..ad5df656c6
--- /dev/null
+++ b/lib/inets/test/httpc_cookie_SUITE.erl
@@ -0,0 +1,451 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(httpc_cookie_SUITE).
+
+-include("test_server.hrl").
+-include_lib("stdlib/include/ms_transform.hrl").
+
+%% Test server specific exports
+-export([all/1, init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases must be exported.
+-export([session_cookies_only/1, netscape_cookies/1,
+ cookie_cancel/1, cookie_expires/1, persistent_cookie/1,
+ domain_cookie/1, secure_cookie/1, update_cookie/1,
+ update_cookie_session/1, cookie_attributes/1]).
+
+-define(URL, "http://myhost.cookie.test.org").
+-define(URL_DOMAIN, "http://myhost2.cookie.test.org").
+-define(URL_SECURE, "https://myhost.cookie.test.org").
+
+%% Test server callback functions
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(session_cookies_only = Case, Config0) ->
+ tsp("init_per_testcase(~p) -> entry with"
+ "~n Config0: ~p", [Case, Config0]),
+ Config = init_workdir(Case, Config0),
+ application:start(inets),
+ http:set_options([{cookies, verify}]),
+ watch_dog(Config);
+
+init_per_testcase(Case, Config0) ->
+ tsp("init_per_testcase(~p) -> entry with"
+ "~n Config0: ~p", [Case, Config0]),
+ Config = init_workdir(Case, Config0),
+ CaseDir = ?config(case_top_dir, Config),
+ application:load(inets),
+ application:set_env(inets, services, [{httpc, {default, CaseDir}}]),
+ application:start(inets),
+ http:set_options([{cookies, verify}]),
+ watch_dog(Config).
+
+watch_dog(Config) ->
+ Dog = test_server:timetrap(inets_test_lib:minutes(10)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ [{watchdog, Dog} | NewConfig].
+
+init_workdir(Case, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ SuiteTopDir = filename:join(PrivDir, ?MODULE),
+ case file:make_dir(SuiteTopDir) of
+ ok ->
+ ok;
+ {error, eexist} ->
+ ok;
+ Error ->
+ tsf({failed_creating_subsuite_top_dir, Error})
+ end,
+
+ CaseTopDir = filename:join(SuiteTopDir, Case),
+ ?line ok = file:make_dir(CaseTopDir),
+ [{suite_top_dir, SuiteTopDir},
+ {case_top_dir, CaseTopDir} | Config].
+
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ tsp("end_per_testcase(~p) -> entry with"
+ "~n Config: ~p", [Case, Config]),
+ application:stop(inets),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Describe the main purpose of this suite"];
+
+all(suite) ->
+ [
+ session_cookies_only,
+ netscape_cookies,
+ cookie_cancel,
+ cookie_expires,
+ persistent_cookie,
+ domain_cookie,
+ secure_cookie,
+ update_cookie,
+ update_cookie_session,
+ cookie_attributes
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+session_cookies_only(doc) ->
+ ["Test that all cookies are handled as session cookies if there"
+ "does not exist a directory to save presitent cookies in."];
+session_cookies_only(suite) ->
+ [];
+session_cookies_only(Config) when is_list(Config) ->
+ tsp("session_cookies_only -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ ";max-age=60000"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"}
+ = http:cookie_header(?URL),
+ application:stop(inets),
+ application:start(inets),
+ {"cookie",""} = http:cookie_header(?URL),
+
+ tsp("session_cookies_only -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+netscape_cookies(doc) ->
+ ["Test that the old (original) format of cookies are accepted."];
+netscape_cookies(suite) ->
+ [];
+netscape_cookies(Config) when is_list(Config) ->
+ tsp("netscape_cookies -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ Expires = future_netscape_date(),
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/; "
+ "expires=" ++ Expires}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"} =
+ http:cookie_header(?URL),
+
+ tsp("netscape_cookies -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+cookie_cancel(doc) ->
+ ["A cookie can be canceld by sending the same cookie with max-age=0 "
+ "this test cheks that cookie is canceled."];
+cookie_cancel(suite) ->
+ [];
+cookie_cancel(Config) when is_list(Config) ->
+ tsp("cookie_cancel -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "max-age=60000"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"}
+ = http:cookie_header(?URL),
+ NewSetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "max-age=0"}],
+ http:verify_cookies(NewSetCookieHeaders, ?URL),
+ {"cookie", ""} = http:cookie_header(?URL),
+
+ tsp("cookie_cancel -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+cookie_expires(doc) ->
+ ["Test that a cookie is not used when it has expired"];
+cookie_expires(suite) ->
+ [];
+cookie_expires(Config) when is_list(Config) ->
+ tsp("cookie_expires -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "max-age=5"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"}
+ = http:cookie_header(?URL),
+ test_server:sleep(10000),
+ {"cookie", ""} = http:cookie_header(?URL),
+
+ tsp("cookie_expires -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+persistent_cookie(doc) ->
+ ["Test domian cookie attribute"];
+persistent_cookie(suite) ->
+ [];
+persistent_cookie(Config) when is_list(Config)->
+ tsp("persistent_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "max-age=60000"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"} =
+ http:cookie_header(?URL),
+ CaseDir = ?config(case_top_dir, Config),
+ application:stop(inets),
+ application:load(inets),
+ application:set_env(inets, services, [{httpc, {default, CaseDir}}]),
+ application:start(inets),
+ http:set_options([{cookies, enabled}]),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"} = http:cookie_header(?URL),
+
+ tsp("persistent_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+
+domain_cookie(doc) ->
+ ["Test the domian cookie attribute"];
+domain_cookie(suite) ->
+ [];
+domain_cookie(Config) when is_list(Config) ->
+ tsp("domain_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "domain=.cookie.test.org"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/; "
+ "$Domain=.cookie.test.org"} =
+ http:cookie_header(?URL_DOMAIN),
+
+ tsp("domain_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+
+secure_cookie(doc) ->
+ ["Test the secure cookie attribute"];
+secure_cookie(suite) ->
+ [];
+secure_cookie(Config) when is_list(Config) ->
+ tsp("secure_cookie -> entry with"
+ "~n Config: ~p", [Config]),
+
+ inets:enable_trace(max, io, httpc),
+
+ %% httpc:reset_cookies(),
+
+ tsp("secure_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/; secure"}],
+ tsp("secure_cookie -> verify cookies (1)"),
+ ok = http:verify_cookies(SetCookieHeaders, ?URL),
+
+ tsp("secure_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
+
+ tsp("secure_cookie -> check cookie (secure)"),
+ check_cookie("$Version=0; test_cookie=true; $Path=/", ?URL_SECURE),
+
+ tsp("secure_cookie -> check cookie (plain)"),
+ check_cookie("", ?URL),
+
+ tsp("secure_cookie -> verify cookies (2)"),
+ SetCookieHeaders1 = [{"set-cookie", "test1_cookie=true; path=/; secure"}],
+ ok = http:verify_cookies(SetCookieHeaders1, ?URL),
+
+ tsp("secure_cookie -> Cookies 3: ~p", [httpc:which_cookies()]),
+
+ tsp("secure_cookie -> cookie header (3)"),
+ check_cookie("$Version=0; test_cookie=true; $Path=/; "
+ "test1_cookie=true; $Path=/",
+ ?URL_SECURE),
+%% {"cookie","$Version=0; test_cookie=true; $Path=/; "
+%% "test1_cookie=true; $Path=/"} = http:cookie_header(?URL_SECURE),
+
+ tsp("secure_cookie -> Cookies 4: ~p", [httpc:which_cookies()]),
+
+ inets:disable_trace(),
+ tsp("secure_cookie -> done"),
+ ok.
+
+update_cookie(doc)->
+ ["Test that a cookie can be updated."];
+update_cookie(suite) ->
+ [];
+update_cookie(Config) when is_list(Config)->
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "max-age=6500"},
+ {"set-cookie", "test_cookie2=true; path=/;"
+ "max-age=6500"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie", "$Version=0; test_cookie2=true; $Path=/; "
+ "test_cookie=true; $Path=/"} = http:cookie_header(?URL),
+ NewSetCookieHeaders = [{"set-cookie", "test_cookie=false; "
+ "path=/;max-age=6500"}],
+ http:verify_cookies(NewSetCookieHeaders, ?URL),
+ {"cookie", "$Version=0; test_cookie2=true; $Path=/; "
+ "test_cookie=false; $Path=/"} = http:cookie_header(?URL).
+
+update_cookie_session(doc)->
+ ["Test that a cookie can be updated."];
+update_cookie_session(suite) ->
+ [];
+update_cookie_session(Config) when is_list(Config)->
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/"},
+ {"set-cookie", "test_cookie2=true; path=/"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie", "$Version=0; test_cookie2=true; $Path=/; "
+ "test_cookie=true; $Path=/"} = http:cookie_header(?URL),
+ NewSetCookieHeaders = [{"set-cookie", "test_cookie=false; path=/"}],
+ http:verify_cookies(NewSetCookieHeaders, ?URL),
+ {"cookie", "$Version=0; test_cookie2=true; $Path=/; "
+ "test_cookie=false; $Path=/"} = http:cookie_header(?URL).
+
+
+cookie_attributes(doc) ->
+ ["Test attribute not covered by the other test cases"];
+cookie_attributes(suite) ->
+ [];
+cookie_attributes(Config) when is_list(Config) ->
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true;version=1;"
+ "comment=foobar; "%% Comment
+ "foo=bar;" %% Nonsense should be ignored
+ "max-age=60000"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=1; test_cookie=true"} = http:cookie_header(?URL),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+check_cookie(Expect, URL) ->
+ case http:cookie_header(URL) of
+ {"cookie", Expect} ->
+ ok;
+ {"cookie", Unexpected} ->
+ case lists:prefix(Expect, Unexpected) of
+ true ->
+ Extra = Unexpected -- Expect,
+ tsf({extra_cookie_info, Extra});
+ false ->
+ tsf({unknown_cookie, Expect, Unexpected})
+ end;
+ Bad ->
+ tsf({bad_cookies, Bad})
+ end.
+
+
+future_netscape_date() ->
+ [Day, DD, Mon, YYYY] = netscape_date(date()),
+ lists:flatten(io_lib:format("~s, ~s ~s ~s 12:30:00 GMT",
+ [Day, DD, Mon, YYYY])).
+
+netscape_date({Year, 12, _}) ->
+ NewYear = Year + 1,
+ NewMonth = 1,
+ NewDay = calendar:last_day_of_the_month(NewYear, NewMonth),
+ WeekDay = calendar:day_of_the_week(NewYear, NewMonth, NewDay),
+ WeekDayNrStr = day_nr_str(NewDay),
+ NewDayStr = week_day_str(WeekDay),
+ MonthStr = month_str(NewMonth),
+ [NewDayStr, WeekDayNrStr, MonthStr, integer_to_list(NewYear)];
+
+netscape_date({Year, Month, _}) ->
+ NewMonth = Month + 1,
+ NewDay = calendar:last_day_of_the_month(Year, NewMonth),
+ WeekDay = calendar:day_of_the_week(Year, NewMonth, NewDay),
+ WeekDayNrStr = day_nr_str(NewDay),
+ NewDayStr = week_day_str(WeekDay),
+ MonthStr = month_str(NewMonth),
+ [NewDayStr, WeekDayNrStr, MonthStr, integer_to_list(Year)].
+
+week_day_str(1) ->
+ "Mon";
+week_day_str(2) ->
+ "Tus";
+week_day_str(3) ->
+ "Wdy";
+week_day_str(4) ->
+ "Thu";
+week_day_str(5) ->
+ "Fri";
+week_day_str(6) ->
+ "Sat";
+week_day_str(7) ->
+ "Sun".
+
+day_nr_str(1) ->
+ "01";
+day_nr_str(2) ->
+ "02";
+day_nr_str(3) ->
+ "03";
+day_nr_str(4) ->
+ "04";
+day_nr_str(5) ->
+ "05";
+day_nr_str(6) ->
+ "06";
+day_nr_str(7) ->
+ "07";
+day_nr_str(8) ->
+ "08";
+day_nr_str(0) ->
+ "09";
+day_nr_str(N) ->
+ integer_to_list(N).
+
+month_str(1) ->"Jan";
+month_str(2) ->"Feb";
+month_str(3) ->"Mar";
+month_str(4) ->"Apr";
+month_str(5) ->"May";
+month_str(6) ->"Jun";
+month_str(7) ->"Jul";
+month_str(8) ->"Aug";
+month_str(9) ->"Sep";
+month_str(10) ->"Oct";
+month_str(11) ->"Nov";
+month_str(12) ->"Dec".
+
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+
diff --git a/lib/inets/test/httpc_internal.hrl b/lib/inets/test/httpc_internal.hrl
new file mode 120000
index 0000000000..bef2c94879
--- /dev/null
+++ b/lib/inets/test/httpc_internal.hrl
@@ -0,0 +1 @@
+../src/http_client/httpc_internal.hrl \ No newline at end of file
diff --git a/lib/inets/test/httpd_1_1.erl b/lib/inets/test/httpd_1_1.erl
new file mode 100644
index 0000000000..055d034bec
--- /dev/null
+++ b/lib/inets/test/httpd_1_1.erl
@@ -0,0 +1,494 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(httpd_1_1).
+-author('[email protected]').
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include_lib("kernel/include/file.hrl").
+
+-export([host/4, chunked/4, expect/4, range/4, if_test/5, http_trace/4,
+ head/4, mod_cgi_chunked_encoding_test/5]).
+
+%% -define(all_keys_lower_case,true).
+-ifndef(all_keys_lower_case).
+-define(CONTENT_LENGTH, "Content-Length: ").
+-define(CONTENT_RANGE, "Content-Range: ").
+-define(CONTENT_TYPE, "Content-Type: ").
+-else.
+-define(CONTENT_LENGTH, "content-length:").
+-define(CONTENT_RANGE, "content-range:").
+-define(CONTENT_TYPE, "content-type:").
+-endif.
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+host(Type, Port, Host, Node) ->
+ %% No host needed for HTTP/1.0
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ %% No host must generate an error
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\n\r\n",
+ [{statuscode, 400}]),
+
+ %% If it is a fully qualified URL no host is needed
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET HTTP://"++ Host ++ ":" ++
+ integer_to_list(Port)++
+ "/ HTTP/1.1\r\n\r\n",
+ [{statuscode, 200}]),
+
+ %% If both look at the url.
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET HTTP://"++ Host ++ ":"++
+ integer_to_list(Port) ++
+ "/ HTTP/1.1\r\nHost:"++ Host ++
+ "\r\n\r\n",[{statuscode, 200}]),
+
+ %% Allow the request if its a Host field
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:"++
+ Host ++ "\r\n\r\n",
+ [{statuscode, 200}]),
+ ok.
+
+chunked(Type, Port, Host, Node)->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\n"
+ "Host:"++ Host ++"\r\n"
+ "Transfer-Encoding:chunked\r\n"
+ "\r\n"
+ "A\r\n"
+ "1234567890\r\n"
+ "4\r\n"
+ "HEJ!\r\n"
+ "0\r\n\r\n",
+ [{statuscode, 200}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\n"
+ "Host:"++ Host ++"\r\n"
+ "Transfer-Encoding:chunked\r\n"
+ "Trailer:Content-Type\r\n"
+ "\r\n"
+ "A\r\n"
+ "1234567890\r\n"
+ "4\r\n"
+ "HEJ!\r\n"
+ "0\r\n"
+ "Content-Type:text/plain\r\n\r\n",
+ [{statuscode, 200}]),
+ ok.
+
+expect(Type, Port, Host, Node)->
+ Request="GET / HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nContent-Length:22\r\nExpect:100-continue\r\n\r\n",
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ Request,
+ [{statuscode, 100}]).
+range(Type, Port, Host, Node)->
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /range.txt HTTP/1.1\r\nHost:"
+ ++ Host
+ ++ "\r\nRange:bytes=110-120\r\n\r\n",
+ [{statuscode,416}]),
+ %%The simples of all range request a range
+ Request1="GET /range.txt HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nRange:bytes=0-9\r\n\r\n",
+ {ok, Socket1} = inets_test_lib:connect_byte(Type, Host, Port),
+ inets_test_lib:send(Type, Socket1,Request1),
+ ok = validateRangeRequest(Socket1,[],"1234567890",$2,$0,$6),
+ inets_test_lib:close(Type,Socket1),
+
+ %% Request the end of the file
+ Request2 =
+ "GET /range.txt HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nRange:bytes=90-\r\n\r\n",
+
+ {ok, Socket2} = inets_test_lib:connect_byte(Type, Host, Port),
+ inets_test_lib:send(Type, Socket2, Request2),
+ ok = validateRangeRequest(Socket2,[],"1234567890",$2,$0,$6),
+ inets_test_lib:close(Type,Socket2),
+
+ %% The last byte in the file
+ Request3 =
+ "GET /range.txt HTTP/1.1\r\nHost:"++
+ Host ++ "\r\nRange:bytes=-1\r\n\r\n",
+ {ok, Socket3} = inets_test_lib:connect_byte(Type, Host, Port),
+ inets_test_lib:send(Type, Socket3,Request3),
+ ok = validateRangeRequest(Socket3,[],"0",$2,$0,$6),
+ inets_test_lib:close(Type, Socket3),
+
+ %%Multi Range
+ Request4 = "GET /range.txt HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nRange:bytes=0-0,2-2,-1\r\n\r\n",
+ {ok, Socket4} = inets_test_lib:connect_byte(Type, Host, Port),
+ inets_test_lib:send(Type, Socket4, Request4),
+ ok = validateRangeRequest(Socket4,[],"130",$2,$0,$6),
+ inets_test_lib:close(Type, Socket4).
+
+if_test(Type, Port, Host, Node, DocRoot)->
+ {ok, FileInfo} =
+ file:read_file_info(filename:join([DocRoot,"index.html"])),
+ CreatedSec =
+ calendar:datetime_to_gregorian_seconds(FileInfo#file_info.mtime),
+
+ Mod = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+ CreatedSec-1)),
+
+ %% Test that we get the data when the file is modified
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nIf-Modified-Since:" ++
+ Mod ++ "\r\n\r\n",
+ [{statuscode, 200}]),
+ Mod1 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+ CreatedSec+100)),
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++"\r\nIf-Modified-Since:"
+ ++ Mod1 ++"\r\n\r\n",
+ [{statuscode, 304}]),
+
+ Mod2 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+ CreatedSec+1)),
+ %% Control that the If-Unmodified-Header lmits the response
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++
+ "\r\nIf-Unmodified-Since:" ++ Mod2
+ ++ "\r\n\r\n",
+ [{statuscode, 200}]),
+ Mod3 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+ CreatedSec-1)),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++
+ "\r\nIf-Unmodified-Since:"++ Mod3
+ ++"\r\n\r\n",
+ [{statuscode, 412}]),
+
+ %% Control that we get the body when the etag match
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:" ++ Host
+ ++"\r\n"++
+ "If-Match:"++
+ httpd_util:create_etag(FileInfo)++
+ "\r\n\r\n",
+ [{statuscode, 200}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:" ++
+ Host ++ "\r\n"++
+ "If-Match:NotEtag\r\n\r\n",
+ [{statuscode, 412}]),
+
+ %% Control the response when the if-none-match header is there
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++"\r\n"++
+ "If-None-Match:NoTaag," ++
+ httpd_util:create_etag(FileInfo) ++
+ "\r\n\r\n",
+ [{statuscode, 304}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++ "\r\n"++
+ "If-None-Match:NotEtag,"
+ "NeihterEtag\r\n\r\n",
+ [{statuscode,200}]).
+
+http_trace(Type, Port, Host, Node)->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "TRACE / HTTP/1.1\r\n" ++
+ "Host:" ++ Host ++ "\r\n" ++
+ "Max-Forwards:2\r\n\r\n",
+ [{statuscode, 200}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "TRACE / HTTP/1.0\r\n\r\n",
+ [{statuscode, 501},
+ {version, "HTTP/1.0"}]).
+head(Type, Port, Host, Node)->
+ %% mod_include
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /fsize.shtml HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /fsize.shtml HTTP/1.1\r\nhost:" ++
+ Host ++ "\r\n\r\n", [{statuscode, 200}]),
+ %% mod_esi
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /cgi-bin/erl/httpd_example/newformat"
+ " HTTP/1.0\r\n\r\n", [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /cgi-bin/erl/httpd_example/newformat "
+ "HTTP/1.1\r\nhost:" ++ Host ++ "\r\n\r\n",
+ [{statuscode, 200}]),
+ %% mod_cgi
+ Script =
+ case test_server:os_type() of
+ {win32, _} ->
+ "printenv.bat";
+ _ ->
+ "printenv.sh"
+ end,
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,"HEAD /cgi-bin/"
+ ++ Script ++ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node, "HEAD /cgi-bin/"
+ ++ Script ++ " HTTP/1.1\r\nhost:" ++
+ Host ++ "\r\n\r\n",
+ [{statuscode, 200}]).
+
+mod_cgi_chunked_encoding_test(_, _, _, _, [])->
+ ok;
+mod_cgi_chunked_encoding_test(Type, Port, Host, Node, [Request| Rest])->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, Request,
+ [{statuscode, 200}]),
+ mod_cgi_chunked_encoding_test(Type, Port, Host, Node, Rest).
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+validateRangeRequest(Socket,Response,ValidBody,C,O,DE)->
+ receive
+ {tcp,Socket,Data} ->
+ case string:str(Data,"\r\n") of
+ 0->
+ validateRangeRequest(Socket,
+ Response ++ Data,
+ ValidBody, C, O, DE);
+ _N ->
+ case Response ++ Data of
+ [$H,$T,$T,$P,$/,$1,$.,$1,$ ,C,O,DE | _Rest]->
+ case [C,O,DE] of
+ "206" ->
+ validateRangeRequest1(Socket,
+ Response ++ Data,
+ ValidBody);
+ _ ->
+ bad_code
+ end;
+ _->
+ error
+ end
+ end;
+ _Error ->
+ error
+ end.
+
+validateRangeRequest1(Socket, Response, ValidBody) ->
+ case end_of_header(Response) of
+ false ->
+ receive
+ {tcp,Socket,Data} ->
+ validateRangeRequest1(Socket, Response ++ Data,
+ ValidBody);
+ _->
+ error
+ end;
+ {true, Head1, Body, _Size} ->
+ %% In this case size will be 0 if it is a multipart so
+ %% don't use it.
+ validateRangeRequest2(Socket, Head1, Body, ValidBody,
+ getRangeSize(Head1))
+ end.
+
+validateRangeRequest2(Socket, Head, Body, ValidBody, {multiPart,Boundary})->
+ case endReached(Body,Boundary) of
+ true ->
+ validateMultiPartRangeRequest(Body, ValidBody, Boundary);
+ false->
+ receive
+ {tcp, Socket, Data} ->
+ validateRangeRequest2(Socket, Head, Body ++ Data,
+ ValidBody, {multiPart, Boundary});
+ {tcp_closed, Socket} ->
+ error;
+ _ ->
+ error
+ end
+ end;
+
+validateRangeRequest2(Socket, Head, Body, ValidBody, BodySize)
+ when is_integer(BodySize) ->
+ case length(Body) of
+ Size when Size =:= BodySize ->
+ case Body of
+ ValidBody ->
+ ok;
+ Body ->
+ error
+ end;
+ Size when Size < BodySize ->
+ receive
+ {tcp, Socket, Data} ->
+ validateRangeRequest2(Socket, Head,
+ Body ++ Data, ValidBody, BodySize);
+ _ ->
+ error
+ end;
+ _ ->
+ error
+ end.
+
+
+validateMultiPartRangeRequest(Body, ValidBody, Boundary)->
+ case inets_regexp:split(Body,"--"++Boundary++"--") of
+ %%Last is the epilogue and must be ignored
+ {ok,[First | _Last]}->
+ %%First is now the actuall http request body.
+ case inets_regexp:split(First, "--" ++ Boundary) of
+ %%Parts is now a list of ranges and the heads for each range
+ %%Gues we try to split out the body
+ {ok,Parts}->
+ case lists:flatten(lists:map(fun splitRange/1,Parts)) of
+ ValidBody->
+ ok;
+ ParsedBody->
+ error = ParsedBody
+ end
+ end;
+ _ ->
+ error
+ end.
+
+
+splitRange(Part)->
+ case inets_regexp:split(Part, "\r\n\r\n") of
+ {ok,[_, Body]} ->
+ string:substr(Body, 1, length(Body) - 2);
+ _ ->
+ []
+ end.
+
+endReached(Body, Boundary)->
+ EndBound = "--" ++ Boundary ++ "--",
+ case string:str(Body, EndBound) of
+ 0 ->
+ false;
+ _ ->
+ true
+ end.
+
+getRangeSize(Head)->
+ case controlMimeType(Head) of
+ {multiPart, BoundaryString}->
+ {multiPart, BoundaryString};
+ _X1 ->
+ case inets_regexp:match(Head, ?CONTENT_RANGE "bytes=.*\r\n") of
+ {match, Start, Lenght} ->
+ %% Get the range data remove the fieldname and the
+ %% end of line.
+ RangeInfo = string:substr(Head, Start + 20,
+ Lenght - (20 - 2)),
+ rangeSize(RangeInfo);
+ _X2 ->
+ error
+ end
+ end.
+%%RangeInfo is NNN1-NNN2/NNN3
+%%NNN1=RangeStartByte
+%%NNN2=RangeEndByte
+%%NNN3=total amount of bytes in file
+rangeSize([$=|RangeInfo]) ->
+ rangeSize(RangeInfo);
+rangeSize(RangeInfo) ->
+ StartByte = lists:takewhile(fun(X)->
+ num(X, true)
+ end, RangeInfo),
+ RangeInfo2 = string:substr(RangeInfo, length(StartByte) + 2),
+ EndByte = lists:takewhile(fun(X)->
+ num(X,true)
+ end, RangeInfo2),
+ case list_to_integer(EndByte) - list_to_integer(StartByte) of
+ Val when is_number(Val) ->
+ %%Add one since it is startByte to endbyte ie 0-0 is 1
+ %%byte 0-99 is 100 bytes
+ Val + 1;
+ _Val ->
+ error
+ end.
+
+num(CharVal, RetVal) when (CharVal >= 48) andalso (CharVal =< 57) ->
+ RetVal;
+num(_CharVal, true) ->
+ false;
+num(_CharVal, false) ->
+ true.
+
+controlMimeType(Head)->
+ case inets_regexp:match(Head,?CONTENT_TYPE "multipart/byteranges.*\r\n") of
+ {match,Start,Length}->
+ FieldNameLen = length(?CONTENT_TYPE "multipart/byteranges"),
+ case clearBoundary(string:substr(Head, Start + FieldNameLen,
+ Length - (FieldNameLen+2))) of
+ error ->
+ error;
+ BoundaryStr ->
+ {multiPart,BoundaryStr}
+ end;
+ nomatch->
+ 0;
+ _ ->
+ error
+ end.
+
+clearBoundary(Boundary)->
+ case inets_regexp:match(Boundary, "boundary=.*\$") of
+ {match, Start1, Length1}->
+ BoundLen = length("boundary="),
+ string:substr(Boundary, Start1 + BoundLen, Length1 - BoundLen);
+ _ ->
+ error
+ end.
+
+
+end_of_header(HeaderPart) ->
+ case httpd_util:split(HeaderPart,"\r\n\r\n",2) of
+ {ok, [Head, Body]} ->
+ {true, Head, Body, get_body_size(Head)};
+ _Pos ->
+ false
+ end.
+
+get_body_size(Head) ->
+ case inets_regexp:match(Head,?CONTENT_LENGTH ".*\r\n") of
+ {match, Start, Length} ->
+ %% 15 is length of Content-Length,
+ %% 17 Is length of Content-Length and \r\
+ S = list_to_integer(
+ string:strip(string:substr(Head, Start + 15, Length-17))),
+ S;
+ _->
+ 0
+ end.
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
new file mode 100644
index 0000000000..7403d4a643
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -0,0 +1,2081 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(httpd_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("inets_test_lib.hrl").
+
+-include_lib("kernel/include/file.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_testcase/2, end_per_testcase/2,
+ init_per_suite/1, end_per_suite/1]).
+
+%% Test cases must be exported.
+-export([ip/1, ssl/1, http_1_1_ip/1, http_1_0_ip/1, http_0_9_ip/1,
+ ipv6/1, tickets/1]).
+
+%% Core Server tests
+-export([ip_mod_alias/1, ip_mod_actions/1, ip_mod_security/1, ip_mod_auth/1,
+ ip_mod_auth_api/1, ip_mod_auth_mnesia_api/1,
+ ip_mod_htaccess/1, ip_mod_cgi/1, ip_mod_esi/1,
+ ip_mod_get/1, ip_mod_head/1, ip_mod_all/1, ip_load_light/1,
+ ip_load_medium/1, ip_load_heavy/1, ip_dos_hostname/1,
+ ip_time_test/1, ip_block_disturbing_idle/1,
+ ip_block_non_disturbing_idle/1, ip_block_503/1,
+ ip_block_disturbing_active/1, ip_block_non_disturbing_active/1,
+ ip_block_disturbing_active_timeout_not_released/1,
+ ip_block_disturbing_active_timeout_released/1,
+ ip_block_non_disturbing_active_timeout_not_released/1,
+ ip_block_non_disturbing_active_timeout_released/1,
+ ip_block_disturbing_blocker_dies/1,
+ ip_block_non_disturbing_blocker_dies/1,
+ ip_restart_no_block/1, ip_restart_disturbing_block/1,
+ ip_restart_non_disturbing_block/1
+ ]).
+
+-export([ssl_mod_alias/1, ssl_mod_actions/1, ssl_mod_security/1,
+ ssl_mod_auth/1, ssl_mod_auth_api/1,
+ ssl_mod_auth_mnesia_api/1, ssl_mod_htaccess/1,
+ ssl_mod_cgi/1, ssl_mod_esi/1, ssl_mod_get/1, ssl_mod_head/1,
+ ssl_mod_all/1, ssl_load_light/1, ssl_load_medium/1,
+ ssl_load_heavy/1, ssl_dos_hostname/1, ssl_time_test/1,
+ ssl_restart_no_block/1, ssl_restart_disturbing_block/1,
+ ssl_restart_non_disturbing_block/1, ssl_block_disturbing_idle/1,
+ ssl_block_non_disturbing_idle/1, ssl_block_503/1,
+ ssl_block_disturbing_active/1, ssl_block_non_disturbing_active/1,
+ ssl_block_disturbing_active_timeout_not_released/1,
+ ssl_block_disturbing_active_timeout_released/1,
+ ssl_block_non_disturbing_active_timeout_not_released/1,
+ ssl_block_non_disturbing_active_timeout_released/1,
+ ssl_block_disturbing_blocker_dies/1,
+ ssl_block_non_disturbing_blocker_dies/1]).
+
+%%% HTTP 1.1 tests
+-export([ip_host/1, ip_chunked/1, ip_expect/1, ip_range/1,
+ ip_if_test/1, ip_http_trace/1, ip_http1_1_head/1,
+ ip_mod_cgi_chunked_encoding_test/1]).
+
+%%% HTTP 1.0 tests
+-export([ip_head_1_0/1, ip_get_1_0/1, ip_post_1_0/1]).
+
+%%% HTTP 0.9 tests
+-export([ip_get_0_9/1]).
+
+%%% Ticket tests
+-export([ticket_5775/1,ticket_5865/1,ticket_5913/1,ticket_6003/1,
+ ticket_7304/1]).
+
+%%% Misc
+-export([ipv6_hostname/1, ipv6_address/1]).
+
+%% Help functions
+-export([cleanup_mnesia/0, setup_mnesia/0, setup_mnesia/1]).
+
+-define(IP_PORT, 8898).
+-define(SSL_PORT, 8899).
+-define(MAX_HEADER_SIZE, 256).
+-define(IPV6_LOCAL_HOST, "0:0:0:0:0:0:0:1").
+
+%% Minutes before failed auths timeout.
+-define(FAIL_EXPIRE_TIME,1).
+
+%% Seconds before successful auths timeout.
+-define(AUTH_TIMEOUT,5).
+
+-record(httpd_user, {user_name, password, user_data}).
+-record(httpd_group,{group_name, userlist}).
+
+
+%%--------------------------------------------------------------------
+%% all(Arg) -> [Doc] | [Case] | {skip, Comment}
+%% Arg - doc | suite
+%% Doc - string()
+%% Case - atom()
+%% Name of a test case function.
+%% Comment - string()
+%% Description: Returns documentation/test cases in this test suite
+%% or a skip tuple if the platform is not supported.
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test the http server in the intes application."];
+all(suite) ->
+ [
+ ip,
+ ssl,
+ http_1_1_ip,
+ http_1_0_ip,
+ http_0_9_ip,
+ %% ipv6,
+ tickets
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ io:format(user, "init_per_suite -> entry with"
+ "~n Config: ~p"
+ "~n", [Config]),
+
+ PrivDir = ?config(priv_dir, Config),
+ SuiteTopDir = filename:join(PrivDir, ?MODULE),
+ case file:make_dir(SuiteTopDir) of
+ ok ->
+ ok;
+ {error, eexist} ->
+ ok;
+ Error ->
+ throw({error, {failed_creating_suite_top_dir, Error}})
+ end,
+
+ [{suite_top_dir, SuiteTopDir},
+ {node, node()},
+ {host, inets_test_lib:hostname()},
+ {address, getaddr()} | Config].
+
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+
+end_per_suite(_Config) ->
+ %% SuiteTopDir = ?config(suite_top_dir, Config),
+ %% inets_test_lib:del_dirs(SuiteTopDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ NewConfig = init_per_testcase2(Case, Config),
+ init_per_testcase3(Case, NewConfig).
+
+
+init_per_testcase2(Case, Config) ->
+
+ io:format(user, "~w:init_per_testcase2(~w) -> entry with"
+ "~n Config: ~p"
+ "~n", [?MODULE, Case, Config]),
+
+ IpNormal = integer_to_list(?IP_PORT) ++ ".conf",
+ IpHtacess = integer_to_list(?IP_PORT) ++ "htacess.conf",
+ SslNormal = integer_to_list(?SSL_PORT) ++ ".conf",
+ SslHtacess = integer_to_list(?SSL_PORT) ++ "htacess.conf",
+
+ DataDir = ?config(data_dir, Config),
+ SuiteTopDir = ?config(suite_top_dir, Config),
+
+ io:format(user, "~w:init_per_testcase2(~w) -> "
+ "~n SuiteDir: ~p"
+ "~n DataDir: ~p"
+ "~n", [?MODULE, Case, SuiteTopDir, DataDir]),
+
+ TcTopDir = filename:join(SuiteTopDir, Case),
+ ?line ok = file:make_dir(TcTopDir),
+
+ io:format(user, "~w:init_per_testcase2(~w) -> "
+ "~n TcTopDir: ~p"
+ "~n", [?MODULE, Case, TcTopDir]),
+
+ DataSrc = filename:join([DataDir, "server_root"]),
+ ServerRoot = filename:join([TcTopDir, "server_root"]),
+
+ io:format(user, "~w:init_per_testcase2(~w) -> "
+ "~n DataSrc: ~p"
+ "~n ServerRoot: ~p"
+ "~n", [?MODULE, Case, DataSrc, ServerRoot]),
+
+ ok = file:make_dir(ServerRoot),
+ ok = file:make_dir(filename:join([TcTopDir, "logs"])),
+
+ NewConfig = [{tc_top_dir, TcTopDir}, {server_root, ServerRoot} | Config],
+
+ io:format(user, "~w:init_per_testcase2(~w) -> "
+ "copy DataSrc to ServerRoot~n",
+ [?MODULE, Case]),
+
+ inets_test_lib:copy_dirs(DataSrc, ServerRoot),
+
+ io:format(user, "~w:init_per_testcase2(~w) -> fix cgi~n",
+ [?MODULE, Case]),
+ EnvCGI = filename:join([ServerRoot, "cgi-bin", "printenv.sh"]),
+ {ok, FileInfo} = file:read_file_info(EnvCGI),
+ ok = file:write_file_info(EnvCGI,
+ FileInfo#file_info{mode = 8#00755}),
+
+ EchoCGI = case test_server:os_type() of
+ {win32, _} ->
+ "cgi_echo.exe";
+ _ ->
+ "cgi_echo"
+ end,
+ CGIDir = filename:join([ServerRoot, "cgi-bin"]),
+ inets_test_lib:copy_file(EchoCGI, DataDir, CGIDir),
+ NewEchoCGI = filename:join([CGIDir, EchoCGI]),
+ {ok, FileInfo1} = file:read_file_info(NewEchoCGI),
+ ok = file:write_file_info(NewEchoCGI,
+ FileInfo1#file_info{mode = 8#00755}),
+
+ %% To be used by IP test cases
+ io:format(user, "~w:init_per_testcase2(~w) -> ip testcase setups~n",
+ [?MODULE, Case]),
+ create_config([{port, ?IP_PORT}, {sock_type, ip_comm} | NewConfig],
+ normal_acess, IpNormal),
+ create_config([{port, ?IP_PORT}, {sock_type, ip_comm} | NewConfig],
+ mod_htaccess, IpHtacess),
+
+ %% To be used by SSL test cases
+ io:format(user, "~w:init_per_testcase2(~w) -> ssl testcase setups~n",
+ [?MODULE, Case]),
+ create_config([{port, ?SSL_PORT}, {sock_type, ssl} | NewConfig],
+ normal_acess, SslNormal),
+ create_config([{port, ?SSL_PORT}, {sock_type, ssl} | NewConfig],
+ mod_htaccess, SslHtacess),
+
+ %% To be used by IPv6 test cases. Case-clause is so that
+ %% you can do ts:run(inets, httpd_SUITE, <test case>)
+ %% for all cases except the ipv6 cases as they depend
+ %% on 'test_host_ipv6_only' that will only be present
+ %% when you run the whole test suite due to shortcomings
+ %% of the test server.
+ %% case (catch ?config(test_host_ipv6_only, Config)) of
+ %% {_,IPv6Host,IPv6Adress,_,_} ->
+ %% create_ipv6_config([{port, ?IP_PORT},
+ %% {sock_type, ip_comm} | NewConfig],
+ %% "ipv6_hostname.conf", IPv6Host),
+ %% create_ipv6_config([{port, ?IP_PORT},
+ %% {sock_type, ip_comm} | NewConfig],
+ %% "ipv6_address.conf", IPv6Adress);
+ %% _ ->
+ %% ok
+ %% end,
+
+ io:format(user, "~w:init_per_testcase2(~w) -> done~n",
+ [?MODULE, Case]),
+
+ NewConfig.
+
+
+init_per_testcase3(Case, Config) ->
+ io:format(user, "~w:init_per_testcase3(~w) -> entry with"
+ "~n Config: ~p", [?MODULE, Case, Config]),
+
+ %% Clean up (we do not want this clean up in end_per_testcase
+ %% if init_per_testcase crases for some testcase it will
+ %% have contaminated the environment and there will be no clean up.)
+ %% This init can take a few different paths so that one crashes
+ %% does not mean that all invocations will.
+
+ application:unset_env(inets, services),
+ application:stop(inets),
+ application:stop(ssl),
+ cleanup_mnesia(),
+
+ %% TraceLevel = max,
+ TraceLevel = 70,
+ TraceDest = io,
+ inets:enable_trace(TraceLevel, TraceDest),
+
+ %% Start initialization
+ io:format(user, "~w:init_per_testcase3(~w) -> start init",
+ [?MODULE, Case]),
+
+ Dog = test_server:timetrap(inets_test_lib:minutes(10)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ TcTopDir = ?config(tc_top_dir, Config),
+ CaseRest =
+ case atom_to_list(Case) of
+ "ip_mod_htaccess" ->
+ inets_test_lib:start_http_server(
+ filename:join(TcTopDir,
+ integer_to_list(?IP_PORT) ++
+ "htacess.conf")),
+ "mod_htaccess";
+ "ip_" ++ Rest ->
+ inets_test_lib:start_http_server(
+ filename:join(TcTopDir,
+ integer_to_list(?IP_PORT) ++ ".conf")),
+ Rest;
+ "ticket_5913" ->
+ HttpdOptions =
+ [{file,
+ filename:join(TcTopDir,
+ integer_to_list(?IP_PORT) ++ ".conf")},
+ {accept_timeout,30000},
+ {debug,[{exported_functions,
+ [httpd_manager,httpd_request_handler]}]}],
+ inets_test_lib:start_http_server(HttpdOptions);
+ "ticket_"++Rest ->
+ %% OTP-5913 use the new syntax of inets.config
+ inets_test_lib:start_http_server([{file,
+ filename:join(TcTopDir,
+ integer_to_list(?IP_PORT) ++ ".conf")}]),
+ Rest;
+ "ssl_mod_htaccess" ->
+ case inets_test_lib:start_http_server_ssl(
+ filename:join(TcTopDir,
+ integer_to_list(?SSL_PORT) ++
+ "htacess.conf")) of
+ ok ->
+ "mod_htaccess";
+ Other ->
+ error_logger:info_report("Other: ~p~n", [Other]),
+ {skip, "SSL does not seem to be supported"}
+ end;
+ "ssl_" ++ Rest ->
+ case inets_test_lib:start_http_server_ssl(
+ filename:join(TcTopDir,
+ integer_to_list(?SSL_PORT) ++
+ ".conf")) of
+ ok ->
+ Rest;
+ Other ->
+ error_logger:info_report("Other: ~p~n", [Other]),
+ {skip, "SSL does not seem to be supported"}
+ end;
+ "ipv6_" ++ _ = TestCaseStr ->
+ {ok, Hostname} = inet:gethostname(),
+
+ case lists:member(list_to_atom(Hostname),
+ ?config(ipv6_hosts, Config)) of
+ true ->
+ inets_test_lib:start_http_server(
+ filename:join(TcTopDir,
+ TestCaseStr ++ ".conf"));
+
+ false ->
+ {skip, "Host does not support IPv6"}
+ end
+ end,
+
+ case CaseRest of
+ {skip, _} = Skip ->
+ Skip;
+ "mod_auth_" ++ _ ->
+ start_mnesia(?config(node, Config)),
+ [{watchdog, Dog} | NewConfig];
+ "mod_htaccess" ->
+ ServerRoot = ?config(server_root, Config),
+ Path = filename:join([ServerRoot, "htdocs"]),
+ catch remove_htacess(Path),
+ create_htacess_data(Path, ?config(address, Config)),
+ [{watchdog, Dog} | NewConfig];
+ "range" ->
+ ServerRoot = ?config(server_root, Config),
+ Path = filename:join([ServerRoot, "htdocs"]),
+ create_range_data(Path),
+ [{watchdog, Dog} | NewConfig];
+ _ ->
+ [{watchdog, Dog} | NewConfig]
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ end_per_testcase2(Case, lists:keydelete(watchdog, 1, Config)),
+ ok.
+
+end_per_testcase2(Case, Config) ->
+ io:format(user, "~w:end_per_testcase2(~w) -> entry with"
+ "~n Config: ~p~n",
+ [?MODULE, Case, Config]),
+ application:unset_env(inets, services),
+ application:stop(inets),
+ application:stop(ssl),
+ cleanup_mnesia(),
+ io:format(user, "~w:end_per_testcase2(~w) -> done~n",
+ [?MODULE, Case]),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+ip(doc) ->
+ ["HTTP tests using TCP/IP"];
+ip(suite) ->
+ [
+ ip_mod_alias,
+ ip_mod_actions,
+ ip_mod_security,
+ ip_mod_auth,
+ ip_mod_auth_api,
+ ip_mod_auth_mnesia_api,
+ ip_mod_htaccess,
+ ip_mod_cgi,
+ ip_mod_esi,
+ ip_mod_get,
+ ip_mod_head,
+ ip_mod_all,
+ ip_load_light,
+ ip_load_medium,
+ ip_load_heavy,
+ ip_dos_hostname,
+ ip_time_test,
+ ip_block_disturbing_idle,
+ ip_block_non_disturbing_idle,
+ ip_block_503,
+ ip_block_disturbing_active,
+ ip_block_non_disturbing_active,
+ ip_block_disturbing_active_timeout_not_released,
+ ip_block_disturbing_active_timeout_released,
+ ip_block_non_disturbing_active_timeout_not_released,
+ ip_block_non_disturbing_active_timeout_released,
+ ip_block_disturbing_blocker_dies,
+ ip_block_non_disturbing_blocker_dies,
+ ip_restart_no_block,
+ ip_restart_disturbing_block,
+ ip_restart_non_disturbing_block
+ ].
+
+%%-------------------------------------------------------------------------
+ssl(doc) ->
+ ["HTTP test using SSL"];
+ssl(suite) ->
+ [
+ ssl_mod_alias,
+ ssl_mod_actions,
+ ssl_mod_security,
+ ssl_mod_auth,
+ ssl_mod_auth_api,
+ ssl_mod_auth_mnesia_api,
+ ssl_mod_htaccess,
+ ssl_mod_cgi,
+ ssl_mod_esi,
+ ssl_mod_get,
+ ssl_mod_head,
+ ssl_mod_all,
+ ssl_load_light,
+ ssl_load_medium,
+ ssl_load_heavy,
+ ssl_dos_hostname,
+ ssl_time_test,
+ ssl_restart_no_block,
+ ssl_restart_disturbing_block,
+ ssl_restart_non_disturbing_block,
+ ssl_block_disturbing_idle,
+ ssl_block_non_disturbing_idle,
+ ssl_block_503,
+ ssl_block_disturbing_active,
+ ssl_block_non_disturbing_active,
+ ssl_block_disturbing_active_timeout_not_released,
+ ssl_block_disturbing_active_timeout_released,
+ ssl_block_non_disturbing_active_timeout_not_released,
+ ssl_block_non_disturbing_active_timeout_released,
+ ssl_block_disturbing_blocker_dies,
+ ssl_block_non_disturbing_blocker_dies
+ ].
+
+%%-------------------------------------------------------------------------
+http_1_1_ip(doc) ->
+ ["HTTP/1.1"];
+http_1_1_ip(suite) ->
+ [
+ ip_host,
+ ip_chunked,
+ ip_expect,
+ ip_range,
+ ip_if_test,
+ ip_http_trace,
+ ip_http1_1_head,
+ ip_mod_cgi_chunked_encoding_test
+ ].
+
+%%-------------------------------------------------------------------------
+http_1_0_ip(doc) ->
+ ["HTTP/1.0"];
+http_1_0_ip(suite) ->
+ [
+ ip_head_1_0,
+ ip_get_1_0,
+ ip_post_1_0
+ ].
+
+%%-------------------------------------------------------------------------
+http_0_9_ip(doc) ->
+ ["HTTP/0.9"];
+http_0_9_ip(suite) ->
+ [
+ ip_get_0_9
+ ].
+
+%%-------------------------------------------------------------------------
+ipv6(doc) ->
+ ["Tests ipv6 functionality."];
+ipv6(suite) ->
+ [
+ ipv6_hostname,
+ ipv6_address
+ ].
+
+%%-------------------------------------------------------------------------
+tickets(doc) ->
+ ["Test cases for reported bugs."];
+tickets(suite) ->
+ [
+ ticket_5775,
+ ticket_5865,
+ ticket_5913,
+ ticket_6003,
+ ticket_7304
+ ].
+
+%%-------------------------------------------------------------------------
+ip_mod_alias(doc) ->
+ ["Module test: mod_alias"];
+ip_mod_alias(suite) ->
+ [];
+ip_mod_alias(Config) when is_list(Config) ->
+ httpd_mod:alias(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_actions(doc) ->
+ ["Module test: mod_actions"];
+ip_mod_actions(suite) ->
+ [];
+ip_mod_actions(Config) when is_list(Config) ->
+ httpd_mod:actions(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_security(doc) ->
+ ["Module test: mod_security"];
+ip_mod_security(suite) ->
+ [];
+ip_mod_security(Config) when is_list(Config) ->
+ ServerRoot = ?config(server_root, Config),
+ httpd_mod:security(ServerRoot, ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_mod_auth(doc) ->
+ ["Module test: mod_auth"];
+ip_mod_auth(suite) ->
+ [];
+ip_mod_auth(Config) when is_list(Config) ->
+ httpd_mod:auth(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_mod_auth_api(doc) ->
+ ["Module test: mod_auth_api"];
+ip_mod_auth_api(suite) ->
+ [];
+ip_mod_auth_api(Config) when is_list(Config) ->
+ ServerRoot = ?config(server_root, Config),
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ httpd_mod:auth_api(ServerRoot, "", ip_comm, ?IP_PORT, Host, Node),
+ httpd_mod:auth_api(ServerRoot, "dets_", ip_comm, ?IP_PORT, Host, Node),
+ httpd_mod:auth_api(ServerRoot, "mnesia_", ip_comm, ?IP_PORT, Host, Node),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_auth_mnesia_api(doc) ->
+ ["Module test: mod_auth_mnesia_api"];
+ip_mod_auth_mnesia_api(suite) ->
+ [];
+ip_mod_auth_mnesia_api(Config) when is_list(Config) ->
+ httpd_mod:auth_mnesia_api(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_htaccess(doc) ->
+ ["Module test: mod_htaccess"];
+ip_mod_htaccess(suite) ->
+ [];
+ip_mod_htaccess(Config) when is_list(Config) ->
+ httpd_mod:htaccess(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_cgi(doc) ->
+ ["Module test: mod_cgi"];
+ip_mod_cgi(suite) ->
+ [];
+ip_mod_cgi(Config) when is_list(Config) ->
+ case test_server:os_type() of
+ vxworks ->
+ {skip, cgi_not_supported_on_vxwoks};
+ _ ->
+ httpd_mod:cgi(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok
+ end.
+%%-------------------------------------------------------------------------
+ip_mod_esi(doc) ->
+ ["Module test: mod_esi"];
+ip_mod_esi(suite) ->
+ [];
+ip_mod_esi(Config) when is_list(Config) ->
+ httpd_mod:esi(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_mod_get(doc) ->
+ ["Module test: mod_get"];
+ip_mod_get(suite) ->
+ [];
+ip_mod_get(Config) when is_list(Config) ->
+ httpd_mod:get(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_mod_head(doc) ->
+ ["Module test: mod_head"];
+ip_mod_head(suite) ->
+ [];
+ip_mod_head(Config) when is_list(Config) ->
+ httpd_mod:head(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_all(doc) ->
+ ["All modules test"];
+ip_mod_all(suite) ->
+ [];
+ip_mod_all(Config) when is_list(Config) ->
+ httpd_mod:all(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_load_light(doc) ->
+ ["Test light load"];
+ip_load_light(suite) ->
+ [];
+ip_load_light(Config) when is_list(Config) ->
+ httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ip_comm, light)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_load_medium(doc) ->
+ ["Test medium load"];
+ip_load_medium(suite) ->
+ [];
+ip_load_medium(Config) when is_list(Config) ->
+ httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ip_comm, medium)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_load_heavy(doc) ->
+ ["Test heavy load"];
+ip_load_heavy(suite) ->
+ [];
+ip_load_heavy(Config) when is_list(Config) ->
+ httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ip_comm, heavy)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_dos_hostname(doc) ->
+ ["Denial Of Service (DOS) attack test case"];
+ip_dos_hostname(suite) ->
+ [];
+ip_dos_hostname(Config) when is_list(Config) ->
+ dos_hostname(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config), ?MAX_HEADER_SIZE),
+ ok.
+%%-------------------------------------------------------------------------
+ip_time_test(doc) ->
+ [""];
+ip_time_test(suite) ->
+ [];
+ip_time_test(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Skippable = [win32],
+ Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_time_test:t(ip_comm, ?config(host, Config), ?IP_PORT),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_block_503(doc) ->
+ ["Check that you will receive status code 503 when the server"
+ " is blocked and 200 when its not blocked."];
+ip_block_503(suite) ->
+ [];
+ip_block_503(Config) when is_list(Config) ->
+ httpd_block:block_503(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_disturbing_idle(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "distribing does not really make a difference in this case."];
+ip_block_disturbing_idle(suite) ->
+ [];
+ip_block_disturbing_idle(Config) when is_list(Config) ->
+ httpd_block:block_disturbing_idle(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_non_disturbing_idle(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "non distribing does not really make a difference in this case."];
+ip_block_non_disturbing_idle(suite) ->
+ [];
+ip_block_non_disturbing_idle(Config) when is_list(Config) ->
+ httpd_block:block_non_disturbing_idle(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_disturbing_active(doc) ->
+ ["Check that you can block/unblock an active server. The strategy "
+ "distribing means ongoing requests should be terminated."];
+ip_block_disturbing_active(suite) ->
+ [];
+ip_block_disturbing_active(Config) when is_list(Config) ->
+ httpd_block:block_disturbing_active(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_non_disturbing_active(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "non distribing means the ongoing requests should be compleated."];
+ip_block_non_disturbing_active(suite) ->
+ [];
+ip_block_non_disturbing_active(Config) when is_list(Config) ->
+ httpd_block:block_non_disturbing_idle(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_block_disturbing_active_timeout_not_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "distribing means ongoing requests should be compleated"
+ "if the timeout does not occur."];
+ip_block_disturbing_active_timeout_not_released(suite) ->
+ [];
+ip_block_disturbing_active_timeout_not_released(Config)
+ when is_list(Config) ->
+ httpd_block:block_disturbing_active_timeout_not_released(ip_comm,
+ ?IP_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_disturbing_active_timeout_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "distribing means ongoing requests should be terminated when"
+ "the timeout occurs."];
+ip_block_disturbing_active_timeout_released(suite) ->
+ [];
+ip_block_disturbing_active_timeout_released(Config)
+ when is_list(Config) ->
+ httpd_block:block_disturbing_active_timeout_released(ip_comm,
+ ?IP_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_block_non_disturbing_active_timeout_not_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "non non distribing means ongoing requests should be completed."];
+ip_block_non_disturbing_active_timeout_not_released(suite) ->
+ [];
+ip_block_non_disturbing_active_timeout_not_released(Config)
+ when is_list(Config) ->
+ httpd_block:
+ block_non_disturbing_active_timeout_not_released(ip_comm,
+ ?IP_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_non_disturbing_active_timeout_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "non non distribing means ongoing requests should be completed. "
+ "When the timeout occurs the block operation sohould be canceled." ];
+ip_block_non_disturbing_active_timeout_released(suite) ->
+ [];
+ip_block_non_disturbing_active_timeout_released(Config)
+ when is_list(Config) ->
+ httpd_block:
+ block_non_disturbing_active_timeout_released(ip_comm,
+ ?IP_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_disturbing_blocker_dies(doc) ->
+ [];
+ip_block_disturbing_blocker_dies(suite) ->
+ [];
+ip_block_disturbing_blocker_dies(Config) when is_list(Config) ->
+ httpd_block:disturbing_blocker_dies(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_non_disturbing_blocker_dies(doc) ->
+ [];
+ip_block_non_disturbing_blocker_dies(suite) ->
+ [];
+ip_block_non_disturbing_blocker_dies(Config) when is_list(Config) ->
+ httpd_block:non_disturbing_blocker_dies(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_restart_no_block(doc) ->
+ [""];
+ip_restart_no_block(suite) ->
+ [];
+ip_restart_no_block(Config) when is_list(Config) ->
+ httpd_block:restart_no_block(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_restart_disturbing_block(doc) ->
+ [""];
+ip_restart_disturbing_block(suite) ->
+ [];
+ip_restart_disturbing_block(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Condition =
+ fun() ->
+ case os:type() of
+ {unix, linux} ->
+ HW = string:strip(os:cmd("uname -m"), right, $\n),
+ case HW of
+ "ppc" ->
+ case inet:gethostname() of
+ {ok, "peach"} ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end
+ end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_block:restart_disturbing_block(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_restart_non_disturbing_block(doc) ->
+ [""];
+ip_restart_non_disturbing_block(suite) ->
+ [];
+ip_restart_non_disturbing_block(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Condition =
+ fun() ->
+ case os:type() of
+ {unix, linux} ->
+ HW = string:strip(os:cmd("uname -m"), right, $\n),
+ case HW of
+ "ppc" ->
+ case inet:gethostname() of
+ {ok, "peach"} ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end
+ end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_block:restart_non_disturbing_block(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_mod_alias(doc) ->
+ ["Module test: mod_alias"];
+ssl_mod_alias(suite) ->
+ [];
+ssl_mod_alias(Config) when is_list(Config) ->
+ httpd_mod:alias(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_actions(doc) ->
+ ["Module test: mod_actions"];
+ssl_mod_actions(suite) ->
+ [];
+ssl_mod_actions(Config) when is_list(Config) ->
+ httpd_mod:actions(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_security(doc) ->
+ ["Module test: mod_security"];
+ssl_mod_security(suite) ->
+ [];
+ssl_mod_security(Config) when is_list(Config) ->
+ ServerRoot = ?config(server_root, Config),
+ httpd_mod:security(ServerRoot, ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_auth(doc) ->
+ ["Module test: mod_auth"];
+ssl_mod_auth(suite) ->
+ [];
+ssl_mod_auth(Config) when is_list(Config) ->
+ httpd_mod:auth(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_auth_api(doc) ->
+ ["Module test: mod_auth"];
+ssl_mod_auth_api(suite) ->
+ [];
+ssl_mod_auth_api(Config) when is_list(Config) ->
+ ServerRoot = ?config(server_root, Config),
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ httpd_mod:auth_api(ServerRoot, "", ssl, ?SSL_PORT, Host, Node),
+ httpd_mod:auth_api(ServerRoot, "dets_", ssl, ?SSL_PORT, Host, Node),
+ httpd_mod:auth_api(ServerRoot, "mnesia_", ssl, ?SSL_PORT, Host, Node),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_mod_auth_mnesia_api(doc) ->
+ ["Module test: mod_auth_mnesia_api"];
+ssl_mod_auth_mnesia_api(suite) ->
+ [];
+ssl_mod_auth_mnesia_api(Config) when is_list(Config) ->
+ httpd_mod:auth_mnesia_api(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_htaccess(doc) ->
+ ["Module test: mod_htaccess"];
+ssl_mod_htaccess(suite) ->
+ [];
+ssl_mod_htaccess(Config) when is_list(Config) ->
+ httpd_mod:htaccess(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_cgi(doc) ->
+ ["Module test: mod_cgi"];
+ssl_mod_cgi(suite) ->
+ [];
+ssl_mod_cgi(Config) when is_list(Config) ->
+ case test_server:os_type() of
+ vxworks ->
+ {skip, cgi_not_supported_on_vxwoks};
+ _ ->
+ httpd_mod:cgi(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok
+ end.
+%%-------------------------------------------------------------------------
+ssl_mod_esi(doc) ->
+ ["Module test: mod_esi"];
+ssl_mod_esi(suite) ->
+ [];
+ssl_mod_esi(Config) when is_list(Config) ->
+ httpd_mod:esi(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_mod_get(doc) ->
+ ["Module test: mod_get"];
+ssl_mod_get(suite) ->
+ [];
+ssl_mod_get(Config) when is_list(Config) ->
+ httpd_mod:get(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_head(doc) ->
+ ["Module test: mod_head"];
+ssl_mod_head(suite) ->
+ [];
+ssl_mod_head(Config) when is_list(Config) ->
+ httpd_mod:head(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_all(doc) ->
+ ["All modules test"];
+ssl_mod_all(suite) ->
+ [];
+ssl_mod_all(Config) when is_list(Config) ->
+ httpd_mod:all(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_load_light(doc) ->
+ ["Test light load"];
+ssl_load_light(suite) ->
+ [];
+ssl_load_light(Config) when is_list(Config) ->
+ httpd_load:load_test(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ssl, light)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_load_medium(doc) ->
+ ["Test medium load"];
+ssl_load_medium(suite) ->
+ [];
+ssl_load_medium(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Skippable = [win32],
+ Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_load:load_test(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ssl, medium)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_load_heavy(doc) ->
+ ["Test heavy load"];
+ssl_load_heavy(suite) ->
+ [];
+ssl_load_heavy(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Skippable = [win32],
+ Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_load:load_test(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ssl, heavy)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_dos_hostname(doc) ->
+ ["Denial Of Service (DOS) attack test case"];
+ssl_dos_hostname(suite) ->
+ [];
+ssl_dos_hostname(Config) when is_list(Config) ->
+ dos_hostname(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config), ?MAX_HEADER_SIZE),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_time_test(doc) ->
+ [""];
+ssl_time_test(suite) ->
+ [];
+ssl_time_test(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Condition = fun() -> true end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_time_test:t(ssl, ?config(host, Config), ?SSL_PORT),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_block_503(doc) ->
+ ["Check that you will receive status code 503 when the server"
+ " is blocked and 200 when its not blocked."];
+ssl_block_503(suite) ->
+ [];
+ssl_block_503(Config) when is_list(Config) ->
+ httpd_block:block_503(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_disturbing_idle(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "distribing does not really make a difference in this case."];
+ssl_block_disturbing_idle(suite) ->
+ [];
+ssl_block_disturbing_idle(Config) when is_list(Config) ->
+ httpd_block:block_disturbing_idle(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_non_disturbing_idle(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "non distribing does not really make a difference in this case."];
+ssl_block_non_disturbing_idle(suite) ->
+ [];
+ssl_block_non_disturbing_idle(Config) when is_list(Config) ->
+ httpd_block:block_non_disturbing_idle(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_disturbing_active(doc) ->
+ ["Check that you can block/unblock an active server. The strategy "
+ "distribing means ongoing requests should be terminated."];
+ssl_block_disturbing_active(suite) ->
+ [];
+ssl_block_disturbing_active(Config) when is_list(Config) ->
+ httpd_block:block_disturbing_active(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_non_disturbing_active(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "non distribing means the ongoing requests should be compleated."];
+ssl_block_non_disturbing_active(suite) ->
+ [];
+ssl_block_non_disturbing_active(Config) when is_list(Config) ->
+ httpd_block:block_non_disturbing_idle(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_block_disturbing_active_timeout_not_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "distribing means ongoing requests should be compleated"
+ "if the timeout does not occur."];
+ssl_block_disturbing_active_timeout_not_released(suite) ->
+ [];
+ssl_block_disturbing_active_timeout_not_released(Config)
+ when is_list(Config) ->
+ httpd_block:
+ block_disturbing_active_timeout_not_released(ssl,
+ ?SSL_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_disturbing_active_timeout_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "distribing means ongoing requests should be terminated when"
+ "the timeout occurs."];
+ssl_block_disturbing_active_timeout_released(suite) ->
+ [];
+ssl_block_disturbing_active_timeout_released(Config)
+ when is_list(Config) ->
+ httpd_block:block_disturbing_active_timeout_released(ssl,
+ ?SSL_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_block_non_disturbing_active_timeout_not_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "non non distribing means ongoing requests should be completed."];
+ssl_block_non_disturbing_active_timeout_not_released(suite) ->
+ [];
+ssl_block_non_disturbing_active_timeout_not_released(Config)
+ when is_list(Config) ->
+ httpd_block:
+ block_non_disturbing_active_timeout_not_released(ssl,
+ ?SSL_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_non_disturbing_active_timeout_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "non non distribing means ongoing requests should be completed. "
+ "When the timeout occurs the block operation sohould be canceled." ];
+ssl_block_non_disturbing_active_timeout_released(suite) ->
+ [];
+ssl_block_non_disturbing_active_timeout_released(Config)
+ when is_list(Config) ->
+ httpd_block:
+ block_non_disturbing_active_timeout_released(ssl,
+ ?SSL_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_block_disturbing_blocker_dies(doc) ->
+ [];
+ssl_block_disturbing_blocker_dies(suite) ->
+ [];
+ssl_block_disturbing_blocker_dies(Config) when is_list(Config) ->
+ httpd_block:disturbing_blocker_dies(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_non_disturbing_blocker_dies(doc) ->
+ [];
+ssl_block_non_disturbing_blocker_dies(suite) ->
+ [];
+ssl_block_non_disturbing_blocker_dies(Config) when is_list(Config) ->
+ httpd_block:non_disturbing_blocker_dies(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_restart_no_block(doc) ->
+ [""];
+ssl_restart_no_block(suite) ->
+ [];
+ssl_restart_no_block(Config) when is_list(Config) ->
+ httpd_block:restart_no_block(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_restart_disturbing_block(doc) ->
+ [""];
+ssl_restart_disturbing_block(suite) ->
+ [];
+ssl_restart_disturbing_block(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Condition =
+ fun() ->
+ case os:type() of
+ {unix, linux} ->
+ HW = string:strip(os:cmd("uname -m"), right, $\n),
+ case HW of
+ "ppc" ->
+ case inet:gethostname() of
+ {ok, "peach"} ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end
+ end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_block:restart_disturbing_block(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_restart_non_disturbing_block(doc) ->
+ [""];
+ssl_restart_non_disturbing_block(suite) ->
+ [];
+ssl_restart_non_disturbing_block(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Condition =
+ fun() ->
+ case os:type() of
+ {unix, linux} ->
+ HW = string:strip(os:cmd("uname -m"), right, $\n),
+ case HW of
+ "ppc" ->
+ case inet:gethostname() of
+ {ok, "peach"} ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end
+ end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_block:restart_non_disturbing_block(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_host(doc) ->
+ ["Control that the server accepts/rejects requests with/ without host"];
+ip_host(suite)->
+ [];
+ip_host(Config) when is_list(Config) ->
+ httpd_1_1:host(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_chunked(doc) ->
+ ["Control that the server accepts chunked requests"];
+ip_chunked(suite) ->
+ [];
+ip_chunked(Config) when is_list(Config) ->
+ httpd_1_1:chunked(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_expect(doc) ->
+ ["Control that the server handles request with the expect header "
+ "field appropiate"];
+ip_expect(suite)->
+ [];
+ip_expect(Config) when is_list(Config) ->
+ httpd_1_1:expect(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_range(doc) ->
+ ["Control that the server can handle range requests to plain files"];
+ip_range(suite)->
+ [];
+ip_range(Config) when is_list(Config) ->
+ httpd_1_1:range(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_if_test(doc) ->
+ ["Test that the if - request header fields is handled correclty"];
+ip_if_test(suite) ->
+ [];
+ip_if_test(Config) when is_list(Config) ->
+ ServerRoot = ?config(server_root, Config),
+ DocRoot = filename:join([ServerRoot, "htdocs"]),
+ httpd_1_1:if_test(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config), DocRoot),
+ ok.
+%%-------------------------------------------------------------------------
+ip_http_trace(doc) ->
+ ["Test the trace module "];
+ip_http_trace(suite) ->
+ [];
+ip_http_trace(Config) when is_list(Config) ->
+ httpd_1_1:http_trace(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_http1_1_head(doc) ->
+ ["Test the trace module "];
+ip_http1_1_head(suite)->
+ [];
+ip_http1_1_head(Config) when is_list(Config) ->
+ httpd_1_1:head(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_get_0_9(doc) ->
+ ["Test simple HTTP/0.9 GET"];
+ip_get_0_9(suite)->
+ [];
+ip_get_0_9(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "GET / \r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/0.9"} ]),
+ %% Without space after uri
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "GET /\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/0.9"} ]),
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "GET / HTTP/0.9\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/0.9"}]),
+
+ ok.
+%%-------------------------------------------------------------------------
+ip_head_1_0(doc) ->
+ ["Test HTTP/1.0 HEAD"];
+ip_head_1_0(suite)->
+ [];
+ip_head_1_0(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "HEAD / HTTP/1.0\r\n\r\n", [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+
+ ok.
+%%-------------------------------------------------------------------------
+ip_get_1_0(doc) ->
+ ["Test HTTP/1.0 GET"];
+ip_get_1_0(suite)->
+ [];
+ip_get_1_0(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "GET / HTTP/1.0\r\n\r\n", [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+
+ ok.
+%%-------------------------------------------------------------------------
+ip_post_1_0(doc) ->
+ ["Test HTTP/1.0 POST"];
+ip_post_1_0(suite)->
+ [];
+ip_post_1_0(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ %% Test the post message formatin 1.0! Real post are testes elsewhere
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "POST / HTTP/1.0\r\n\r\n "
+ "Content-Length:6 \r\n\r\nfoobar",
+ [{statuscode, 500}, {version, "HTTP/1.0"}]),
+
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_cgi_chunked_encoding_test(doc) ->
+ ["Test the trace module "];
+ip_mod_cgi_chunked_encoding_test(suite)->
+ [];
+ip_mod_cgi_chunked_encoding_test(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ Script =
+ case test_server:os_type() of
+ {win32, _} ->
+ "/cgi-bin/printenv.bat";
+ _ ->
+ "/cgi-bin/printenv.sh"
+ end,
+ Requests =
+ ["GET " ++ Script ++ " HTTP/1.1\r\nHost:"++ Host ++"\r\n\r\n",
+ "GET /cgi-bin/erl/httpd_example/newformat HTTP/1.1\r\nHost:"
+ ++ Host ++"\r\n\r\n"],
+ httpd_1_1:mod_cgi_chunked_encoding_test(ip_comm, ?IP_PORT,
+ Host,
+ ?config(node, Config),
+ Requests),
+ ok.
+
+%-------------------------------------------------------------------------
+ipv6_hostname(doc) ->
+ ["Test standard ipv6 address"];
+ipv6_hostname(suite)->
+ [];
+ipv6_hostname(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, node(),
+ "GET / HTTP/1.1\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.1"}]),
+ ok.
+
+%%-------------------------------------------------------------------------
+ipv6_address(doc) ->
+ ["Test standard ipv6 address"];
+ipv6_address(suite)->
+ [];
+ipv6_address(Config) when is_list(Config) ->
+ httpd_test_lib:verify_request(ip_comm, ?IPV6_LOCAL_HOST, ?IP_PORT,
+ node(), "GET / HTTP/1.1\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.1"}]),
+ ok.
+
+%%--------------------------------------------------------------------
+ticket_5775(doc) ->
+ ["Tests that content-length is correct"];
+ticket_5775(suite) ->
+ [];
+ticket_5775(Config) ->
+ ok=httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
+ ?IP_PORT, ?config(node, Config),
+ "GET /cgi-bin/erl/httpd_example:get_bin "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok.
+ticket_5865(doc) ->
+ ["Tests that a header without last-modified is handled"];
+ticket_5865(suite) ->
+ [];
+ticket_5865(Config) ->
+ Host = ?config(host,Config),
+ ServerRoot = ?config(server_root, Config),
+ DocRoot = filename:join([ServerRoot, "htdocs"]),
+ File = filename:join([DocRoot,"last_modified.html"]),
+
+ Bad_mtime = case test_server:os_type() of
+ {win32, _} ->
+ {{1600,12,31},{23,59,59}};
+ {unix, _} ->
+ {{1969,12,31},{23,59,59}}
+ end,
+
+ {ok,FI}=file:read_file_info(File),
+
+ case file:write_file_info(File,FI#file_info{mtime=Bad_mtime}) of
+ ok ->
+ ok = httpd_test_lib:verify_request(ip_comm, Host,
+ ?IP_PORT, ?config(node, Config),
+ "GET /last_modified.html"
+ " HTTP/1.1\r\nHost:"
+ ++Host++"\r\n\r\n",
+ [{statuscode, 200},
+ {no_last_modified,
+ "last-modified"}]),
+ ok;
+ {error, Reason} ->
+ Fault =
+ io_lib:format("Attempt to change the file info to set the"
+ " preconditions of the test case failed ~p~n",
+ [Reason]),
+ {skip, Fault}
+ end.
+
+ticket_5913(doc) ->
+ ["Tests that a header without last-modified is handled"];
+ticket_5913(suite) -> [];
+ticket_5913(Config) ->
+ ok=httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
+ ?IP_PORT, ?config(node, Config),
+ "GET /cgi-bin/erl/httpd_example:get_bin "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok.
+
+ticket_6003(doc) ->
+ ["Tests that a URI with a bad hexadecimal code is handled"];
+ticket_6003(suite) -> [];
+ticket_6003(Config) ->
+ ok=httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
+ ?IP_PORT, ?config(node, Config),
+ "GET http://www.erlang.org/%skalle "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 400},
+ {version, "HTTP/1.0"}]),
+ ok.
+
+ticket_7304(doc) ->
+ ["Tests missing CR in delimiter"];
+ticket_7304(suite) ->
+ [];
+ticket_7304(Config) ->
+ ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
+ ?IP_PORT, ?config(node, Config),
+ "GET / HTTP/1.0\r\n\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+dos_hostname(Type, Port, Host, Node, Max) ->
+ H1 = {"", 200},
+ H2 = {"dummy-host.ericsson.se", 200},
+ TooLongHeader = lists:append(lists:duplicate(Max + 1, "a")),
+ H3 = {TooLongHeader, 403},
+ Hosts = [H1,H2,H3],
+ dos_hostname_poll(Type, Host, Port, Node, Hosts).
+
+%% make_ipv6(T) when is_tuple(T) andalso (size(T) =:= 8) ->
+%% make_ipv6(tuple_to_list(T));
+
+%% make_ipv6([_, _, _, _, _, _, _, _] = IPV6) ->
+%% lists:flatten(io_lib:format("~s:~s:~s:~s:~s:~s:~s:~s", IPV6)).
+
+
+%%--------------------------------------------------------------------
+%% Other help functions
+create_config(Config, Access, FileName) ->
+ ServerRoot = ?config(server_root, Config),
+ TcTopDir = ?config(tc_top_dir, Config),
+ Port = ?config(port, Config),
+ Type = ?config(sock_type, Config),
+ Host = ?config(host, Config),
+ Mods = io_lib:format("~p", [httpd_mod]),
+ Funcs = io_lib:format("~p", [ssl_password_cb]),
+ MaxHdrSz = io_lib:format("~p", [256]),
+ MaxHdrAct = io_lib:format("~p", [close]),
+ SSL =
+ case Type of
+ ssl ->
+ [cline(["SSLCertificateFile ",
+ filename:join(ServerRoot, "ssl/ssl_server.pem")]),
+ cline(["SSLCertificateKeyFile ",
+ filename:join(ServerRoot, "ssl/ssl_server.pem")]),
+ cline(["SSLCACertificateFile ",
+ filename:join(ServerRoot, "ssl/ssl_server.pem")]),
+ cline(["SSLPasswordCallbackModule ", Mods]),
+ cline(["SSLPasswordCallbackFunction ", Funcs]),
+ cline(["SSLVerifyClient 0"]),
+ cline(["SSLVerifyDepth 1"])];
+ _ ->
+ []
+ end,
+ Mod_order = case Access of
+ mod_htaccess ->
+ "Modules mod_alias mod_htaccess mod_auth "
+ "mod_security "
+ "mod_responsecontrol mod_trace mod_esi "
+ "mod_actions mod_cgi mod_include mod_dir "
+ "mod_range mod_get "
+ "mod_head mod_log mod_disk_log";
+ _ ->
+ "Modules mod_alias mod_auth mod_security "
+ "mod_responsecontrol mod_trace mod_esi "
+ "mod_actions mod_cgi mod_include mod_dir "
+ "mod_range mod_get "
+ "mod_head mod_log mod_disk_log"
+ end,
+
+%% The test suite currently does not handle an explicit BindAddress.
+%% They assume any has been used, that is Addr is always set to undefined!
+
+%% {ok, Hostname} = inet:gethostname(),
+%% {ok, Addr} = inet:getaddr(Hostname, inet6),
+%% AddrStr = make_ipv6(Addr),
+%% BindAddress = lists:flatten(io_lib:format("~s|inet6", [AddrStr])),
+
+ %% BindAddress = "*|inet",
+ BindAddress = "*",
+
+ HttpConfig = [
+ cline(["Port ", integer_to_list(Port)]),
+ cline(["ServerName ", Host]),
+ cline(["SocketType ", atom_to_list(Type)]),
+ cline([Mod_order]),
+ %% cline(["LogFormat ", "erlang"]),
+ cline(["ServerAdmin [email protected]"]),
+ cline(["BindAddress ", BindAddress]),
+ cline(["ServerRoot ", ServerRoot]),
+ cline(["ErrorLog ", TcTopDir,
+ "/logs/error_log_", integer_to_list(Port)]),
+ cline(["TransferLog ", TcTopDir,
+ "/logs/access_log_", integer_to_list(Port)]),
+ cline(["SecurityLog ", TcTopDir,
+ "/logs/security_log_", integer_to_list(Port)]),
+ cline(["ErrorDiskLog ", TcTopDir,
+ "/logs/error_disk_log_", integer_to_list(Port)]),
+ cline(["ErrorDiskLogSize ", "190000 ", "11"]),
+ cline(["TransferDiskLog ", TcTopDir,
+ "/logs/access_disk_log_", integer_to_list(Port)]),
+ cline(["TransferDiskLogSize ", "200000 ", "10"]),
+ cline(["SecurityDiskLog ", TcTopDir,
+ "/logs/security_disk_log_", integer_to_list(Port)]),
+ cline(["SecurityDiskLogSize ", "210000 ", "9"]),
+ cline(["MaxClients 10"]),
+ cline(["MaxHeaderSize ", MaxHdrSz]),
+ cline(["MaxHeaderAction ", MaxHdrAct]),
+ cline(["DocumentRoot ",
+ filename:join(ServerRoot, "htdocs")]),
+ cline(["DirectoryIndex ", "index.html ", "welcome.html"]),
+ cline(["DefaultType ", "text/plain"]),
+ SSL,
+ mod_alias_config(ServerRoot),
+
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "open"]),
+ "Open Area",
+ filename:join(ServerRoot, "auth/passwd"),
+ filename:join(ServerRoot, "auth/group"),
+ plain,
+ "user one Aladdin",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "secret"]),
+ "Secret Area",
+ filename:join(ServerRoot, "auth/passwd"),
+ filename:join(ServerRoot, "auth/group"),
+ plain,
+ "group group1 group2",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "secret",
+ "top_secret"]),
+ "Top Secret Area",
+ filename:join(ServerRoot, "auth/passwd"),
+ filename:join(ServerRoot, "auth/group"),
+ plain,
+ "group group3",
+ filename:join(ServerRoot, "security_data")),
+
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "dets_open"]),
+ "Dets Open Area",
+ filename:join(ServerRoot, "passwd"),
+ filename:join(ServerRoot, "group"),
+ dets,
+ "user one Aladdin",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "dets_secret"]),
+ "Dets Secret Area",
+ filename:join(ServerRoot, "passwd"),
+ filename:join(ServerRoot, "group"),
+ dets,
+ "group group1 group2",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "dets_secret",
+ "top_secret"]),
+ "Dets Top Secret Area",
+ filename:join(ServerRoot, "passwd"),
+ filename:join(ServerRoot, "group"),
+ dets,
+ "group group3",
+ filename:join(ServerRoot, "security_data")),
+
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "mnesia_open"]),
+ "Mnesia Open Area",
+ false,
+ false,
+ mnesia,
+ "user one Aladdin",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "mnesia_secret"]),
+ "Mnesia Secret Area",
+ false,
+ false,
+ mnesia,
+ "group group1 group2",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join(
+ [ServerRoot, "htdocs", "mnesia_secret",
+ "top_secret"]),
+ "Mnesia Top Secret Area",
+ false,
+ false,
+ mnesia,
+ "group group3",
+ filename:join(ServerRoot, "security_data"))
+ ],
+ ConfigFile = filename:join([TcTopDir, FileName]),
+ {ok, Fd} = file:open(ConfigFile, [write]),
+ ok = file:write(Fd, lists:flatten(HttpConfig)),
+ ok = file:close(Fd).
+
+config_directory(Dir, AuthName, AuthUserFile, AuthGroupFile, AuthDBType,
+ Require, SF) ->
+ file:delete(SF),
+ [
+ cline(["<Directory ", Dir, ">"]),
+ cline(["SecurityDataFile ", SF]),
+ cline(["SecurityMaxRetries 3"]),
+ cline(["SecurityFailExpireTime ", integer_to_list(?FAIL_EXPIRE_TIME)]),
+ cline(["SecurityBlockTime 1"]),
+ cline(["SecurityAuthTimeout ", integer_to_list(?AUTH_TIMEOUT)]),
+ cline(["SecurityCallbackModule ", "httpd_mod"]),
+ cline_if_set("AuthUserFile", AuthUserFile),
+ cline_if_set("AuthGroupFile", AuthGroupFile),
+ cline_if_set("AuthName", AuthName),
+ cline_if_set("AuthDBType", AuthDBType),
+ cline(["require ", Require]),
+ cline(["</Directory>\r\n"])
+ ].
+
+mod_alias_config(Root) ->
+ [
+ cline(["Alias /icons/ ", filename:join(Root,"icons"), "/"]),
+ cline(["Alias /pics/ ", filename:join(Root, "icons"), "/"]),
+ cline(["ScriptAlias /cgi-bin/ ", filename:join(Root, "cgi-bin"), "/"]),
+ cline(["ScriptAlias /htbin/ ", filename:join(Root, "cgi-bin"), "/"]),
+ cline(["ErlScriptAlias /cgi-bin/erl httpd_example io"]),
+ cline(["EvalScriptAlias /eval httpd_example io"])
+ ].
+
+cline(List) ->
+ lists:flatten([List, "\r\n"]).
+
+cline_if_set(_, false) ->
+ [];
+cline_if_set(Name, Var) when is_list(Var) ->
+ cline([Name, " ", Var]);
+cline_if_set(Name, Var) when is_atom(Var) ->
+ cline([Name, " ", atom_to_list(Var)]).
+
+getaddr() ->
+ {ok,HostName} = inet:gethostname(),
+ {ok,{A1,A2,A3,A4}} = inet:getaddr(HostName,inet),
+ lists:flatten(io_lib:format("~p.~p.~p.~p",[A1,A2,A3,A4])).
+
+start_mnesia(Node) ->
+ case rpc:call(Node, ?MODULE, cleanup_mnesia, []) of
+ ok ->
+ ok;
+ Other ->
+ test_server:fail({failed_to_cleanup_mnesia, Other})
+ end,
+ case rpc:call(Node, ?MODULE, setup_mnesia, []) of
+ {atomic, ok} ->
+ ok;
+ Other2 ->
+ test_server:fail({failed_to_setup_mnesia, Other2})
+ end,
+ ok.
+
+setup_mnesia() ->
+ setup_mnesia([node()]).
+
+setup_mnesia(Nodes) ->
+ ok = mnesia:create_schema(Nodes),
+ ok = mnesia:start(),
+ {atomic, ok} = mnesia:create_table(httpd_user,
+ [{attributes,
+ record_info(fields, httpd_user)},
+ {disc_copies,Nodes}, {type, set}]),
+ {atomic, ok} = mnesia:create_table(httpd_group,
+ [{attributes,
+ record_info(fields,
+ httpd_group)},
+ {disc_copies,Nodes}, {type,bag}]).
+
+cleanup_mnesia() ->
+ mnesia:start(),
+ mnesia:delete_table(httpd_user),
+ mnesia:delete_table(httpd_group),
+ stopped = mnesia:stop(),
+ mnesia:delete_schema([node()]),
+ ok.
+
+create_htacess_data(Path, IpAddress)->
+ create_htacess_dirs(Path),
+
+ create_html_file(filename:join([Path,"ht/open/dummy.html"])),
+ create_html_file(filename:join([Path,"ht/blocknet/dummy.html"])),
+ create_html_file(filename:join([Path,"ht/secret/dummy.html"])),
+ create_html_file(filename:join([Path,"ht/secret/top_secret/dummy.html"])),
+
+ create_htacess_file(filename:join([Path,"ht/open/.htaccess"]),
+ Path, "user one Aladdin"),
+ create_htacess_file(filename:join([Path,"ht/secret/.htaccess"]),
+ Path, "group group1 group2"),
+ create_htacess_file(filename:join([Path,
+ "ht/secret/top_secret/.htaccess"]),
+ Path, "user four"),
+ create_htacess_file(filename:join([Path,"ht/blocknet/.htaccess"]),
+ Path, nouser, IpAddress),
+
+ create_user_group_file(filename:join([Path,"ht","users.file"]),
+ "one:OnePassword\ntwo:TwoPassword\nthree:"
+ "ThreePassword\nfour:FourPassword\nAladdin:"
+ "AladdinPassword"),
+ create_user_group_file(filename:join([Path,"ht","groups.file"]),
+ "group1: two one\ngroup2: two three").
+
+create_html_file(PathAndFileName)->
+ file:write_file(PathAndFileName,list_to_binary(
+ "<html><head><title>test</title></head>
+ <body>testar</body></html>")).
+
+create_htacess_file(PathAndFileName, BaseDir, RequireData)->
+ file:write_file(PathAndFileName,
+ list_to_binary(
+ "AuthUserFile "++ BaseDir ++
+ "/ht/users.file\nAuthGroupFile "++ BaseDir
+ ++ "/ht/groups.file\nAuthName Test\nAuthType"
+ " Basic\n<Limit>\nrequire " ++ RequireData ++
+ "\n</Limit>")).
+
+create_htacess_file(PathAndFileName, BaseDir, nouser, IpAddress)->
+ file:write_file(PathAndFileName,list_to_binary(
+ "AuthUserFile "++ BaseDir ++
+ "/ht/users.file\nAuthGroupFile " ++
+ BaseDir ++ "/ht/groups.file\nAuthName"
+ " Test\nAuthType"
+ " Basic\n<Limit GET>\n\tallow from " ++
+ format_ip(IpAddress,
+ string:rchr(IpAddress,$.)) ++
+ "\n</Limit>")).
+
+create_user_group_file(PathAndFileName, Data)->
+ file:write_file(PathAndFileName, list_to_binary(Data)).
+
+create_htacess_dirs(Path)->
+ ok = file:make_dir(filename:join([Path,"ht"])),
+ ok = file:make_dir(filename:join([Path,"ht/open"])),
+ ok = file:make_dir(filename:join([Path,"ht/blocknet"])),
+ ok = file:make_dir(filename:join([Path,"ht/secret"])),
+ ok = file:make_dir(filename:join([Path,"ht/secret/top_secret"])).
+
+remove_htacess_dirs(Path)->
+ file:del_dir(filename:join([Path,"ht/secret/top_secret"])),
+ file:del_dir(filename:join([Path,"ht/secret"])),
+ file:del_dir(filename:join([Path,"ht/blocknet"])),
+ file:del_dir(filename:join([Path,"ht/open"])),
+ file:del_dir(filename:join([Path,"ht"])).
+
+format_ip(IpAddress,Pos)when Pos > 0->
+ case lists:nth(Pos,IpAddress) of
+ $.->
+ case lists:nth(Pos-2,IpAddress) of
+ $.->
+ format_ip(IpAddress,Pos-3);
+ _->
+ lists:sublist(IpAddress,Pos-2) ++ "."
+ end;
+ _ ->
+ format_ip(IpAddress,Pos-1)
+ end;
+
+format_ip(IpAddress, _Pos)->
+ "1" ++ IpAddress.
+
+remove_htacess(Path)->
+ file:delete(filename:join([Path,"ht/open/dummy.html"])),
+ file:delete(filename:join([Path,"ht/secret/dummy.html"])),
+ file:delete(filename:join([Path,"ht/secret/top_secret/dummy.html"])),
+ file:delete(filename:join([Path,"ht/blocknet/dummy.html"])),
+ file:delete(filename:join([Path,"ht/blocknet/.htaccess"])),
+ file:delete(filename:join([Path,"ht/open/.htaccess"])),
+ file:delete(filename:join([Path,"ht/secret/.htaccess"])),
+ file:delete(filename:join([Path,"ht/secret/top_secret/.htaccess"])),
+ file:delete(filename:join([Path,"ht","users.file"])),
+ file:delete(filename:join([Path,"ht","groups.file"])),
+ remove_htacess_dirs(Path).
+
+
+dos_hostname_poll(Type, Host, Port, Node, Hosts) ->
+ [dos_hostname_poll1(Type, Host, Port, Node, Host1, Code)
+ || {Host1,Code} <- Hosts].
+
+dos_hostname_poll1(Type, Host, Port, Node, Host1, Code) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ dos_hostname_request(Host1),
+ [{statuscode, Code},
+ {version, "HTTP/1.0"}]).
+
+dos_hostname_request(Host) ->
+ "GET / HTTP/1.0\r\n" ++ Host ++ "\r\n\r\n".
+
+get_nof_clients(Mode, Load) ->
+ get_nof_clients(test_server:os_type(), Mode, Load).
+
+get_nof_clients(vxworks, _, light) -> 1;
+get_nof_clients(vxworks, ip_comm, medium) -> 3;
+get_nof_clients(vxworks, ssl, medium) -> 3;
+get_nof_clients(vxworks, ip_comm, heavy) -> 5;
+get_nof_clients(vxworks, ssl, heavy) -> 5;
+get_nof_clients(_, ip_comm, light) -> 5;
+get_nof_clients(_, ssl, light) -> 2;
+get_nof_clients(_, ip_comm, medium) -> 10;
+get_nof_clients(_, ssl, medium) -> 4;
+get_nof_clients(_, ip_comm, heavy) -> 20;
+get_nof_clients(_, ssl, heavy) -> 6.
+
+%% Make a file 100 bytes long containing 012...9*10
+create_range_data(Path)->
+ PathAndFileName=filename:join([Path,"range.txt"]),
+ file:write_file(PathAndFileName,list_to_binary(["12345678901234567890",
+ "12345678901234567890",
+ "12345678901234567890",
+ "12345678901234567890",
+ "12345678901234567890"])).
+
+%% create_ipv6_config(Config, FileName, Ipv6Address) ->
+%% ServerRoot = ?config(server_root, Config),
+%% TcTopDir = ?config(tc_top_dir, Config),
+%% Port = ?config(port, Config),
+%% SockType = ?config(sock_type, Config),
+%%
+%% MaxHdrSz = io_lib:format("~p", [256]),
+%% MaxHdrAct = io_lib:format("~p", [close]),
+%%
+%% Mod_order = "Modules mod_alias mod_auth mod_esi mod_actions mod_cgi"
+%% " mod_include mod_dir mod_get mod_head"
+%% " mod_log mod_disk_log mod_trace",
+%%
+%% HttpConfig = [cline(["BindAddress ", "[" ++ Ipv6Address ++"]|inet6"]),
+%% cline(["Port ", integer_to_list(Port)]),
+%% cline(["ServerName ", "httpc_test"]),
+%% cline(["SocketType ", atom_to_list(SockType)]),
+%% cline([Mod_order]),
+%% cline(["ServerRoot ", ServerRoot]),
+%% cline(["DocumentRoot ",
+%% filename:join(ServerRoot, "htdocs")]),
+%% cline(["MaxHeaderSize ",MaxHdrSz]),
+%% cline(["MaxHeaderAction ",MaxHdrAct]),
+%% cline(["DirectoryIndex ", "index.html "]),
+%% cline(["DefaultType ", "text/plain"])],
+%% ConfigFile = filename:join([TcTopDir,FileName]),
+%% {ok, Fd} = file:open(ConfigFile, [write]),
+%% ok = file:write(Fd, lists:flatten(HttpConfig)),
+%% ok = file:close(Fd).
diff --git a/lib/inets/test/httpd_SUITE_data/Makefile.src b/lib/inets/test/httpd_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..b0fdb43d8d
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/Makefile.src
@@ -0,0 +1,14 @@
+CC = @CC@
+LD = @LD@
+CFLAGS = @CFLAGS@ -I@erl_include@ @DEFS@
+CROSSLDFLAGS = @CROSSLDFLAGS@
+
+PROGS = cgi_echo@exe@
+
+all: $(PROGS)
+
+cgi_echo@exe@: cgi_echo@obj@
+ $(LD) $(CROSSLDFLAGS) -o cgi_echo cgi_echo@obj@ @LIBS@
+
+cgi_echo@obj@: cgi_echo.c
+ $(CC) -c -o cgi_echo@obj@ $(CFLAGS) cgi_echo.c
diff --git a/lib/inets/test/httpd_SUITE_data/cgi_echo.c b/lib/inets/test/httpd_SUITE_data/cgi_echo.c
new file mode 100644
index 0000000000..580f860e96
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/cgi_echo.c
@@ -0,0 +1,97 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#if defined __WIN32__
+#include <windows.h>
+#include <fcntl.h>
+#endif
+
+static int read_exact(char *buffer, int len);
+static int write_exact(char *buffer, int len);
+
+int main(void)
+{
+ char msg[100];
+ int msg_len;
+#ifdef __WIN32__
+ _setmode(_fileno( stdin), _O_BINARY);
+ _setmode(_fileno( stdout), _O_BINARY);
+#endif
+ msg_len = read_exact(msg, 100);
+
+ write_exact("Content-type: text/plain\r\n\r\n", 28);
+ write_exact(msg, msg_len);
+ exit(EXIT_SUCCESS);
+}
+
+
+/* read from stdin */
+#ifdef __WIN32__
+static int read_exact(char *buffer, int len)
+{
+ HANDLE standard_input = GetStdHandle(STD_INPUT_HANDLE);
+
+ unsigned read_result;
+ unsigned sofar = 0;
+
+ if (!len) { /* Happens for "empty packages */
+ return 0;
+ }
+ for (;;) {
+ if (!ReadFile(standard_input, buffer + sofar,
+ len - sofar, &read_result, NULL)) {
+ return -1; /* EOF */
+ }
+ if (!read_result) {
+ return -2; /* Interrupted while reading? */
+ }
+ sofar += read_result;
+ if (sofar == len) {
+ return len;
+ }
+ }
+}
+#else
+static int read_exact(char *buffer, int len) {
+ int i, got = 0;
+
+ do {
+ if ((i = read(0, buffer + got, len - got)) <= 0)
+ return(i);
+ got += i;
+ } while (got < len);
+ return len;
+
+}
+#endif
+
+/* write to stdout */
+#ifdef __WIN32__
+ static int write_exact(char *buffer, int len)
+ {
+ HANDLE standard_output = GetStdHandle(STD_OUTPUT_HANDLE);
+ unsigned written;
+
+ if (!WriteFile(standard_output, buffer, len, &written, NULL)) {
+ return -1; /* Broken Pipe */
+ }
+ if (written < ((unsigned) len)) {
+ /* This should not happen, standard output is not blocking? */
+ return -2;
+ }
+
+ return (int) written;
+}
+
+#else
+ static int write_exact(char *buffer, int len) {
+ int i, wrote = 0;
+
+ do {
+ if ((i = write(1, buffer + wrote, len - wrote)) <= 0)
+ return i;
+ wrote += i;
+ } while (wrote < len);
+ return len;
+ }
+#endif
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/auth/group b/lib/inets/test/httpd_SUITE_data/server_root/auth/group
new file mode 100644
index 0000000000..b3da0ccbd3
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/auth/group
@@ -0,0 +1,3 @@
+group1: one two
+group2: two three
+group3: three Aladdin
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/auth/passwd b/lib/inets/test/httpd_SUITE_data/server_root/auth/passwd
new file mode 100644
index 0000000000..8c980ff547
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/auth/passwd
@@ -0,0 +1,4 @@
+one:onePassword
+two:twoPassword
+three:threePassword
+Aladdin:AladdinPassword
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.bat b/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.bat
new file mode 100644
index 0000000000..25a49a1536
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.bat
@@ -0,0 +1,9 @@
+@echo off
+echo tomrad > c:\cygwin\tmp\hej
+echo Content-type: text/html
+echo.
+echo ^<HTML^> ^<HEAD^> ^<TITLE^>OS Environment^</TITLE^> ^</HEAD^> ^<BODY^>^<PRE^>
+set
+echo ^</PRE^>^</BODY^>^</HTML^>
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.sh b/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.sh
new file mode 100755
index 0000000000..de81de9bde
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+echo "Content-type: text/html"
+echo ""
+echo "<HTML> <HEAD> <TITLE>OS Environment</TITLE> </HEAD> <BODY><PRE>"
+env
+echo "</PRE></BODY></HTML>" \ No newline at end of file
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf b/lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf
new file mode 100644
index 0000000000..48e66f0114
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf
@@ -0,0 +1,79 @@
+Port 8080
+#ServerName your.server.net
+SocketType ip_comm
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8080
+TransferLog logs/access_log_8080
+SecurityLog logs/security_log_8080
+ErrorDiskLog logs/error_disk_log_8080
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8080
+TransferDiskLogSize 200000 10
+SecurityDiskLog logs/security_disk_log
+SecurityDiskLogSize 200000 10
+MaxClients 50
+#KeepAlive 5
+#KeepAliveTimeout 10
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthDBType plain
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthDBType plain
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthDBType plain
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthDBType mnesia
+AuthName Open Area
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthDBType mnesia
+AuthName Secret Area
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthDBType mnesia
+AuthName Top Secret Area
+require group group3
+allow from 130.100.34 130.100.35
+deny from 100.234.22.12 194.100.34.1 130.100.34.25
+SecurityDataFile logs/security_data
+SecurityMaxRetries 3
+SecurityBlockTime 10
+SecurityFailExpireTime 1
+SecurityAuthTimeout 1
+SecurityCallbackModule security_callback
+</Directory>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf b/lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf
new file mode 100644
index 0000000000..79bb7fcca4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf
@@ -0,0 +1,63 @@
+Port 8888
+#ServerName your.server.net
+SocketType ip_comm
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8888
+TransferLog logs/access_log_8888
+ErrorDiskLog logs/error_disk_log_8888
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8888
+TransferDiskLogSize 200000 10
+MaxClients 150
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthName Open Area
+AuthMnesiaDB On
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthName Secret Area
+AuthMnesiaDB On
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthName Top Secret Area
+AuthMnesiaDB On
+require group group3
+</Directory>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf b/lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf
new file mode 100644
index 0000000000..8a74ed1afd
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf
@@ -0,0 +1,268 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+
+# Port: The port the standalone listens to. For ports < 1023, you will
+# need httpd to be run as root initially.
+
+Port 8888
+
+# BindAddress: This directive is used to tell the server which IP address
+# to listen to. It can either contain "*", an IP address, or a fully
+# qualified Internet domain name.
+#
+# It is also possible to specify the ip-family with the directive.
+# There ar three possible value: inet, inet6 and inet6fb4
+# inet: Use IpFamily inet when retreiving the address and
+# fail if that does not work.
+# inet6: Use IpFamily inet6 when retreiving the address and
+# fail if that does not work.
+# inet6fb4: First IpFamily inet6 is tried and if that does not work,
+# inet is used as fallback.
+# Default value for ip-family is inet6fb4
+#
+# The syntax is: <address>[|<ip-family>]
+#
+#BindAddress *
+#BindAddress *|inet
+
+
+# ServerName allows you to set a host name which is sent back to clients for
+# your server if it's different than the one the program would get (i.e. use
+# "www" instead of the host's real name).
+#
+# Note: You cannot just invent host names and hope they work. The name you
+# define here must be a valid DNS name for your host. If you don't understand
+# this, ask your network administrator.
+
+#ServerName your.server.net
+
+# SocketType is either ip_comm, sockets or ssl.
+
+SocketType ip_comm
+
+# Modules: Server run-time plug-in modules written using the Erlang
+# Web Server API (EWSAPI). The server API make it easy to add functionality
+# to the server. Read more about EWSAPI in the Reference Manual.
+# WARNING! Do not tamper with this directive unless you are familiar with
+# EWSAPI.
+
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_responsecontrol mod_trace mod_range mod_head mod_include mod_dir mod_get mod_log mod_disk_log
+
+# ServerAdmin: Your address, where problems with the server should be
+# e-mailed.
+
+ServerAdmin [email protected]
+
+# ServerRoot: The directory the server's config, error, and log files
+# are kept in
+
+ServerRoot /var/tmp/server_root
+
+# ErrorLog: The location of the error log file. If this does not start
+# with /, ServerRoot is prepended to it.
+
+ErrorLog logs/error_log
+
+# TransferLog: The location of the transfer log file. If this does not
+# start with /, ServerRoot is prepended to it.
+
+TransferLog logs/access_log
+
+# SecurityLog: The location of the security log file (mod_security required)
+#
+SecurityLog logs/security_log
+
+# ErrorDiskLog: The location of the error log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The ErrorDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+ErrorDiskLog logs/error_disk_log
+ErrorDiskLogSize 200000 10
+
+# TransferDiskLog: The location of the transfer log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The TransferDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+TransferDiskLog logs/access_disk_log
+TransferDiskLogSize 200000 10
+
+# SecurityDiskLog: The location of the security log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The SecurityDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+SecurityDiskLog logs/security_disk_log
+SecurityDiskLogSize 200000 10
+
+# Limit on total number of servers running, i.e., limit on the number
+# of clients who can simultaneously connect --- if this limit is ever
+# reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW.
+# It is intended mainly as a brake to keep a runaway server from taking
+# the server with it as it spirals down...
+
+MaxClients 50
+
+# KeepAlive set the flag for persistent connections. For peristent connections
+# set KeepAlive to on. To use One request per connection set the flag to off
+# Note: The value has changed since previous version of INETS.
+KeepAlive on
+
+# KeepAliveTimeout sets the number of seconds before a persistent connection
+# times out and closes.
+KeepAliveTimeout 10
+
+# MaxKeepAliveRequests sets the number of seconds before a persistent connection
+# times out and closes.
+MaxKeepAliveRequests 10
+
+
+
+# DocumentRoot: The directory out of which you will serve your
+# documents. By default, all requests are taken from this directory, but
+# symbolic links and aliases may be used to point to other locations.
+
+DocumentRoot /var/tmp/server_root/htdocs
+
+# DirectoryIndex: Name of the file or files to use as a pre-written HTML
+# directory index. Separate multiple entries with spaces.
+
+DirectoryIndex index.html welcome.html
+
+# DefaultType is the default MIME type for documents which the server
+# cannot find the type of from filename extensions.
+
+DefaultType text/plain
+
+# Aliases: Add here as many aliases as you need (with no limit). The format is
+# Alias fakename realname
+
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+
+# ScriptAlias: This controls which directories contain server scripts.
+# Format: ScriptAlias fakename realname
+
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+
+# This directive adds an action, which will activate cgi-script when a
+# file is requested using the method of method, which can be one of
+# GET, POST and HEAD. It sends the URL and file path of the requested
+# document using the standard CGI PATH_INFO and PATH_TRANSLATED
+# environment variables.
+
+#Script HEAD /cgi-bin/printenv.sh
+
+# This directive adds an action, which will activate cgi-script when a
+# file of content type mime-type is requested. It sends the URL and
+# file path of the requested document using the standard CGI PATH_INFO
+# and PATH_TRANSLATED environment variables.
+
+#Action image/gif /cgi-bin/printenv.sh
+
+# ErlScriptAlias: This specifies how "Erl" server scripts are called.
+# Format: ErlScriptAlias fakename realname allowed_modules
+
+ErlScriptAlias /down/erl httpd_example io
+
+# EvalScriptAlias: This specifies how "Eval" server scripts are called.
+# Format: EvalScriptAlias fakename realname allowed_modules
+
+EvalScriptAlias /eval httpd_example io
+
+# Point SSLCertificateFile at a PEM encoded certificate.
+
+SSLCertificateFile /var/tmp/server_root/ssl/ssl_server.pem
+
+# If the key is not combined with the certificate, use this directive to
+# point at the key file.
+
+SSLCertificateKeyFile /var/tmp/server_root/ssl/ssl_server.pem
+
+# Set SSLVerifyClient to:
+# 0 if no certicate is required
+# 1 if the client may present a valid certificate
+# 2 if the client must present a valid certificate
+# 3 if the client may present a valid certificate but it is not required to
+# have a valid CA
+
+SSLVerifyClient 0
+
+# Each directory to which INETS has access, can be configured with respect
+# to which services and features are allowed and/or disabled in that
+# directory (and its subdirectories).
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthDBType plain
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthDBType plain
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthDBType plain
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthDBType mnesia
+AuthName Open Area
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthDBType mnesia
+AuthName Secret Area
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthDBType mnesia
+AuthName Top Secret Area
+require group group3
+allow from 130.100.34 130.100.35
+deny from 100.234.22.12 194.100.34.1 130.100.34.25
+SecurityDataFile logs/security_data
+SecurityMaxRetries 3
+SecurityBlockTime 10
+SecurityFailExpireTime 1
+SecurityAuthTimeout 1
+SecurityCallbackModule security_callback
+</Directory>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types b/lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types
new file mode 100644
index 0000000000..d2f81e4e5e
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types
@@ -0,0 +1,465 @@
+# This is a comment. I love comments.
+
+# MIME type Extension
+application/EDI-Consent
+application/EDI-X12
+application/EDIFACT
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atomicmail
+application/batch-SMTP
+application/beep+xml
+application/cals-1840
+application/commonground
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/eshop
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/font-tdpfr
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathematica-old
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll
+application/oda oda
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/qsig
+application/remote-printing
+application/riscos
+application/rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/smil smi smil
+application/timestamp-query
+application/timestamp-reply
+application/vemmi
+application/vnd.3M.Post-it-Notes
+application/vnd.FloGraphIt
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.aether.imp
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.businessobjects
+application/vnd.bmi
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.comsocaller
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.ctc-posml
+application/vnd.cybank
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hhe.lesson-player
+application/vnd.hp-HPGL
+application/vnd.hp-PCL
+application/vnd.hp-PCLXL
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.MiniPay
+application/vnd.ibm.modcap
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.koan
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.EDM
+application/vnd.novadigm.EDX
+application/vnd.novadigm.EXT
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-xhtml-print+xml
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.tve-trigger
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.vividence.scriptfile
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yellowriver-custom-menu
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xml
+application/xml-dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/basic au snd
+audio/g.722.1
+audio/l16
+audio/midi mid midi kar
+audio/mp4a-latm
+audio/mpa-robust
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/prs.sid
+audio/telephone-event
+audio/tone
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-mpegurl m3u
+audio/x-pn-realaudio ram rm
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/tiff tiff tif
+image/vnd.cns.inf2
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.mix
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar
+text/css css
+text/directory
+text/enriched
+text/html html htm
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/tab-separated-values tsv
+text/t140
+text/uri-list
+text/vnd.DMClientScript
+text/vnd.IPTC.NITF
+text/vnd.IPTC.NewsML
+text/vnd.abc
+text/vnd.curl
+text/vnd.flatland.3dml
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-setext etx
+text/x-server-parsed-html shtml
+text/xml xml xsl
+text/xml-external-parsed-entity
+video/mp4v-es
+video/mpeg mpeg mpg mpe
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu
+video/vnd.mts
+video/vnd.nokia.interleaved-multimedia
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf b/lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf
new file mode 100644
index 0000000000..8b8c57a98b
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf
@@ -0,0 +1,66 @@
+Port 8088
+#ServerName your.server.net
+SocketType ssl
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8088
+TransferLog logs/access_log_8088
+ErrorDiskLog logs/error_disk_log_8088
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8088
+TransferDiskLogSize 200000 10
+MaxClients 150
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+SSLCertificateFile /var/tmp/server_root/ssl/ssl_server.pem
+SSLCertificateKeyFile /var/tmp/server_root/ssl/ssl_server.pem
+SSLVerifyClient 0
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthName Open Area
+AuthMnesiaDB On
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthName Secret Area
+AuthMnesiaDB On
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthName Top Secret Area
+AuthMnesiaDB On
+require group group3
+</Directory>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/config.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/config.shtml
new file mode 100644
index 0000000000..107e3ff610
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/config.shtml
@@ -0,0 +1,70 @@
+<HTML>
+<HEAD>
+<TITLE>/ssi.html (17-Apr-1997)</TITLE>
+</HEAD>
+<BODY>
+<H1>/ssi.html</H1>
+
+<!-- ************* CONFIG ************* -->
+
+<!--#config timefmt="%a %b %e %T %Z %Y" sizefmt="abbrev"-->
+<!--#config errmsg="[an especially ugly error occurred while processing this directive]"-->
+
+<!-- ************* INCLUDE ************* -->
+
+<P>Include /misc/friedrich.html:
+<!--#include virtual="/misc/friedrich.html"-->
+<P>Include /misc/not_defined.html: <!--#include virtual="/misc/not_defined.html"-->
+<P>Include misc/friedrich.html:
+<!--#include file="misc/friedrich.html"-->
+<P>Include not_defined.html: <!--#include file="not_defined.html"-->
+
+<P><HR>
+
+<!-- ************* ECHO ************* -->
+
+<P>DOCUMENT_NAME: <!--#echo var="DOCUMENT_NAME"-->
+<P>DOCUMENT_URI: <!--#echo var="DOCUMENT_URI"-->
+<P>QUERY_STRING_UNESCAPED: <!--#echo var="QUERY_STRING_UNESCAPED"-->
+<P>DATE_LOCAL: <!--#echo var="DATE_LOCAL"-->
+<P>DATE_GMT: <!--#echo var="DATE_GMT"-->
+<P>LAST_MODIFIED: <!--#echo var="LAST_MODIFIED"-->
+<P>NOT_DEFINED: <!--#echo var="NOT_DEFINED"-->
+
+<P><HR>
+
+<!-- ************* FSIZE ************* -->
+
+<P>Size of index.html: <!--#fsize file="index.html"-->
+<P>Size of not_defined.html: <!--#fsize file="not_defined.html"-->
+<!--#config sizefmt="bytes"-->
+<P>Size of /misc/friedrich.html: <!--#fsize virtual="/misc/friedrich.html"-->
+<P>Size of /misc/not_defined.html: <!--#fsize virtual="/misc/not_defined.html"-->
+
+<P><HR>
+
+<!-- ************* FLASTMOD ************* -->
+
+<P>Last modification of index.html: <!--#flastmod file="index.html"-->
+<P>Last modification of not_defined.html: <!--#flastmod file="not_defined.html"-->
+<P>Last modification of /misc/friedrich.html: <!--#flastmod virtual="/misc/friedrich.html"-->
+<P>Last modification of /misc/not_defined.html: <!--#flastmod virtual="/misc/not_defined.html"-->
+
+<!--#exec cmd="ls"-->
+<!--#exec cmd="printenv"-->
+<!--#exec cmd="sunemaja"-->
+
+<!--#exec cgi="/cgi-bin/printenv.sh"-->
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html
new file mode 100644
index 0000000000..34db3d5d1a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/echo.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/echo.shtml
new file mode 100644
index 0000000000..141db5be59
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/echo.shtml
@@ -0,0 +1,35 @@
+<HTML>
+<HEAD>
+<TITLE>/echo.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/echo.shtml</H1>
+
+<P>DOCUMENT_NAME: <!--#echo var="DOCUMENT_NAME"-->
+
+<P>DOCUMENT_URI: <!--#echo var="DOCUMENT_URI"-->
+
+<P>QUERY_STRING_UNESCAPED: <!--#echo var="QUERY_STRING_UNESCAPED"-->
+
+<P>DATE_LOCAL: <!--#echo var="DATE_LOCAL"-->
+
+<P>DATE_GMT: <!--#echo var="DATE_GMT"-->
+
+<P>LAST_MODIFIED: <!--#echo var="LAST_MODIFIED"-->
+
+<P>NOT_DEFINED: <!--#echo var="NOT_DEFINED"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/exec.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/exec.shtml
new file mode 100644
index 0000000000..97333da898
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/exec.shtml
@@ -0,0 +1,30 @@
+<HTML>
+<HEAD>
+<TITLE>/exec.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/exec.shtml</H1>
+<PRE>
+<!--#exec cmd="ls"-->
+<HR>
+<!--#exec cmd="printenv"-->
+<HR>
+<!--#exec cmd="sunemaja"-->
+<HR>
+<!--#exec cgi="/cgi-bin/printenv.sh"-->
+</PRE>
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/flastmod.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/flastmod.shtml
new file mode 100644
index 0000000000..d54c36fe50
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/flastmod.shtml
@@ -0,0 +1,29 @@
+<HTML>
+<HEAD>
+<TITLE>/flastmod.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/flastmod.shtml</H1>
+
+<P>Last modification of index.html: <!--#flastmod file="index.html"-->
+
+<P>Last modification of not_defined.html: <!--#flastmod file="not_defined.html"-->
+
+<P>Last modification of /misc/friedrich.html: <!--#flastmod virtual="/misc/friedrich.html"-->
+
+<P>Last modification of /misc/not_defined.html: <!--#flastmod virtual="/misc/not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/fsize.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/fsize.shtml
new file mode 100644
index 0000000000..570ee9cf6d
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/fsize.shtml
@@ -0,0 +1,29 @@
+<HTML>
+<HEAD>
+<TITLE>/fsize.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/fsize.shtml</H1>
+
+<P>Size of index.html: <!--#fsize file="index.html"-->
+
+<P>Size of not_defined.html: <!--#fsize file="not_defined.html"-->
+
+<P>Size of /misc/friedrich.html: <!--#fsize virtual="/misc/friedrich.html"-->
+
+<P>Size of /misc/not_defined.html: <!--#fsize virtual="/misc/not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/include.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/include.shtml
new file mode 100644
index 0000000000..529aad0437
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/include.shtml
@@ -0,0 +1,33 @@
+<HTML>
+<HEAD>
+<TITLE>/include.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/include.shtml</H1>
+
+<P>Include /misc/friedrich.html:
+<!--#include virtual="/misc/friedrich.html"-->
+
+<P>Include /misc/not_defined.html:
+<!--#include virtual="/misc/not_defined.html"-->
+
+<P>Include misc/friedrich.html:
+<!--#include file="misc/friedrich.html"-->
+
+<P>Include not_defined.html:
+<!--#include file="not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/index.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/index.html
new file mode 100644
index 0000000000..cfdc9f9ab7
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/index.html
@@ -0,0 +1,25 @@
+<HTML>
+<HEAD>
+<TITLE>/index.html</TITLE>
+</HEAD>
+<BODY>
+<H1>/index.html</H1>
+
+<STRONG>Server-Side Include (SSI) commands:</STRONG><BR>
+<A HREF="config.shtml">config</A><BR>
+<A HREF="echo.shtml">echo</A><BR>
+<A HREF="exec.shtml">exec</A><BR>
+<A HREF="flastmod.shtml">flastmod</A><BR>
+<A HREF="fsize.shtml">fsize</A><BR>
+<A HREF="include.shtml">include</A><BR>
+
+<BR>
+<BR>
+
+<STRONG>ESI callback:</STRING><BR>
+<A HREF="cgi-bin/erl/httpd_example/get">cgi-bin/erl/httpd_example/get</A><BR>
+<A HREF="cgi-bin/erl/httpd_example/yahoo">cgi-bin/erl/httpd_example/yahoo</A><BR>
+<A HREF="cgi-bin/erl/httpd_example/test1">cgi-bin/erl/httpd_example/test1</A><BR>
+
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/last_modified.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/last_modified.html
new file mode 100644
index 0000000000..65c1790813
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/last_modified.html
@@ -0,0 +1,22 @@
+<HTML>
+<HEAD>
+<TITLE>/last_modified.html</TITLE>
+</HEAD>
+<BODY>
+<H1>/last_modified.html</H1>
+
+<P>This document is only used for test of illegal last-modified date.</P>
+
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/friedrich.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/friedrich.html
new file mode 100644
index 0000000000..d7953d5df4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/friedrich.html
@@ -0,0 +1,7 @@
+<P><CITE>
+Talking much about oneself can also be a means to conceal oneself.<BR>
+-- Friedrich Nietzsche
+</CITE>
+
+<P>Nested Include:
+<!--#include file="misc/oech.html"-->
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/oech.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/oech.html
new file mode 100644
index 0000000000..506064bf04
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/oech.html
@@ -0,0 +1,4 @@
+<P><CITE>
+What excuses stand in your way? How can you eliminate them?<BR>
+-- Roger von Oech
+</CITE>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/welcome.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/welcome.html
new file mode 100644
index 0000000000..8c17451f91
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/welcome.html
@@ -0,0 +1 @@
+<HTML></HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html
new file mode 100644
index 0000000000..2d17e8b596
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/mnesia_secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/mnesia_secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/open/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html
new file mode 100644
index 0000000000..34db3d5d1a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/README b/lib/inets/test/httpd_SUITE_data/server_root/icons/README
new file mode 100644
index 0000000000..a1fc5a5a9c
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/README
@@ -0,0 +1,161 @@
+Public Domain Icons
+
+ These icons were originally made for Mosaic for X and have been
+ included in the NCSA httpd and Apache server distributions in the
+ past. They are in the public domain and may be freely included in any
+ application. The originals were done by Kevin Hughes ([email protected]).
+
+ Many thanks to Andy Polyakov for tuning the icon colors and adding a
+ few new images. If you'd like to contribute additions or ideas to
+ this set, please let me know.
+
+ The distribution site for these icons is at:
+
+ http://www.eit.com/goodies/www.icons/
+
+ Kevin Hughes
+ September 11, 1995
+
+
+Suggested Uses
+
+The following are a few suggestions, to serve as a starting point for ideas.
+Please feel free to tweak and rename the icons as you like.
+
+ a.gif
+ This might be used to represent PostScript or text layout
+ languages.
+
+ alert.black.gif, alert.red.gif
+ These can be used to highlight any important items, such as a
+ README file in a directory.
+
+ back.gif, forward.gif
+ These can be used as links to go to previous and next areas.
+
+ ball.gray.gif, ball.red.gif
+ These might be used as bullets.
+
+ binary.gif
+ This can be used to represent binary files.
+
+ binhex.gif
+ This can represent BinHex-encoded data.
+
+ blank.gif
+ This can be used as a placeholder or a spacing element.
+
+ bomb.gif
+ This can be used to repreesnt core files.
+
+ box1.gif, box2.gif
+ These icons can be used to represent generic 3D applications and
+ related files.
+
+ broken.gif
+ This can represent corrupted data.
+
+ burst.gif
+ This can call attention to new and important items.
+
+ c.gif
+ This might represent C source code.
+
+ comp.blue.gif, comp.red.gif
+ These little computer icons can stand for telnet or FTP
+ sessions.
+
+ compressed.gif
+ This may represent compressed data.
+
+ continued.gif
+ This can be a link to a continued listing of a directory.
+
+ down.gif, up.gif, left.gif, right.gif
+ These can be used to scroll up, down, left and right in a
+ listing or may be used to denote items in an outline.
+
+ dvi.gif
+ This can represent DVI files.
+
+ f.gif
+ This might represent FORTRAN or Forth source code.
+
+ folder.gif, folder.open.gif, folder.sec.gif
+ The folder can represent directories. There is also a version
+ that can represent secure directories or directories that cannot
+ be viewed.
+
+ generic.gif, generic.sec.gif, generic.red.gif
+ These can represent generic files, secure files, and important
+ files, respectively.
+
+ hand.right.gif, hand.up.gif
+ These can point out important items (pun intended).
+
+ image1.gif, image2.gif, image3.gif
+ These can represent image formats of various types.
+
+ index.gif
+ This might represent a WAIS index or search facility.
+
+ layout.gif
+ This might represent files and formats that contain graphics as
+ well as text layout, such as HTML and PDF files.
+
+ link.gif
+ This might represent files that are symbolic links.
+
+ movie.gif
+ This can represent various movie formats.
+
+ p.gif
+ This may stand for Perl or Python source code.
+
+ pie0.gif ... pie8.gif
+ These icons can be used in applications where a list of
+ documents is returned from a search. The little pie chart images
+ can denote how relevant the documents may be to your search
+ query.
+
+ patch.gif
+ This may stand for patches and diff files.
+
+ portal.gif
+ This might be a link to an online service or a 3D world.
+
+ ps.gif, quill.gif
+ These may represent PostScript files.
+
+ screw1.gif, screw2.gif
+ These may represent CAD or engineering data and formats.
+
+ script.gif
+ This can represent any of various interpreted languages, such as
+ Perl, python, TCL, and shell scripts, as well as server
+ configuration files.
+
+ sound1.gif, sound2.gif
+ These can represent sound files.
+
+ sphere1.gif, sphere2.gif
+ These can represent 3D worlds or rendering applications and
+ formats.
+
+ tex.gif
+ This can represent TeX files.
+
+ text.gif
+ This can represent generic (plain) text files.
+
+ transfer.gif
+ This can represent FTP transfers or uploads/downloads.
+
+ unknown.gif
+ This may represent a file of an unknown type.
+
+ uuencoded.gif
+ This can stand for uuencoded data.
+
+ world1.gif, world2.gif
+ These can represent 3D worlds or other 3D formats.
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/a.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/a.gif
new file mode 100644
index 0000000000..bb23d971f4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/a.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.black.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.black.gif
new file mode 100644
index 0000000000..eaecd2172a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.black.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.red.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.red.gif
new file mode 100644
index 0000000000..a423894043
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/apache_pb.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/apache_pb.gif
new file mode 100644
index 0000000000..3a1c139fc4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/apache_pb.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/back.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/back.gif
new file mode 100644
index 0000000000..a694ae1ec3
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/back.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.gray.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.gray.gif
new file mode 100644
index 0000000000..eb84268c4c
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.gray.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.red.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.red.gif
new file mode 100644
index 0000000000..a8425cb574
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/binary.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/binary.gif
new file mode 100644
index 0000000000..9a15cbae04
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/binary.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/binhex.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/binhex.gif
new file mode 100644
index 0000000000..62d0363108
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/binhex.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/blank.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/blank.gif
new file mode 100644
index 0000000000..0ccf01e198
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/blank.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/bomb.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/bomb.gif
new file mode 100644
index 0000000000..270fdb1c06
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/bomb.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/box1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/box1.gif
new file mode 100644
index 0000000000..65dcd002ea
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/box1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/box2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/box2.gif
new file mode 100644
index 0000000000..c43bc4faec
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/box2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/broken.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/broken.gif
new file mode 100644
index 0000000000..9f8cbe9f76
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/broken.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/burst.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/burst.gif
new file mode 100644
index 0000000000..fbdcf575f7
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/burst.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button1.gif
new file mode 100644
index 0000000000..eb97cb7333
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button10.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button10.gif
new file mode 100644
index 0000000000..fe0c97998c
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button10.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button2.gif
new file mode 100644
index 0000000000..7698455bf9
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button3.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button3.gif
new file mode 100644
index 0000000000..a8b8319232
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button4.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button4.gif
new file mode 100644
index 0000000000..0fd15a0d7f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button4.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button5.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button5.gif
new file mode 100644
index 0000000000..64241e5c5d
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button5.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button6.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button6.gif
new file mode 100644
index 0000000000..867cfd1212
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button6.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button7.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button7.gif
new file mode 100644
index 0000000000..b3f5fb248f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button7.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button8.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button8.gif
new file mode 100644
index 0000000000..7a308be8f6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button8.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button9.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button9.gif
new file mode 100644
index 0000000000..9acba576c0
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button9.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonl.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonl.gif
new file mode 100644
index 0000000000..3883088e7a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonl.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonr.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonr.gif
new file mode 100644
index 0000000000..c4dc3887db
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonr.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/c.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/c.gif
new file mode 100644
index 0000000000..7555b6c164
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/c.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.blue.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.blue.gif
new file mode 100644
index 0000000000..f8d76a8c23
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.blue.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.gray.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.gray.gif
new file mode 100644
index 0000000000..7664cd0364
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.gray.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/compressed.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/compressed.gif
new file mode 100644
index 0000000000..39e732739f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/compressed.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/continued.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/continued.gif
new file mode 100644
index 0000000000..b0ffb7e0cc
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/continued.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/dir.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/dir.gif
new file mode 100644
index 0000000000..48264601ae
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/dir.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/down.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/down.gif
new file mode 100644
index 0000000000..a354c871cd
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/down.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/dvi.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/dvi.gif
new file mode 100644
index 0000000000..791be33105
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/dvi.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/f.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/f.gif
new file mode 100644
index 0000000000..fbe353c282
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/f.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.gif
new file mode 100644
index 0000000000..48264601ae
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.open.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.open.gif
new file mode 100644
index 0000000000..30979cb528
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.open.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.sec.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.sec.gif
new file mode 100644
index 0000000000..75332d9e59
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.sec.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/forward.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/forward.gif
new file mode 100644
index 0000000000..b2959b4c85
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/forward.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.gif
new file mode 100644
index 0000000000..de60b2940f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.red.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.red.gif
new file mode 100644
index 0000000000..94743981d9
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.sec.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.sec.gif
new file mode 100644
index 0000000000..88d5240c3c
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.sec.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.right.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.right.gif
new file mode 100644
index 0000000000..5cdbc7206d
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.right.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.up.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.up.gif
new file mode 100644
index 0000000000..85a5d68317
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.up.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/htdig.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/htdig.gif
new file mode 100644
index 0000000000..35443fb63a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/htdig.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/icon.sheet.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/icon.sheet.gif
new file mode 100644
index 0000000000..ad1686e448
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/icon.sheet.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/image1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/image1.gif
new file mode 100644
index 0000000000..01e442bfa9
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/image1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/image2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/image2.gif
new file mode 100644
index 0000000000..751faeea36
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/image2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/image3.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/image3.gif
new file mode 100644
index 0000000000..4f30484ff6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/image3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/index.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/index.gif
new file mode 100644
index 0000000000..162478fb3a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/index.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/layout.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/layout.gif
new file mode 100644
index 0000000000..c96338a152
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/layout.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/left.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/left.gif
new file mode 100644
index 0000000000..279e6710d4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/left.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/link.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/link.gif
new file mode 100644
index 0000000000..c5b6889a76
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/link.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/movie.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/movie.gif
new file mode 100644
index 0000000000..0035183774
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/movie.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/p.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/p.gif
new file mode 100644
index 0000000000..7b917b4e91
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/p.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/patch.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/patch.gif
new file mode 100644
index 0000000000..39bc90e795
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/patch.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pdf.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pdf.gif
new file mode 100644
index 0000000000..c88fd777c4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pdf.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie0.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie0.gif
new file mode 100644
index 0000000000..6f7a0ae7a7
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie0.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie1.gif
new file mode 100644
index 0000000000..03aa6be71e
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie2.gif
new file mode 100644
index 0000000000..b04c5e0908
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie3.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie3.gif
new file mode 100644
index 0000000000..4db9d023ed
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie4.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie4.gif
new file mode 100644
index 0000000000..93471fdd88
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie4.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie5.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie5.gif
new file mode 100644
index 0000000000..57aee93f07
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie5.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie6.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie6.gif
new file mode 100644
index 0000000000..0dc327b569
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie6.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie7.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie7.gif
new file mode 100644
index 0000000000..8661337f06
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie7.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie8.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie8.gif
new file mode 100644
index 0000000000..59ddb34ce0
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie8.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/portal.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/portal.gif
new file mode 100644
index 0000000000..0e6e506e00
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/portal.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/poweredby.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/poweredby.gif
new file mode 100644
index 0000000000..d324ab80ea
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/poweredby.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/ps.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/ps.gif
new file mode 100644
index 0000000000..0f565bc1db
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/ps.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/quill.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/quill.gif
new file mode 100644
index 0000000000..818a5cdc7e
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/quill.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/right.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/right.gif
new file mode 100644
index 0000000000..b256e5f75f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/right.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/screw1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/screw1.gif
new file mode 100644
index 0000000000..af6ba2b097
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/screw1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/screw2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/screw2.gif
new file mode 100644
index 0000000000..06dccb3e44
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/screw2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/script.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/script.gif
new file mode 100644
index 0000000000..d8a853bc58
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/script.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/sound1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/sound1.gif
new file mode 100644
index 0000000000..8efb49f55d
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/sound1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/sound2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/sound2.gif
new file mode 100644
index 0000000000..48e6a7fb2f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/sound2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere1.gif
new file mode 100644
index 0000000000..7067070da2
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere2.gif
new file mode 100644
index 0000000000..a9e462a377
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/star.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/star.gif
new file mode 100644
index 0000000000..4cfe0a5e0f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/star.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/star_blank.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/star_blank.gif
new file mode 100644
index 0000000000..a0c83cb85b
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/star_blank.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/tar.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/tar.gif
new file mode 100644
index 0000000000..617e779efa
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/tar.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/tex.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/tex.gif
new file mode 100644
index 0000000000..45e43233b8
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/tex.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/text.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/text.gif
new file mode 100644
index 0000000000..4c623909fb
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/text.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/transfer.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/transfer.gif
new file mode 100644
index 0000000000..33697dbb66
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/transfer.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/unknown.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/unknown.gif
new file mode 100644
index 0000000000..32b1ea23fb
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/unknown.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/up.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/up.gif
new file mode 100644
index 0000000000..6d6d6d1ebf
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/up.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/uu.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/uu.gif
new file mode 100644
index 0000000000..4387d529f6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/uu.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/uuencoded.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/uuencoded.gif
new file mode 100644
index 0000000000..4387d529f6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/uuencoded.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/world1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/world1.gif
new file mode 100644
index 0000000000..05b4ec2058
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/world1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/world2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/world2.gif
new file mode 100644
index 0000000000..e3203f7a88
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/world2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip b/lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip
new file mode 100644
index 0000000000..8d1c8b69c3
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip
@@ -0,0 +1 @@
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem
new file mode 100644
index 0000000000..8221139eb4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAL6Ym/bgUvhhnPkw08sggGg8Tnp759ThGMEjkmDzhuJ3w3PfnF65
+mgHcgunku4G6LxAQfEUougJWf9Phmjj3oRUCAwEAAQJBAKMjvVvzZxFzfAlP4flc
+OI0AEayFokp04dtvtzuFN09f+aBo2dP18xHmKLCZvxrBOaRAROoQYscALiIVpN07
+GAECIQDfi+sSfAFaDlT3vzpL3xE5UEH6IzY8jWpaZfM1QaToJQIhANpEF50H4wGO
+8Sbh7dUutNd+s+NYUjsMySW2DjLKMsoxAiEAzzb2ftrdsempD0F+O0gZwiPIFKLB
+Kp33YLYyHEKuJtUCIDGi+pvDh2R7VWw6RRQOIyI+tjolg83aAoSI+oGiahqBAiEA
+xzmNNajwoaokvWvlaz0na8rhxu45grOvDrflBT9XvSQ=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD
+VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w
+DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG
+9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzNDM2WhcN
+MDMwMjIyMTUzNDM2WjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s
+bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ
+MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA
+ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC+mJv24FL4
+YZz5MNPLIIBoPE56e+fU4RjBI5Jg84bid8Nz35xeuZoB3ILp5LuBui8QEHxFKLoC
+Vn/T4Zo496EVAgMBAAEwDQYJKoZIhvcNAQEEBQADQQBYxQVfTydyZCE0UXvZd7Ei
+josNsAaWJk9fFIJaG9uyXCEfg2dVgoT2eBk3D9DI+7OB+78isM5CVlFbL7hilvP8
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem
new file mode 100644
index 0000000000..fe739c15f7
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBAL9Bozj3BIjL5Cy8b3rjMT2kPZRychX4wz9bHoIIiKnKo1xXHYjw
+g3N9zWM1f1ZzMADwVry1uAInA8q09+7hL20CAwEAAQJACwu2ao7RozjrV64WXimK
+6X131P/7GMvCMwGHNIlbozqoOqmZcYrbKaF61l+XuwA2QvTo3ywW1Ivxcyr6TeAr
+PQIhAOX+WXT6yiqqwjt08kjBCJyMgfZtdAO6pc/6pKjNWiZfAiEA1OH1iPW/OQe5
+tlQXpiRVdLyneNsPygPRJc4Bdwu3hbMCIQDbI5pA56QxOzqOREOGJsb5wrciAfAE
+jZbnr72sSN2YqQIgAWFpvzagw9Tp/mWzNY+cwkIK7/yzsIKv04fveH8p9IMCIQCr
+td4IiukeUwXmPSvYM4uCE/+J89wEL9qU8Mlc3gDLXA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD
+VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w
+DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG
+9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzMzQxWhcN
+MDMwMjIyMTUzMzQxWjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s
+bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ
+MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA
+ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC/QaM49wSI
+y+QsvG964zE9pD2UcnIV+MM/Wx6CCIipyqNcVx2I8INzfc1jNX9WczAA8Fa8tbgC
+JwPKtPfu4S9tAgMBAAEwDQYJKoZIhvcNAQEEBQADQQAmXDY1CyJjzvQZX442kkHG
+ic9QFY1UuVfzokzNMwlHYl1Qx9zaodx0cJCrcH5GF9O9LJbhhV77LzoxT1Q5wZp5
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpd_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl
new file mode 100644
index 0000000000..f86c1fcb49
--- /dev/null
+++ b/lib/inets/test/httpd_basic_SUITE.erl
@@ -0,0 +1,136 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(httpd_basic_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+all(doc) ->
+ ["Basic test of httpd."];
+
+all(suite) ->
+ [
+ uri_too_long_414,
+ header_too_long_413
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ ok = inets:start(),
+ PrivDir = ?config(priv_dir, Config),
+ HttpdConf = [{port, 0}, {ipfamily, inet},
+ {server_name, "httpd_test"}, {server_root, PrivDir},
+ {document_root, PrivDir}, {bind_address, "localhost"}],
+ [{httpd_conf, HttpdConf} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ inets:stop(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, Config) -> Config
+% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(_, Config) ->
+ Config.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+uri_too_long_414(doc) ->
+ ["Test that too long uri's get 414 HTTP code"];
+uri_too_long_414(suite) ->
+ [];
+uri_too_long_414(Config) when is_list(Config) ->
+ HttpdConf = ?config(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0}, {max_uri_size, 10}
+ | HttpdConf]),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ Address = proplists:get_value(bind_address, Info),
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ "GET /morethantenchars "
+ "HTTP/1.1\r\n\r\n",
+ [{statuscode, 414},
+ %% Server will send lowest version
+ %% as it will not get to the
+ %% client version
+ %% before aborting
+ {version, "HTTP/0.9"}]),
+ inets:stop(httpd, Pid).
+
+header_too_long_413(doc) ->
+ ["Test that too long headers's get 413 HTTP code"];
+header_too_long_413(suite) ->
+ [];
+header_too_long_413(Config) when is_list(Config) ->
+ HttpdConf = ?config(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0}, {max_header_size, 10}
+ | HttpdConf]),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ Address = proplists:get_value(bind_address, Info),
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ "GET index.html "
+ "HTTP/1.1\r\n"
+ "Connection:close \r\n\r\n ",
+ [{statuscode, 413},
+ {version, "HTTP/1.1"}]),
+ inets:stop(httpd, Pid).
+
+
+
+
diff --git a/lib/inets/test/httpd_block.erl b/lib/inets/test/httpd_block.erl
new file mode 100644
index 0000000000..f967d8172a
--- /dev/null
+++ b/lib/inets/test/httpd_block.erl
@@ -0,0 +1,299 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(httpd_block).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% General testcases bodies called from httpd_SUITE
+-export([block_disturbing_idle/4, block_non_disturbing_idle/4,
+ block_503/4, block_disturbing_active/4,
+ block_non_disturbing_active/4,
+ block_disturbing_active_timeout_not_released/4,
+ block_disturbing_active_timeout_released/4,
+ block_non_disturbing_active_timeout_not_released/4,
+ block_non_disturbing_active_timeout_released/4,
+ disturbing_blocker_dies/4,
+ non_disturbing_blocker_dies/4, restart_no_block/4,
+ restart_disturbing_block/4, restart_non_disturbing_block/4
+ ]).
+
+%% Help functions
+-export([do_block_server/4, do_block_nd_server/5, do_long_poll/6]).
+
+-define(report(Label, Content),
+ inets:report_event(20, Label, test_case,
+ [{module, ?MODULE}, {line, ?LINE} | Content])).
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+block_disturbing_idle(_Type, Port, Host, Node) ->
+ unblocked = get_admin_state(Node, Host, Port),
+ block_server(Node, Host, Port),
+ blocked = get_admin_state(Node, Host, Port),
+ unblock_server(Node, Host, Port),
+ unblocked = get_admin_state(Node, Host, Port).
+%%--------------------------------------------------------------------
+block_non_disturbing_idle(_Type, Port, Host, Node) ->
+ unblocked = get_admin_state(Node, Host, Port),
+ block_nd_server(Node, Host, Port),
+ blocked = get_admin_state(Node, Host, Port),
+ unblock_server(Node, Host, Port),
+ unblocked = get_admin_state(Node, Host, Port).
+%%--------------------------------------------------------------------
+block_503(Type, Port, Host, Node) ->
+ Req = "GET / HTTP/1.0\r\ndummy-host.ericsson.se:\r\n\r\n",
+ unblocked = get_admin_state(Node, Host, Port),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, Req,
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = block_server(Node, Host, Port),
+ blocked = get_admin_state(Node, Host, Port),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, Req,
+ [{statuscode, 503},
+ {version, "HTTP/1.0"}]),
+ ok = unblock_server(Node, Host, Port),
+ unblocked = get_admin_state(Node, Host, Port),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, Req,
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]).
+%%--------------------------------------------------------------------
+block_disturbing_active(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Pid = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(15000),
+ block_server(Node, Host, Port),
+ await_suite_failed_process_exit(Pid, "poller", 60000,
+ connection_closed),
+ blocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+block_non_disturbing_active(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(15000),
+ ok = block_nd_server(Node, Host, Port),
+ await_normal_process_exit(Poller, "poller", 60000),
+ blocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+block_disturbing_active_timeout_not_released(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(15000),
+ Blocker = blocker(Node, Host, Port, 50000),
+ await_normal_process_exit(Blocker, "blocker", 50000),
+ await_normal_process_exit(Poller, "poller", 30000),
+ blocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+block_disturbing_active_timeout_released(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 40000),
+ test_server:sleep(5000),
+ Blocker = blocker(Node, Host, Port, 10000),
+ await_normal_process_exit(Blocker, "blocker", 15000),
+ await_suite_failed_process_exit(Poller, "poller", 40000,
+ connection_closed),
+ blocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+block_non_disturbing_active_timeout_not_released(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(5000),
+ ok = block_nd_server(Node, Host, Port, 40000),
+ await_normal_process_exit(Poller, "poller", 60000),
+ blocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+block_non_disturbing_active_timeout_released(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 45000),
+ test_server:sleep(5000),
+ Blocker = blocker_nd(Node, Host, Port ,10000, {error,timeout}),
+ await_normal_process_exit(Blocker, "blocker", 15000),
+ await_normal_process_exit(Poller, "poller", 50000),
+ unblocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+disturbing_blocker_dies(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(5000),
+ Blocker = blocker(Node, Host, Port, 10000),
+ test_server:sleep(5000),
+ exit(Blocker,simulate_blocker_crash),
+ await_normal_process_exit(Poller, "poller", 60000),
+ unblocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+non_disturbing_blocker_dies(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(5000),
+ Blocker = blocker_nd(Node, Host, Port, 10000, ok),
+ test_server:sleep(5000),
+ exit(Blocker, simulate_blocker_crash),
+ await_normal_process_exit(Poller, "poller", 60000),
+ unblocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+restart_no_block(_, Port, Host, Node) ->
+ {error,_Reason} = restart_server(Node, Host, Port).
+
+%%--------------------------------------------------------------------
+restart_disturbing_block(_, Port, Host, Node) ->
+ ?report("restart_disturbing_block - get_admin_state (unblocked)", []),
+ unblocked = get_admin_state(Node, Host, Port),
+ ?report("restart_disturbing_block - block_server", []),
+ ok = block_server(Node, Host, Port),
+ ?report("restart_disturbing_block - restart_server", []),
+ ok = restart_server(Node, Host, Port),
+ ?report("restart_disturbing_block - unblock_server", []),
+ ok = unblock_server(Node, Host, Port),
+ ?report("restart_disturbing_block - get_admin_state (unblocked)", []),
+ unblocked = get_admin_state(Node, Host, Port).
+
+%%--------------------------------------------------------------------
+restart_non_disturbing_block(_, Port, Host, Node) ->
+ ?report("restart_non_disturbing_block - get_admin_state (unblocked)", []),
+ unblocked = get_admin_state(Node, Host, Port),
+ ?report("restart_non_disturbing_block - block_nd_server", []),
+ ok = block_nd_server(Node, Host, Port),
+ ?report("restart_non_disturbing_block - restart_server", []),
+ ok = restart_server(Node, Host, Port),
+ ?report("restart_non_disturbing_block - unblock_server", []),
+ ok = unblock_server(Node, Host, Port),
+ ?report("restart_non_disturbing_block - get_admin_state (unblocked)", []),
+ unblocked = get_admin_state(Node, Host, Port).
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+blocker(Node, Host, Port, Timeout) ->
+ spawn_link(?MODULE, do_block_server,[Node, Host, Port,Timeout]).
+
+do_block_server(Node, Host, Port, Timeout) ->
+ ok = block_server(Node, Host, Port, Timeout),
+ exit(normal).
+
+blocker_nd(Node, Host, Port, Timeout, Reply) ->
+ spawn_link(?MODULE, do_block_nd_server,
+ [Node, Host, Port, Timeout, Reply]).
+
+do_block_nd_server(Node, Host, Port, Timeout, Reply) ->
+ Reply = block_nd_server(Node, Host, Port, Timeout),
+ exit(normal).
+
+restart_server(Node, _Host, Port) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, restart, [Addr, Port]).
+
+block_server(Node, _Host, Port) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, block, [Addr, Port]).
+
+block_server(Node, _Host, Port, Timeout) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, block, [Addr, Port, disturbing, Timeout]).
+
+block_nd_server(Node, _Host, Port) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, block, [Addr, Port, non_disturbing]).
+
+block_nd_server(Node, _Host, Port, Timeout) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, block, [Addr, Port, non_disturbing, Timeout]).
+
+unblock_server(Node, _Host, Port) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, unblock, [Addr, Port]).
+
+get_admin_state(Node,_Host,Port) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, get_admin_state, [Addr, Port]).
+
+await_normal_process_exit(Pid, Name, Timeout) ->
+ receive
+ {'EXIT', Pid, normal} ->
+ ok;
+ {'EXIT', Pid, Reason} ->
+ Err =
+ lists:flatten(
+ io_lib:format("expected normal exit, "
+ "unexpected exit of ~s process: ~p",
+ [Name, Reason])),
+ test_server:fail(Err)
+ after Timeout ->
+ test_server:fail("timeout while waiting for " ++ Name)
+ end.
+
+await_suite_failed_process_exit(Pid, Name, Timeout, Why) ->
+ receive
+ {'EXIT', Pid, {suite_failed, Why}} ->
+ ok;
+ {'EXIT', Pid, Reason} ->
+ Err =
+ lists:flatten(
+ io_lib:format("expected connection_closed, "
+ "unexpected exit of ~s process: ~p",
+ [Name, Reason])),
+ test_server:fail(Err)
+ after Timeout ->
+ test_server:fail("timeout while waiting for " ++ Name)
+ end.
+
+long_poll(Type, Host, Port, Node, StatusCode, Timeout) ->
+ spawn_link(?MODULE, do_long_poll, [Type, Host, Port, Node,
+ StatusCode, Timeout]).
+
+do_long_poll(Type, Host, Port, Node, StatusCode, Timeout) ->
+ Mod = "httpd_example",
+ Func = "delay",
+ Req = lists:flatten(io_lib:format("GET /eval?" ++ Mod ++ ":" ++ Func ++
+ "(~p) HTTP/1.0\r\n\r\n",[30000])),
+ case httpd_test_lib:verify_request(Type, Host, Port, Node, Req,
+ [{statuscode, StatusCode},
+ {version, "HTTP/1.0"}], Timeout) of
+ ok ->
+ exit(normal);
+ Reason ->
+ test_server:fail(Reason)
+ end.
+
+
+
+
+
diff --git a/lib/inets/test/httpd_load.erl b/lib/inets/test/httpd_load.erl
new file mode 100644
index 0000000000..9bb9f9f94e
--- /dev/null
+++ b/lib/inets/test/httpd_load.erl
@@ -0,0 +1,99 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(httpd_load).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% General testcases bodies called from httpd_SUITE
+-export([load_test/5]).
+
+%% Help functions
+-export([load_test_client/8]).
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+load_test(Type, Port, Host, Node, NofTesters) ->
+ URIs =
+ [
+ "/index.html",
+ "/echo.shtml",
+ "/",
+ "/flastmod.shtml",
+ "/misc/"
+ ],
+ Fun = fun(Mod, Host1, Port1, Node1, Req, Exp) ->
+ ok = httpd_test_lib:verify_request(Mod, Host1, Port1,
+ Node1, Req, Exp)
+ end,
+ load_test(Fun, URIs ++ URIs, Type, Host, Port, Node, NofTesters, []).
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+
+load_test(_, _, _, _, _, _, 0, []) ->
+ ok;
+load_test(Fun, URIs, Type, Host, Port, Node, 0, List) ->
+ receive
+ {Pid, done} ->
+ load_test(Fun, URIs, Type, Host, Port, Node, 0,
+ lists:delete(Pid, List));
+ {'EXIT', Pid, normal} ->
+ load_test(Fun, URIs, Type, Host, Port, Node, 0,
+ lists:delete(Pid, List));
+ {'EXIT', Pid, Reason} ->
+ Str = lists:flatten(io_lib:format("client ~p exited: ~p",
+ [Pid,Reason])),
+ test_server:fail(Str);
+ _ ->
+ load_test(Fun, URIs, Type, Host, Port, Node, 0, List)
+ end;
+
+load_test(Fun, URIs, Type, Host, Port, Node, X, List) ->
+ Pid = spawn_link(?MODULE, load_test_client,
+ [Fun, URIs, Type, Host, Port, Node, self(), 100]),
+ load_test(Fun, lists:reverse(URIs), Type, Host, Port, Node, X-1,
+ [Pid | List]).
+
+load_test_client(_Fun, [], _Type, _Host, _Port, _Node, Boss, _Timeout) ->
+ load_test_client_done(Boss);
+load_test_client(Fun, [URI|URIs], Type, Host, Port, Node, Boss, Timeout) ->
+ Req = "GET "++URI++" HTTP/1.0\r\nConnection: Close\r\n"
+ "From: m@erix\r\nReferer: http://www.ericsson.se/\r\n\r\n",
+ Timeout1 =
+ case (catch Fun(Type, Host, Port, Node, Req,
+ [{statuscode, 200}, {statuscode, 500},
+ {statuscode, 503}, {version, "HTTP/1.0"}])) of
+ {'EXIT', {suite_failed, connection_closed, _, _}} ->
+ %% Some platforms seems to handle heavy load badly.
+ %% So, back off and see if this helps
+ %%?LOG("load_test_client->requestfailed:connection_closed"[]),
+ 2 * Timeout;
+ _ ->
+ Timeout
+ end,
+ test_server:sleep(Timeout1),
+ load_test_client(Fun, URIs, Type, Host, Port, Node, Boss, Timeout1).
+
+load_test_client_done(Boss) ->
+ Boss ! {self(), done}.
+
diff --git a/lib/inets/test/httpd_mod.erl b/lib/inets/test/httpd_mod.erl
new file mode 100644
index 0000000000..b03f842e7c
--- /dev/null
+++ b/lib/inets/test/httpd_mod.erl
@@ -0,0 +1,947 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(httpd_mod).
+-author('[email protected]').
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% General testcases bodies called from httpd_SUITE
+-export([alias/4, actions/4, security/5, auth/4, auth_api/6,
+ auth_mnesia_api/4, htaccess/4,
+ cgi/4, esi/4, get/4, head/4, all/4]).
+
+%% Help functions
+-export([event/4, ssl_password_cb/0]).
+
+%% Seconds before successful auths timeout.
+-define(AUTH_TIMEOUT,5).
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+alias(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /pics/icon.sheet.gif "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type","image/gif"},
+ {header, "Server"},
+ {header, "Date"},
+ {version, "HTTP/1.0"}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type","text/html"},
+ {header, "Server"},
+ {header, "Date"},
+ {version, "HTTP/1.0"}]),
+
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET /misc/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type","text/html"},
+ {header, "Server"},
+ {header, "Date"},
+ {version, "HTTP/1.0"}]),
+
+ %% Check redirection if trailing slash is missing.
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET /misc HTTP/1.0\r\n\r\n",
+ [{statuscode, 301},
+ {header, "Location"},
+ {header, "Content-Type","text/html"},
+ {version, "HTTP/1.0"}]).
+
+%%-------------------------------------------------------------------------
+actions(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD / HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]).
+
+%%-------------------------------------------------------------------------
+security(ServerRoot, Type, Port, Host, Node) ->
+ io:format(user, "~w:security -> entry with"
+ "~n ServerRoot: ~p"
+ "~n Type: ~p"
+ "~n Port: ~p"
+ "~n Host: ~p"
+ "~n Node: ~p"
+ "~n", [?MODULE, ServerRoot, Type, Port, Host, Node]),
+
+ global:register_name(mod_security_test, self()), % Receive events
+
+ test_server:sleep(5000),
+
+ OpenDir = filename:join([ServerRoot, "htdocs", "open"]),
+
+ %% Test blocking / unblocking of users.
+
+ %% /open, require user one Aladdin
+ remove_users(Node, ServerRoot, Host, Port, "open"),
+
+ auth_request(Type, Host, Port, Node, "/open/", "one", "onePassword",
+ [{statuscode, 401}]),
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "one"}, {password, "onePassword"}]},
+ Node, Port),
+
+ auth_request(Type,Host,Port,Node,"/open/", "two", "twoPassword",
+ [{statuscode, 401}]),
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "two"}, {password, "twoPassword"}]},
+ Node, Port),
+
+ auth_request(Type, Host, Port, Node,"/open/", "Aladdin",
+ "AladdinPassword", [{statuscode, 401}]),
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "Aladdin"},
+ {password, "AladdinPassword"}]},
+ Node, Port),
+
+ add_user(Node, ServerRoot, Port, "open", "one", "onePassword", []),
+ add_user(Node, ServerRoot, Port, "open", "two", "twoPassword", []),
+
+ auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword",
+ [{statuscode, 401}]),
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "one"}, {password, "WrongPassword"}]},
+ Node, Port),
+
+ auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword",
+ [{statuscode, 401}]),
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "one"}, {password, "WrongPassword"}]},
+ Node, Port),
+
+ receive_security_event({event, user_block, Port, OpenDir,
+ [{user, "one"}]}, Node, Port),
+
+ global:unregister_name(mod_security_test), % No more events.
+
+ auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword",
+ [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node,"/open/", "one", "onePassword",
+ [{statuscode, 403}]),
+
+ %% User "one" should be blocked now..
+ %% [{"one",_, Port, OpenDir,_}] = list_blocked_users(Node,Port),
+ case list_blocked_users(Node, Port) of
+ [{"one",_, Port, OpenDir,_}] ->
+ ok;
+ Blocked ->
+ io:format(user, "~w:security -> Blocked: ~p"
+ "~n", [?MODULE, Blocked]),
+ exit({unexpected_blocked, Blocked})
+ end,
+
+ [{"one",_, Port, OpenDir,_}] = list_blocked_users(Node,Port,OpenDir),
+
+ true = unblock_user(Node, "one", Port, OpenDir),
+ %% User "one" should not be blocked any more..
+ [] = list_blocked_users(Node, Port),
+ [] = list_blocked_users(Node, Port, OpenDir),
+ auth_request(Type, Host, Port, Node,"/open/", "one", "onePassword",
+ [{statuscode, 200}]),
+
+ %% Test list_auth_users & auth_timeout
+ ["one"] = list_auth_users(Node, Port),
+ ["one"] = list_auth_users(Node, Port, OpenDir),
+ auth_request(Type, Host, Port, Node,"/open/", "two", "onePassword",
+ [{statuscode, 401}]),
+ ["one"] = list_auth_users(Node, Port),
+ ["one"] = list_auth_users(Node, Port, OpenDir),
+ auth_request(Type, Host, Port, Node,"/open/", "two", "twoPassword",
+ [{statuscode, 401}]),
+ ["one"] = list_auth_users(Node, Port),
+ ["one"] = list_auth_users(Node, Port, OpenDir),
+ %% Wait for successful auth to timeout.
+ test_server:sleep(?AUTH_TIMEOUT*1001),
+ [] = list_auth_users(Node, Port),
+ [] = list_auth_users(Node, Port, OpenDir),
+ %% "two" is blocked.
+ true = unblock_user(Node, "two", Port, OpenDir),
+ %% Test explicit blocking. Block user 'two'.
+ [] = list_blocked_users(Node,Port,OpenDir),
+ true = block_user(Node, "two", Port, OpenDir, 10),
+ auth_request(Type, Host, Port, Node,"/open/", "two", "twoPassword",
+ [{statuscode, 401}]).
+
+%%-------------------------------------------------------------------------
+auth(Type, Port, Host, Node) ->
+ %% Authentication required!
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET /open/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET /secret/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET /secret/top_secret/"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+
+ %% Authentication OK! ["one:OnePassword" user first in user list]
+ auth_request(Type, Host, Port, Node, "/open/dummy.html", "one",
+ "onePassword", [{statuscode, 200}]),
+ %% Authentication OK and a directory listing is supplied!
+ %% ["Aladdin:open sesame" user second in user list]
+ auth_request(Type, Host, Port, Node, "/open/","Aladdin",
+ "AladdinPassword", [{statuscode, 200}]),
+
+ %% User correct but wrong password! ["one:one" user first in user list]
+ auth_request(Type, Host, Port, Node, "/open/", "one", "one",
+ [{statuscode, 401},{header, "WWW-Authenticate"}]),
+ %% Make sure Authenticate header is received even the second time
+ %% we try a incorrect password! Otherwise a browser client will hang!
+ auth_request(Type, Host, Port, Node, "/open/", "one", "one",
+ [{statuscode, 401},{header, "WWW-Authenticate"}]),
+
+ %% Neither user or password correct! ["dummy:dummy"]
+ auth_request(Type, Host, Port, Node, "/open/", "dummy", "dummy",
+ [{statuscode, 401}]),
+
+ %% Authentication OK! ["two:TwoPassword" user in first group]
+ auth_request(Type, Host, Port, Node, "/secret/dummy.html", "two",
+ "twoPassword", [{statuscode, 200}]),
+ %% Authentication OK and a directory listing is supplied!
+ %% ["three:ThreePassword" user in second group]
+ auth_request(Type, Host, Port, Node,"/secret/", "three",
+ "threePassword", [{statuscode, 200}]),
+
+ %% User correct but wrong password! ["two:two" user in first group]
+ auth_request(Type, Host, Port, Node, "/secret/", "two", "two",
+ [{statuscode, 401}]),
+ %% Neither user or password correct! ["dummy:dummy"]
+ auth_request(Type, Host, Port, Node,"/secret/", "dummy", "dummy",
+ [{statuscode, 401}]),
+
+ %% Nested secret/top_secret OK! ["Aladdin:open sesame"]
+ auth_request(Type, Host, Port, Node, "/secret/top_secret/", "Aladdin",
+ "AladdinPassword", [{statuscode, 200}]),
+ %% Authentication still required!
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /open/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /secret/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /secret/top_secret/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]).
+
+
+%%-------------------------------------------------------------------------
+%% What to test here:
+%%
+%% /open - plain, require user one Aladdin
+%% /secret - plain, require group group1 group2
+%% /secret/top_secret - plain, require group group3
+%% /dets_open - dets, require user one Aladdin
+%% /dets_secret - dets, require group group1 group2
+%% /dets_secret/top_secret - dets, require group group3
+%% /mnesia_open/ - mnesia, require user one Aladdin
+%% /mnesia_secret/ - mnesia, require group group1 group2
+%% /mnesia_secret/top_secret/ - mnesia, require group group3
+auth_api(ServerRoot, AuthStoreType, Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ auth_request(Type, Host, Port, Node, "/", "one", "WrongPassword",
+ [{statuscode, 200}]),
+
+ %% Make sure Authenticate header is received even the second time
+ %% we try a incorrect password! Otherwise a browser client will hang!
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "dummy", "WrongPassword", [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "dummy", "WrongPassword", [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
+
+ %% Change the password to DummyPassword then try to add a user
+ %% Get an error and set it to NoPassword
+ ok = update_password(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "open", "NoPassword", "DummyPassword"),
+ {error,bad_password} =
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "one",
+ "onePassword", []),
+ ok = update_password(Node, ServerRoot, Host, Port, AuthStoreType ++"open",
+ "DummyPassword", "NoPassword"),
+
+ %% Test /*open, require user one Aladdin
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++ "open"),
+
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "one", "onePassword", [{statuscode, 401}]),
+
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "two", "twoPassword", [{statuscode, 401}]),
+
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "Aladdin", "onePassword", [{statuscode, 401}]),
+
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "one",
+ "onePassword", []),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "two",
+ "twoPassword", []),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "Aladdin",
+ "AladdinPassword", []),
+
+ {ok, [_|_]} = list_users(Node, ServerRoot, Host, Port,
+ AuthStoreType++"open"),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "open/",
+ "one", "WrongPassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "open/",
+ "one", "onePassword", [{statuscode, 200}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "two", "twoPassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "open/",
+ "Aladdin", "WrongPassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "Aladdin", "AladdinPassword", [{statuscode, 200}]),
+
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType++"open"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port,
+ AuthStoreType++"open"),
+
+ %% Phase 2
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType++"secret"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "secret"),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "one", "onePassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "two", "twoPassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "secret/",
+ "three", "threePassword", [{statuscode, 401}]),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "secret", "one",
+ "onePassword",
+ []),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "secret",
+ "two", "twoPassword", []),
+ add_user(Node, ServerRoot, Port, AuthStoreType++"secret", "Aladdin",
+ "AladdinPassword",[]),
+ add_group_member(Node, ServerRoot, Port, AuthStoreType ++ "secret",
+ "one", "group1"),
+ add_group_member(Node, ServerRoot, Port, AuthStoreType ++ "secret",
+ "two", "group1"),
+ add_group_member(Node, ServerRoot, Port, AuthStoreType ++
+ "secret", "Aladdin", "group2"),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "one", "onePassword", [{statuscode, 200}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "two", "twoPassword", [{statuscode, 200}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "Aladdin", "AladdinPassword", [{statuscode, 200}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "three", "threePassword", [{statuscode, 401}]),
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++ "secret"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port,
+ AuthStoreType ++ "secret"),
+ remove_groups(Node, ServerRoot, Host, Port, AuthStoreType ++ "secret"),
+ Directory = filename:join([ServerRoot, "htdocs", AuthStoreType ++
+ "secret"]),
+ {ok, []} = list_groups(Node, ServerRoot, Host, Port, Directory),
+
+ %% Phase 3
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "secret/top_secret"),
+ remove_groups(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "secret/top_secret"),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++
+ "secret/top_secret/",
+ "three", "threePassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++
+ "secret/top_secret/", "two", "twoPassword",
+ [{statuscode, 401}]),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++
+ "secret/top_secret","three",
+ "threePassword",[]),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "secret/top_secret",
+ "two","twoPassword", []),
+ add_group_member(Node, ServerRoot, Port, AuthStoreType ++
+ "secret/top_secret",
+ "three", "group3"),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++
+ "secret/top_secret/", "three", "threePassword",
+ [{statuscode, 200}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++
+ "secret/top_secret/", "two", "twoPassword",
+ [{statuscode, 401}]),
+ add_group_member(Node, ServerRoot, Port, AuthStoreType ++
+ "secret/top_secret",
+ "two", "group3"),
+ auth_request(Type,Host,Port,Node,"/" ++ AuthStoreType ++
+ "secret/top_secret/",
+ "two", "twoPassword", [{statuscode, 200}]),
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "secret/top_secret"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port,
+ AuthStoreType ++ "secret/top_secret"),
+ remove_groups(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "secret/top_secret"),
+ Directory2 = filename:join([ServerRoot, "htdocs",
+ AuthStoreType ++ "secret/top_secret"]),
+ {ok, []} = list_groups(Node, ServerRoot, Host, Port, Directory2),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++
+ "secret/top_secret/", "two", "twoPassword",
+ [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++
+ "secret/top_secret/","three", "threePassword",
+ [{statuscode, 401}]).
+
+%%--------------------------------------------------------------------------
+auth_mnesia_api(_Type, Port, _Host, _Node) ->
+ %% Create three groups:
+ %% group1 : one Aladdin
+ %% group2 : two
+ %% group3 : three
+ mod_auth_mnesia:store_user("one", "onePassword", Port,
+ "/mnesia_open", ""),
+ mod_auth_mnesia:store_user("Aladdin", "AladdinPassword", Port,
+ "/mnesia_open", ""),
+ mod_auth_mnesia:store_user("two", "twoPassword", Port,
+ "/mnesia_open", ""),
+ mod_auth_mnesia:store_user("three", "threePassword", Port,
+ "/mnesia_open", ""),
+ Users = mod_auth_mnesia:list_users(Port, "/mnesia_open"),
+
+ ok = check_lists_members(Users,["Aladdin","one","two","three"]),
+
+ true = mod_auth_mnesia:store_group_member("group1", "one", Port,
+ "/mnesia_open", ""),
+ true = mod_auth_mnesia:store_group_member("group1","Aladdin", Port,
+ "/mnesia_open", ""),
+ true = mod_auth_mnesia:store_group_member("group2","two", Port,
+ "/mnesia_open", ""),
+ true = mod_auth_mnesia:store_group_member("group3","three", Port,
+ "/mnesia_open", ""),
+ %% Check that all three created groups exist.
+ Groups = mod_auth_mnesia:list_groups(Port, "/mnesia_open"),
+ ok = check_lists_members(Groups, ["group1","group2","group3"]),
+
+ %% Check that the members of all groups are correct.
+ Group1 = mod_auth_mnesia:list_group_members("group1", Port,
+ "/mnesia_open"),
+ ok = check_lists_members(Group1,["one","Aladdin"]),
+ {ok,["two"]} = mod_auth_mnesia:list_group_members("group2", Port,
+ "/mnesia_open"),
+
+ {ok,["three"]} = mod_auth_mnesia:list_group_members("group3", Port,
+ "/mnesia_open"),
+
+ %% Delete user 'one' from group one and check that he was removed
+ %% correctly.
+ true = mod_auth_mnesia:remove_group_member("group1", "one", Port,
+ "/mnesia_open", ""),
+ {ok,["Aladdin"]} = mod_auth_mnesia:list_group_members("group1", Port,
+ "/mnesia_open"),
+
+ %% Remove group1 and check that the group was removed correctly.
+ true = mod_auth_mnesia:remove_group("group1", Port, "/mnesia_open", ""),
+ Groups_1 = mod_auth_mnesia:list_groups(Port, "/mnesia_open"),
+ ok = check_lists_members(Groups_1,["group2","group3"]),
+
+ %% Check that the other users still exist in their groups.
+ Users_1 = mod_auth_mnesia:list_users(Port, "/mnesia_open"),
+ ok = check_lists_members(Users_1,["Aladdin","one","two","three"]),
+ {ok,["two"]} = mod_auth_mnesia:list_group_members("group2", Port,
+ "/mnesia_open"),
+ {ok,["three"]} = mod_auth_mnesia:list_group_members("group3", Port,
+ "/mnesia_open"),
+
+ %% Remove the remaining groups/users and check that all
+ %% users/groups are removed.
+ true = mod_auth_mnesia:remove_group("group2", Port, "/mnesia_open", ""),
+ true = mod_auth_mnesia:remove_group("group3", Port, "/mnesia_open", ""),
+ {ok, []} = mod_auth_mnesia:list_groups(Port, "/mnesia_open"),
+ true = mod_auth_mnesia:remove_user("one", Port, "/mnesia_open", ""),
+ true = mod_auth_mnesia:remove_user("Aladdin", Port, "/mnesia_open", ""),
+ true = mod_auth_mnesia:remove_user("two", Port, "/mnesia_open", ""),
+ true = mod_auth_mnesia:remove_user("three", Port, "/mnesia_open", ""),
+ {ok, []} = mod_auth_mnesia:list_users(Port, "/mnesia_open"),
+ ok.
+%%--------------------------------------------------------------------------
+htaccess(Type, Port, Host, Node) ->
+ %% Control that authentication required!
+ %% Control that the pages that shall be
+ %% authenticated really need authenticatin
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /ht/open/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /ht/secret/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /ht/secret/top_secret/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+
+ %% Make sure Authenticate header is received even the second time
+ %% we try a incorrect password! Otherwise a browser client will hang!
+ auth_request(Type, Host, Port, Node,"/ht/open/",
+ "dummy", "WrongPassword", [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
+ auth_request(Type, Host, Port, Node,"/ht/open/",
+ "dummy", "WrongPassword", [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
+
+ %% Control that not just the first user in the list is valid
+ %% Control the first user
+ %% Authennticating ["one:OnePassword" user first in user list]
+ auth_request(Type, Host, Port, Node, "/ht/open/dummy.html", "one",
+ "OnePassword", [{statuscode, 200}]),
+
+ %% Control the second user
+ %% Authentication OK and a directory listing is supplied!
+ %% ["Aladdin:open sesame" user second in user list]
+ auth_request(Type, Host, Port, Node, "/ht/open/","Aladdin",
+ "AladdinPassword", [{statuscode, 200}]),
+
+ %% Contro that bad passwords and userids get a good denial
+ %% User correct but wrong password! ["one:one" user first in user list]
+ auth_request(Type, Host, Port, Node, "/ht/open/", "one", "one",
+ [{statuscode, 401}]),
+ %% Neither user or password correct! ["dummy:dummy"]
+ auth_request(Type, Host, Port, Node, "/ht/open/", "dummy", "dummy",
+ [{statuscode, 401}]),
+
+ %% Control that authetication still works, even if its a member in a group
+ %% Authentication OK! ["two:TwoPassword" user in first group]
+ auth_request(Type, Host, Port, Node, "/ht/secret/dummy.html", "two",
+ "TwoPassword", [{statuscode, 200}]),
+
+ %% Authentication OK and a directory listing is supplied!
+ %% ["three:ThreePassword" user in second group]
+ auth_request(Type, Host, Port, Node,"/ht/secret/", "three",
+ "ThreePassword", [{statuscode, 200}]),
+
+ %% Deny users with bad passwords even if the user is a group member
+ %% User correct but wrong password! ["two:two" user in first group]
+ auth_request(Type, Host, Port, Node, "/ht/secret/", "two", "two",
+ [{statuscode, 401}]),
+ %% Neither user or password correct! ["dummy:dummy"]
+ auth_request(Type, Host, Port, Node,"/ht/secret/", "dummy", "dummy",
+ [{statuscode, 401}]),
+
+ %% control that we deny the users that are in subnet above the allowed
+ auth_request(Type, Host, Port, Node,"/ht/blocknet/dummy.html", "four",
+ "FourPassword", [{statuscode, 403}]),
+ %% Control that we only applies the rules to the right methods
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /ht/blocknet/dummy.html"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+
+ %% Control that the rerquire directive can be overrideen
+ auth_request(Type, Host, Port, Node,
+ "/ht/secret/top_secret/", "Aladdin", "AladdinPassword",
+ [{statuscode, 401}]),
+
+ %% Authentication still required!
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /ht/open/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /ht/secret/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /ht/secret/top_secret/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]).
+%%--------------------------------------------------------------------
+cgi(Type, Port, Host, Node) ->
+ {Script, Script2, Script3} =
+ case test_server:os_type() of
+ {win32, _} ->
+ {"printenv.bat", "printenv.sh", "cgi_echo.exe"};
+ _ ->
+ {"printenv.sh", "printenv.bat", "cgi_echo"}
+ end,
+
+ %% The length (> 100) is intentional
+ ok = httpd_test_lib:
+ verify_request(Type, Host, Port, Node,
+ "POST /cgi-bin/" ++ Script3 ++
+ " HTTP/1.0\r\n"
+ "Content-Length:100 \r\n\r\n "
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ " \r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"},
+ {header, "content-type", "text/plain"}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/"++ Script ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/not_there "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 404},{statuscode, 500},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/"++ Script ++
+ "?Nisse:kkk?sss/lll HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "POST /cgi-bin/"++ Script ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /htbin/"++ Script ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /htbin/not_there "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 404},{statuscode, 500},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /htbin/"++ Script ++
+ "?Nisse:kkk?sss/lll HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "POST /htbin/"++ Script ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "POST /htbin/"++ Script ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+
+ %% Execute an existing, but bad CGI script..
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "POST /htbin/"++ Script2 ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 404},
+ {version, "HTTP/1.0"}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "POST /cgi-bin/"++ Script2 ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 404},
+ {version, "HTTP/1.0"}]),
+ ok.
+
+%%--------------------------------------------------------------------
+esi(Type, Port, Host, Node) ->
+ %% Check "ErlScriptAlias" and "EvalScriptAlias" directives
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /eval?httpd_example:print(\"Hi!\")"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /eval?not_allowed:print(\"Hi!\")"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 403},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /eval?httpd_example:undef(\"Hi!\")"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 500},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 400},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example:get "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example:"
+ "get?input=4711"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example:"
+ "post HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/not_allowed:post "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 403},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example:undef "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 404},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example/yahoo"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 302},
+ {version, "HTTP/1.0"}]),
+ ok.
+%%--------------------------------------------------------------------
+get(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /index.html HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type", "text/html"},
+ {header, "Date"},
+ {header, "Server"},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /fsize.shtml HTTP/1.1\r\nHost:"
+ ++ Host ++ "\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type", "text/html"},
+ {header, "Date"},
+ {header, "Server"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /fsize.shtml HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type"},
+ {header, "Server"},
+ {header, "Date"},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /secret/dummy.html "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {header, "WWW-Authenticate"},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /index.html HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Server"},
+ {header, "Date"},
+ {header, "Content-Type",
+ "text/html"},
+ {version, "HTTP/1.0"}]),
+ ok.
+
+%%--------------------------------------------------------------------
+head(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /index.html HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok.
+%%--------------------------------------------------------------------
+all(Type, Port, Host, Node) ->
+ actions(Type, Port, Host, Node),
+ alias(Type, Port, Host, Node),
+ auth(Type, Port, Host, Node),
+ cgi(Type, Port, Host, Node),
+ esi(Type, Port, Host, Node),
+ get(Type, Port, Host, Node),
+ head(Type, Port, Host, Node),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+auth_request(Type, Host, Port, Node, URI, User, Passwd, Expect) ->
+ Req = ["GET ", URI, " HTTP/1.0\r\n",
+ "Authorization: Basic ",
+ base64:encode_to_string(User++":"++Passwd),
+ "\r\n\r\n"],
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ lists:flatten(Req),
+ [{version, "HTTP/1.0"} | Expect]).
+
+remove_users(Node, ServerRoot, Host, Port, Dir) ->
+ %% List users, delete them, and make sure they are gone.
+ case list_users(Node, ServerRoot, Host, Port, Dir) of
+ {ok, Users} ->
+ lists:foreach(fun(User) ->
+ delete_user(Node, ServerRoot, Host,
+ Port, Dir, User)
+ end,
+ Users),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port, Dir);
+ _ ->
+ ok
+ end.
+
+add_user(Node, Root, Port, Dir, User, Password, UserData) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", Dir]),
+ rpc:call(Node, mod_auth, add_user,
+ [User, Password, UserData, Addr, Port, Directory]).
+
+delete_user(Node, Root, _Host, Port, Dir, User) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", Dir]),
+ rpc:call(Node, mod_auth, delete_user, [User, Addr, Port, Directory]).
+
+list_users(Node, Root, _Host, Port, Dir) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", Dir]),
+ rpc:call(Node, mod_auth, list_users, [Addr, Port, Directory]).
+
+receive_security_event(Event, Node, Port) ->
+ io:format(user, "~w:receive_security_event -> entry with"
+ "~n Event: ~p"
+ "~n Node: ~p"
+ "~n Port: ~p"
+ "~n", [?MODULE, Event, Node, Port]),
+ receive
+ Event ->
+ ok;
+ {'EXIT', _, _} ->
+ receive_security_event(Event, Node, Port);
+ Other ->
+ test_server:fail({unexpected_event,
+ {expected, Event}, {received, Other}})
+ after 5000 ->
+ test_server:fail(no_event_recived)
+
+ end.
+
+list_blocked_users(Node,Port) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_blocked_users, [Addr,Port]).
+
+list_blocked_users(Node,Port,Dir) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_blocked_users, [Addr,Port,Dir]).
+
+block_user(Node,User,Port,Dir,Sec) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, block_user, [User, Addr, Port, Dir, Sec]).
+
+unblock_user(Node,User,Port,Dir) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, unblock_user, [User, Addr, Port, Dir]).
+
+list_auth_users(Node,Port) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_auth_users, [Addr,Port]).
+
+list_auth_users(Node,Port,Dir) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_auth_users, [Addr,Port,Dir]).
+
+update_password(Node, ServerRoot, _Address, Port, Dir, Old, New)->
+ Directory = filename:join([ServerRoot, "htdocs", Dir]),
+ rpc:call(Node, mod_auth, update_password,
+ [undefined, Port, Directory, Old, New, New]).
+
+remove_groups(Node, ServerRoot, Host, Port, Dir) ->
+ Directory = filename:join([ServerRoot, "htdocs", Dir]),
+ {ok, Groups} = list_groups(Node, ServerRoot, Host, Port, Directory),
+ lists:foreach(fun(Group) ->
+ delete_group(Node, Group, Port, Directory)
+ end,
+ Groups),
+ {ok, []} = list_groups(Node, ServerRoot, Host, Port, Directory),
+ ok.
+
+delete_group(Node, Group, Port, Dir) ->
+ Addr = undefined,
+ rpc:call(Node, mod_auth, delete_group, [Group, Addr, Port, Dir]).
+
+list_groups(Node, _, _, Port, Dir) ->
+ Addr = undefined,
+ rpc:call(Node, mod_auth, list_groups, [Addr, Port, Dir]).
+
+add_group_member(Node, ServerRoot, Port, Dir, User, Group) ->
+ Addr = undefined,
+ rpc:call(Node, mod_auth, add_group_member, [Group, User, Addr, Port,
+ filename:join(
+ [ServerRoot,
+ "htdocs",Dir])]).
+event(What, Port, Dir, Data) ->
+ Msg = {event, What, Port, Dir, Data},
+ case global:whereis_name(mod_security_test) of
+ undefined ->
+ ok;
+ _Pid ->
+ global:send(mod_security_test, Msg)
+ end.
+
+ssl_password_cb() ->
+ "dummy-ssl-password".
+
+check_lists_members({ok,L},L) ->
+ ok;
+check_lists_members({ok,L1},L2) ->
+ check_lists_members1(lists:sort(L1),lists:sort(L2));
+check_lists_members(Error,_L) ->
+ Error.
+
+check_lists_members1(L,L) ->
+ ok;
+check_lists_members1(L1,L2) ->
+ {error,{lists_not_equal,L1,L2}}.
diff --git a/lib/inets/test/httpd_poll.erl b/lib/inets/test/httpd_poll.erl
new file mode 100644
index 0000000000..1cc10365a7
--- /dev/null
+++ b/lib/inets/test/httpd_poll.erl
@@ -0,0 +1,496 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(httpd_poll).
+-behaviour(gen_server).
+
+
+%% External API
+-export([start/0, start_appup/2, start/3,stop/0,verbosity/1,poll_time/1]).
+
+%% gen_server exports
+-export([init/1,
+ handle_call/3, handle_cast/2, handle_info/2, terminate/2]).
+
+
+-define(default_verbosity,error).
+-define(default_poll_time,60000). %% 60 seconds
+
+
+-record(state,{host = "", port = -1, ptime = -1, tref = none, uris = []}).
+
+
+%% start/0
+%%
+%% Description: Start polling HTTPD with default values
+%%
+start() ->
+ Options = default_options(otp),
+ start("gandalf", 8000, Options).
+
+start_appup(Host, Port) ->
+ Options = default_options(top),
+ start(Host, Port, Options).
+
+%% start/3
+%%
+%% Description: Start polling HTTPD
+%%
+%% Parameters:
+%% Host = string()
+%% Host name of HTTPD
+%% Port = integer()
+%% Port number of HTTPD
+%% Options = [Option]
+%% Option = {poll_time,integer()} | {verbosity,verbosity()} |
+%% {log_file,string()} | {uris,[uri()]}
+%% verbosity() = silence | error | log | debug | trace
+%% uri() = {string(),string}
+%% First part is a descriptive string and the second
+%% part is the actual URI.
+%%
+start(Host,Port,Options) ->
+ gen_server:start({local,httpd_tester},?MODULE,[Host,Port,Options],[]).
+
+stop() ->
+ gen_server:call(httpd_tester,stop).
+
+
+default_options(UriDesc) ->
+ Verbosity = {verbosity,?default_verbosity},
+ Uris = {uris,uris(UriDesc)},
+ PollTime = {poll_time,?default_poll_time},
+ Logging = {log_file,"httpd_poll.log"},
+ [Verbosity, Uris, PollTime, Logging].
+
+
+options(Options) ->
+ options(Options, default_options(otp), []).
+
+options([], Defaults, Options) ->
+ Options ++ Defaults;
+options([{Key,Val} = Opt|Opts], Defaults, Options) ->
+ options(Opts, lists:keydelete(Key, 1, Defaults), [Opt|Options]).
+
+
+verbosity(silence) ->
+ set_verbosity(silence);
+verbosity(error) ->
+ set_verbosity(error);
+verbosity(log) ->
+ set_verbosity(log);
+verbosity(debug) ->
+ set_verbosity(debug);
+verbosity(trace) ->
+ set_verbosity(trace).
+
+set_verbosity(Verbosity) ->
+ gen_server:cast(httpd_tester,{verbosity,Verbosity}).
+
+poll_time(NewTime) ->
+ gen_server:call(httpd_tester,{poll_time,NewTime}).
+
+
+%% ----------------------------------------------------------------------
+
+
+init([Host, Port, Options0]) ->
+ process_flag(trap_exit,true),
+ Options = options(Options0),
+ put(verbosity,get_verbosity(Options)),
+ log_open(get_log_file(Options)),
+ tstart(),
+ PollTime = get_poll_time(Options),
+ Ref = tcreate(PollTime),
+ log("created"),
+ {ok,#state{host = Host,
+ port = Port,
+ ptime = PollTime,
+ tref = Ref,
+ uris = get_uris(Options)}}.
+
+uris(top) ->
+ [uri_top_index()];
+
+uris(otp) ->
+ [
+ uri_top_index(),
+ uri_internal_product1(),
+ uri_internal_product2(),
+ uri_p7a_test_results(),
+ uri_bjorn1(),
+ uri_bjorn2(),
+ uri_top_ronja()
+ ].
+
+uri_top_index() ->
+ {"top page","/"}.
+
+uri_internal_product1() ->
+ {"product internal page (1)","/product/internal/"}.
+
+uri_internal_product2() ->
+ {"product internal page (2)","/product/internal"}.
+
+uri_p7a_test_results() ->
+ {"test summery index page",
+ "/product/internal/test/test_results/progress_P7A/index.html"}.
+
+uri_bjorn1() ->
+ {"bjorns home page (1)","/~bjorn/"}.
+
+uri_bjorn2() ->
+ {"bjorns home page (2)","/~bjorn"}.
+
+uri_top_ronja() ->
+ {"ronja top page","/ronja/"}.
+
+
+handle_call(stop, _From, State) ->
+ vlog("stop request"),
+ {stop, normal, ok, State};
+
+handle_call({poll_time,NewTime}, _From, State) ->
+ vlog("set new poll time: ~p",[NewTime]),
+ OldTime = State#state.ptime,
+ {stop, normal, OldTime, State#state{ptime = NewTime}};
+
+handle_call(Request, _From, State) ->
+ vlog("unexpected request(call): ~p",[Request]),
+ {reply, ok, State}.
+
+
+handle_cast({verbosity,Verbosity}, State) ->
+ vlog("set (new) verbosity to: ~p",[Verbosity]),
+ put(verbosity,Verbosity),
+ {noreply, State};
+
+handle_cast(Message, State) ->
+ vlog("unexpected message(call): ~p",[Message]),
+ {noreply, State}.
+
+
+handle_info(poll_time,State) ->
+ {{Description,Uri},Uris} = get_uri(State#state.uris),
+ vlog("poll time for ~s",[Description]),
+ do_poll(State#state.host,State#state.port,Uri),
+ Ref = tcreate(State#state.ptime),
+ {noreply, State#state{tref = Ref, uris = Uris}};
+
+handle_info(Info, State) ->
+ vlog("unexpected message(info): ~p",[Info]),
+ {noreply, State}.
+
+
+terminate(Reason,State) ->
+ tcancel(State#state.tref),
+ log_close(get(log_file)),
+ ok.
+
+
+get_uri([Uri|Uris]) ->
+ {Uri,Uris++[Uri]}.
+
+
+do_poll(Host,Port,Uri) ->
+ (catch poll(create(Host,Port),Uri,"200")).
+
+poll({ok,Socket},Uri,ExpStatus) ->
+ vtrace("poll -> entry with Socket: ~p",[Socket]),
+ put(latest_requested_uri,Uri),
+ Req = "GET " ++ Uri ++ " HTTP/1.0\r\n\r\n",
+ await_poll_response(send(Socket,Req),Socket,ExpStatus);
+poll({error,Reason},_Req,_ExpStatus) ->
+ verror("failed creating socket: ~p",[Reason]),
+ log("failed creating socket: ~p",[Reason]),
+ exit({error,Reason});
+poll(O,_Req,_ExpStatus) ->
+ verror("unexpected result from socket create: ~p",[O]),
+ log("unexpected result from socket create: ~p",[O]),
+ exit({unexpected_result,O}).
+
+await_poll_response(ok,Socket,ExpStatusCode) ->
+ vtrace("await_poll_response -> awaiting response with status ~s",
+ [ExpStatusCode]),
+ receive
+ {tcp_closed,Socket} ->
+ verror("connection closed when awaiting poll response"),
+ log("connection closed when awaiting reply to GET of '~s'",
+ [get(latest_requested_uri)]),
+ exit(connection_closed);
+ {tcp,Socket,Response} ->
+ vdebug("received response"),
+ validate(ExpStatusCode,Socket,Response)
+ after 10000 ->
+ verror("connection timeout waiting for poll response",[]),
+ log("connection timeout waiting for reply to GET of '~s'",
+ [get(latest_requested_uri)]),
+ exit(connection_timed_out)
+ end;
+await_poll_response(Error,_Socket,_ExpStatusCode) ->
+ verror("failed sending GET request for '~s' for reason: ~p",
+ [get(latest_requested_uri),Error]),
+ log("failed sending GET request for '~s' for reason: ~p",
+ [get(latest_requested_uri),Error]),
+ exit(Error).
+
+
+validate(ExpStatusCode,Socket,Response) ->
+ Sz = sz(Response),
+ vtrace("validate -> Entry with ~p bytes response",[Sz]),
+ Size = trash_the_rest(Socket,Sz),
+ close(Socket),
+ case inets_regexp:split(Response," ") of
+ {ok,["HTTP/1.0",ExpStatusCode|_]} ->
+ vlog("response (~p bytes) was ok",[Size]),
+ ok;
+ {ok,["HTTP/1.0",StatusCode|_]} ->
+ verror("unexpected response status received: ~s => ~s",
+ [StatusCode,status_to_message(StatusCode)]),
+ log("unexpected result to GET of '~s': ~s => ~s",
+ [get(latest_requested_uri),StatusCode,
+ status_to_message(StatusCode)]),
+ exit({unexpected_response_code,StatusCode,ExpStatusCode})
+ end.
+
+
+%% ------------------------------------------------------------------
+
+trash_the_rest(Socket,N) ->
+ receive
+ {tcp, Socket, Trash} ->
+ vtrace("trash_the_rest -> trash ~p bytes",[sz(Trash)]),
+ trash_the_rest(Socket,add(N,sz(Trash)));
+ {tcp_closed, Socket} ->
+ vdebug("socket closed after receiving ~p bytes",[N]),
+ N
+ after 10000 ->
+ verror("connection timeout waiting for message"),
+ exit(connection_timed_out)
+ end.
+
+
+add(N1,N2) when integer(N1),integer(N2) ->
+ N1 + N2;
+add(N1,N2) when integer(N1) ->
+ N1;
+add(N1,N2) when integer(N2) ->
+ N2.
+
+sz(L) when list(L) ->
+ length(lists:flatten(L));
+sz(B) when binary(B) ->
+ size(B);
+sz(O) ->
+ {unknown_size,O}.
+
+
+%% --------------------------------------------------------------
+%%
+%% Status code to printable string
+%%
+
+status_to_message(L) when list(L) ->
+ case (catch list_to_integer(L)) of
+ I when integer(I) ->
+ status_to_message(I);
+ _ ->
+ io_lib:format("UNKNOWN STATUS CODE: '~p'",[L])
+ end;
+status_to_message(100) -> "Section 10.1.1: Continue";
+status_to_message(101) -> "Section 10.1.2: Switching Protocols";
+status_to_message(200) -> "Section 10.2.1: OK";
+status_to_message(201) -> "Section 10.2.2: Created";
+status_to_message(202) -> "Section 10.2.3: Accepted";
+status_to_message(203) -> "Section 10.2.4: Non-Authoritative Information";
+status_to_message(204) -> "Section 10.2.5: No Content";
+status_to_message(205) -> "Section 10.2.6: Reset Content";
+status_to_message(206) -> "Section 10.2.7: Partial Content";
+status_to_message(300) -> "Section 10.3.1: Multiple Choices";
+status_to_message(301) -> "Section 10.3.2: Moved Permanently";
+status_to_message(302) -> "Section 10.3.3: Found";
+status_to_message(303) -> "Section 10.3.4: See Other";
+status_to_message(304) -> "Section 10.3.5: Not Modified";
+status_to_message(305) -> "Section 10.3.6: Use Proxy";
+status_to_message(307) -> "Section 10.3.8: Temporary Redirect";
+status_to_message(400) -> "Section 10.4.1: Bad Request";
+status_to_message(401) -> "Section 10.4.2: Unauthorized";
+status_to_message(402) -> "Section 10.4.3: Peyment Required";
+status_to_message(403) -> "Section 10.4.4: Forbidden";
+status_to_message(404) -> "Section 10.4.5: Not Found";
+status_to_message(405) -> "Section 10.4.6: Method Not Allowed";
+status_to_message(406) -> "Section 10.4.7: Not Acceptable";
+status_to_message(407) -> "Section 10.4.8: Proxy Authentication Required";
+status_to_message(408) -> "Section 10.4.9: Request Time-Out";
+status_to_message(409) -> "Section 10.4.10: Conflict";
+status_to_message(410) -> "Section 10.4.11: Gone";
+status_to_message(411) -> "Section 10.4.12: Length Required";
+status_to_message(412) -> "Section 10.4.13: Precondition Failed";
+status_to_message(413) -> "Section 10.4.14: Request Entity Too Large";
+status_to_message(414) -> "Section 10.4.15: Request-URI Too Large";
+status_to_message(415) -> "Section 10.4.16: Unsupported Media Type";
+status_to_message(416) -> "Section 10.4.17: Requested range not satisfiable";
+status_to_message(417) -> "Section 10.4.18: Expectation Failed";
+status_to_message(500) -> "Section 10.5.1: Internal Server Error";
+status_to_message(501) -> "Section 10.5.2: Not Implemented";
+status_to_message(502) -> "Section 10.5.3: Bad Gatteway";
+status_to_message(503) -> "Section 10.5.4: Service Unavailable";
+status_to_message(504) -> "Section 10.5.5: Gateway Time-out";
+status_to_message(505) -> "Section 10.5.6: HTTP Version not supported";
+status_to_message(Code) -> io_lib:format("Unknown status code: ~p",[Code]).
+
+
+%% ----------------------------------------------------------------
+
+create(Host,Port) ->
+ vtrace("create -> ~n\tHost: ~s~n\tPort: ~p",[Host,Port]),
+ case gen_tcp:connect(Host,Port,[{packet,0},{reuseaddr,true}]) of
+ {ok,Socket} ->
+ {ok,Socket};
+ {error,{enfile,_}} ->
+ {error,enfile};
+ Error ->
+ Error
+ end.
+
+close(Socket) ->
+ gen_tcp:close(Socket).
+
+
+send(Socket,Data) ->
+ vtrace("send -> send ~p bytes of data",[length(Data)]),
+ gen_tcp:send(Socket,Data).
+
+
+%% ----------------------------------------------------------------
+
+tstart() ->
+ timer:start().
+
+tcreate(Time) ->
+ {ok,Ref} = timer:send_after(Time,poll_time),
+ Ref.
+
+tcancel(Ref) ->
+ timer:cancel(Ref).
+
+%% ----------------------------------------------------------------
+
+log_open(undefined) ->
+ ok;
+log_open(FileName) ->
+ put(log_file,fopen(FileName)).
+
+log_close(undefined) ->
+ ok;
+log_close(Fd) ->
+ fclose(Fd).
+
+log(F) ->
+ log(F,[]).
+
+log(F,A) ->
+ {{Year,Month,Day},{Hour,Min,Sec}} = local_time(),
+ fwrite(get(log_file),
+ "~w.~w.~w ~w.~w.~w " ++ F ++ "~n",
+ [Year,Month,Day,Hour,Min,Sec] ++ A).
+
+%% ----------------------------------------------------------------
+
+fopen(Name) ->
+ {ok,Fd} = file:open(Name,[write]),
+ Fd.
+
+fclose(Fd) ->
+ file:close(Fd).
+
+fwrite(undefined,_F,_A) ->
+ ok;
+fwrite(Fd,F,A) ->
+ io:format(Fd,F,A).
+
+
+%% ----------------------------------------------------------------
+
+get_poll_time(Opts) ->
+ get_option(poll_time,Opts,?default_poll_time).
+
+get_log_file(Opts) ->
+ get_option(log_file,Opts).
+
+get_uris(Opts) ->
+ get_option(uris,Opts,[]).
+
+get_verbosity(Opts) ->
+ get_option(verbosity,Opts,?default_verbosity).
+
+get_option(Opt,Opts) ->
+ get_option(Opt,Opts,undefined).
+
+get_option(Opt,Opts,Default) ->
+ case lists:keysearch(Opt,1,Opts) of
+ {value,{Opt,Value}} ->
+ Value;
+ false ->
+ Default
+ end.
+
+%% ----------------------------------------------------------------
+
+%% sleep(T) -> receive after T -> ok end.
+
+%% ----------------------------------------------------------------
+
+%% vtrace(F) -> vprint(get(verbosity),trace,F,[]).
+vtrace(F,A) -> vprint(get(verbosity),trace,F,A).
+
+vdebug(F) -> vprint(get(verbosity),debug,F,[]).
+vdebug(F,A) -> vprint(get(verbosity),debug,F,A).
+
+vlog(F) -> vprint(get(verbosity),log,F,[]).
+vlog(F,A) -> vprint(get(verbosity),log,F,A).
+
+verror(F) -> vprint(get(verbosity),error,F,[]).
+verror(F,A) -> vprint(get(verbosity),error,F,A).
+
+vprint(trace,Severity,F,A) -> vprint(Severity,F,A);
+vprint(debug,trace,F,A) -> ok;
+vprint(debug,Severity,F,A) -> vprint(Severity,F,A);
+vprint(log,log,F,A) -> vprint(log,F,A);
+vprint(log,error,F,A) -> vprint(log,F,A);
+vprint(error,error,F,A) -> vprint(error,F,A);
+vprint(_Verbosity,_Severity,_F,_A) -> ok.
+
+vprint(Severity,F,A) ->
+ {{Year,Month,Day},{Hour,Min,Sec}} = local_time(),
+ io:format("~w.~w.~w ~w.~w.~w " ++ image_of(Severity) ++ F ++ "~n",
+ [Year,Month,Day,Hour,Min,Sec] ++ A).
+
+image_of(error) -> "ERR: ";
+image_of(log) -> "LOG: ";
+image_of(debug) -> "DBG: ";
+image_of(trace) -> "TRC: ".
+
+local_time() -> calendar:local_time().
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/auth/group b/lib/inets/test/httpd_test_data/server_root/auth/group
new file mode 100644
index 0000000000..b3da0ccbd3
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/auth/group
@@ -0,0 +1,3 @@
+group1: one two
+group2: two three
+group3: three Aladdin
diff --git a/lib/inets/test/httpd_test_data/server_root/auth/passwd b/lib/inets/test/httpd_test_data/server_root/auth/passwd
new file mode 100644
index 0000000000..8c980ff547
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/auth/passwd
@@ -0,0 +1,4 @@
+one:onePassword
+two:twoPassword
+three:threePassword
+Aladdin:AladdinPassword
diff --git a/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.bat b/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.bat
new file mode 100644
index 0000000000..25a49a1536
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.bat
@@ -0,0 +1,9 @@
+@echo off
+echo tomrad > c:\cygwin\tmp\hej
+echo Content-type: text/html
+echo.
+echo ^<HTML^> ^<HEAD^> ^<TITLE^>OS Environment^</TITLE^> ^</HEAD^> ^<BODY^>^<PRE^>
+set
+echo ^</PRE^>^</BODY^>^</HTML^>
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.sh b/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.sh
new file mode 100755
index 0000000000..de81de9bde
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+echo "Content-type: text/html"
+echo ""
+echo "<HTML> <HEAD> <TITLE>OS Environment</TITLE> </HEAD> <BODY><PRE>"
+env
+echo "</PRE></BODY></HTML>" \ No newline at end of file
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/8080.conf b/lib/inets/test/httpd_test_data/server_root/conf/8080.conf
new file mode 100644
index 0000000000..48e66f0114
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/conf/8080.conf
@@ -0,0 +1,79 @@
+Port 8080
+#ServerName your.server.net
+SocketType ip_comm
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8080
+TransferLog logs/access_log_8080
+SecurityLog logs/security_log_8080
+ErrorDiskLog logs/error_disk_log_8080
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8080
+TransferDiskLogSize 200000 10
+SecurityDiskLog logs/security_disk_log
+SecurityDiskLogSize 200000 10
+MaxClients 50
+#KeepAlive 5
+#KeepAliveTimeout 10
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthDBType plain
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthDBType plain
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthDBType plain
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthDBType mnesia
+AuthName Open Area
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthDBType mnesia
+AuthName Secret Area
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthDBType mnesia
+AuthName Top Secret Area
+require group group3
+allow from 130.100.34 130.100.35
+deny from 100.234.22.12 194.100.34.1 130.100.34.25
+SecurityDataFile logs/security_data
+SecurityMaxRetries 3
+SecurityBlockTime 10
+SecurityFailExpireTime 1
+SecurityAuthTimeout 1
+SecurityCallbackModule security_callback
+</Directory>
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/8888.conf b/lib/inets/test/httpd_test_data/server_root/conf/8888.conf
new file mode 100644
index 0000000000..79bb7fcca4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/conf/8888.conf
@@ -0,0 +1,63 @@
+Port 8888
+#ServerName your.server.net
+SocketType ip_comm
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8888
+TransferLog logs/access_log_8888
+ErrorDiskLog logs/error_disk_log_8888
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8888
+TransferDiskLogSize 200000 10
+MaxClients 150
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthName Open Area
+AuthMnesiaDB On
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthName Secret Area
+AuthMnesiaDB On
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthName Top Secret Area
+AuthMnesiaDB On
+require group group3
+</Directory>
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf b/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
new file mode 100644
index 0000000000..8a74ed1afd
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
@@ -0,0 +1,268 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+
+# Port: The port the standalone listens to. For ports < 1023, you will
+# need httpd to be run as root initially.
+
+Port 8888
+
+# BindAddress: This directive is used to tell the server which IP address
+# to listen to. It can either contain "*", an IP address, or a fully
+# qualified Internet domain name.
+#
+# It is also possible to specify the ip-family with the directive.
+# There ar three possible value: inet, inet6 and inet6fb4
+# inet: Use IpFamily inet when retreiving the address and
+# fail if that does not work.
+# inet6: Use IpFamily inet6 when retreiving the address and
+# fail if that does not work.
+# inet6fb4: First IpFamily inet6 is tried and if that does not work,
+# inet is used as fallback.
+# Default value for ip-family is inet6fb4
+#
+# The syntax is: <address>[|<ip-family>]
+#
+#BindAddress *
+#BindAddress *|inet
+
+
+# ServerName allows you to set a host name which is sent back to clients for
+# your server if it's different than the one the program would get (i.e. use
+# "www" instead of the host's real name).
+#
+# Note: You cannot just invent host names and hope they work. The name you
+# define here must be a valid DNS name for your host. If you don't understand
+# this, ask your network administrator.
+
+#ServerName your.server.net
+
+# SocketType is either ip_comm, sockets or ssl.
+
+SocketType ip_comm
+
+# Modules: Server run-time plug-in modules written using the Erlang
+# Web Server API (EWSAPI). The server API make it easy to add functionality
+# to the server. Read more about EWSAPI in the Reference Manual.
+# WARNING! Do not tamper with this directive unless you are familiar with
+# EWSAPI.
+
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_responsecontrol mod_trace mod_range mod_head mod_include mod_dir mod_get mod_log mod_disk_log
+
+# ServerAdmin: Your address, where problems with the server should be
+# e-mailed.
+
+ServerAdmin [email protected]
+
+# ServerRoot: The directory the server's config, error, and log files
+# are kept in
+
+ServerRoot /var/tmp/server_root
+
+# ErrorLog: The location of the error log file. If this does not start
+# with /, ServerRoot is prepended to it.
+
+ErrorLog logs/error_log
+
+# TransferLog: The location of the transfer log file. If this does not
+# start with /, ServerRoot is prepended to it.
+
+TransferLog logs/access_log
+
+# SecurityLog: The location of the security log file (mod_security required)
+#
+SecurityLog logs/security_log
+
+# ErrorDiskLog: The location of the error log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The ErrorDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+ErrorDiskLog logs/error_disk_log
+ErrorDiskLogSize 200000 10
+
+# TransferDiskLog: The location of the transfer log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The TransferDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+TransferDiskLog logs/access_disk_log
+TransferDiskLogSize 200000 10
+
+# SecurityDiskLog: The location of the security log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The SecurityDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+SecurityDiskLog logs/security_disk_log
+SecurityDiskLogSize 200000 10
+
+# Limit on total number of servers running, i.e., limit on the number
+# of clients who can simultaneously connect --- if this limit is ever
+# reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW.
+# It is intended mainly as a brake to keep a runaway server from taking
+# the server with it as it spirals down...
+
+MaxClients 50
+
+# KeepAlive set the flag for persistent connections. For peristent connections
+# set KeepAlive to on. To use One request per connection set the flag to off
+# Note: The value has changed since previous version of INETS.
+KeepAlive on
+
+# KeepAliveTimeout sets the number of seconds before a persistent connection
+# times out and closes.
+KeepAliveTimeout 10
+
+# MaxKeepAliveRequests sets the number of seconds before a persistent connection
+# times out and closes.
+MaxKeepAliveRequests 10
+
+
+
+# DocumentRoot: The directory out of which you will serve your
+# documents. By default, all requests are taken from this directory, but
+# symbolic links and aliases may be used to point to other locations.
+
+DocumentRoot /var/tmp/server_root/htdocs
+
+# DirectoryIndex: Name of the file or files to use as a pre-written HTML
+# directory index. Separate multiple entries with spaces.
+
+DirectoryIndex index.html welcome.html
+
+# DefaultType is the default MIME type for documents which the server
+# cannot find the type of from filename extensions.
+
+DefaultType text/plain
+
+# Aliases: Add here as many aliases as you need (with no limit). The format is
+# Alias fakename realname
+
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+
+# ScriptAlias: This controls which directories contain server scripts.
+# Format: ScriptAlias fakename realname
+
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+
+# This directive adds an action, which will activate cgi-script when a
+# file is requested using the method of method, which can be one of
+# GET, POST and HEAD. It sends the URL and file path of the requested
+# document using the standard CGI PATH_INFO and PATH_TRANSLATED
+# environment variables.
+
+#Script HEAD /cgi-bin/printenv.sh
+
+# This directive adds an action, which will activate cgi-script when a
+# file of content type mime-type is requested. It sends the URL and
+# file path of the requested document using the standard CGI PATH_INFO
+# and PATH_TRANSLATED environment variables.
+
+#Action image/gif /cgi-bin/printenv.sh
+
+# ErlScriptAlias: This specifies how "Erl" server scripts are called.
+# Format: ErlScriptAlias fakename realname allowed_modules
+
+ErlScriptAlias /down/erl httpd_example io
+
+# EvalScriptAlias: This specifies how "Eval" server scripts are called.
+# Format: EvalScriptAlias fakename realname allowed_modules
+
+EvalScriptAlias /eval httpd_example io
+
+# Point SSLCertificateFile at a PEM encoded certificate.
+
+SSLCertificateFile /var/tmp/server_root/ssl/ssl_server.pem
+
+# If the key is not combined with the certificate, use this directive to
+# point at the key file.
+
+SSLCertificateKeyFile /var/tmp/server_root/ssl/ssl_server.pem
+
+# Set SSLVerifyClient to:
+# 0 if no certicate is required
+# 1 if the client may present a valid certificate
+# 2 if the client must present a valid certificate
+# 3 if the client may present a valid certificate but it is not required to
+# have a valid CA
+
+SSLVerifyClient 0
+
+# Each directory to which INETS has access, can be configured with respect
+# to which services and features are allowed and/or disabled in that
+# directory (and its subdirectories).
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthDBType plain
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthDBType plain
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthDBType plain
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthDBType mnesia
+AuthName Open Area
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthDBType mnesia
+AuthName Secret Area
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthDBType mnesia
+AuthName Top Secret Area
+require group group3
+allow from 130.100.34 130.100.35
+deny from 100.234.22.12 194.100.34.1 130.100.34.25
+SecurityDataFile logs/security_data
+SecurityMaxRetries 3
+SecurityBlockTime 10
+SecurityFailExpireTime 1
+SecurityAuthTimeout 1
+SecurityCallbackModule security_callback
+</Directory>
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/mime.types b/lib/inets/test/httpd_test_data/server_root/conf/mime.types
new file mode 100644
index 0000000000..d2f81e4e5e
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/conf/mime.types
@@ -0,0 +1,465 @@
+# This is a comment. I love comments.
+
+# MIME type Extension
+application/EDI-Consent
+application/EDI-X12
+application/EDIFACT
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atomicmail
+application/batch-SMTP
+application/beep+xml
+application/cals-1840
+application/commonground
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/eshop
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/font-tdpfr
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathematica-old
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll
+application/oda oda
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/qsig
+application/remote-printing
+application/riscos
+application/rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/smil smi smil
+application/timestamp-query
+application/timestamp-reply
+application/vemmi
+application/vnd.3M.Post-it-Notes
+application/vnd.FloGraphIt
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.aether.imp
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.businessobjects
+application/vnd.bmi
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.comsocaller
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.ctc-posml
+application/vnd.cybank
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hhe.lesson-player
+application/vnd.hp-HPGL
+application/vnd.hp-PCL
+application/vnd.hp-PCLXL
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.MiniPay
+application/vnd.ibm.modcap
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.koan
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.EDM
+application/vnd.novadigm.EDX
+application/vnd.novadigm.EXT
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-xhtml-print+xml
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.tve-trigger
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.vividence.scriptfile
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yellowriver-custom-menu
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xml
+application/xml-dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/basic au snd
+audio/g.722.1
+audio/l16
+audio/midi mid midi kar
+audio/mp4a-latm
+audio/mpa-robust
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/prs.sid
+audio/telephone-event
+audio/tone
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-mpegurl m3u
+audio/x-pn-realaudio ram rm
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/tiff tiff tif
+image/vnd.cns.inf2
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.mix
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar
+text/css css
+text/directory
+text/enriched
+text/html html htm
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/tab-separated-values tsv
+text/t140
+text/uri-list
+text/vnd.DMClientScript
+text/vnd.IPTC.NITF
+text/vnd.IPTC.NewsML
+text/vnd.abc
+text/vnd.curl
+text/vnd.flatland.3dml
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-setext etx
+text/x-server-parsed-html shtml
+text/xml xml xsl
+text/xml-external-parsed-entity
+video/mp4v-es
+video/mpeg mpeg mpg mpe
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu
+video/vnd.mts
+video/vnd.nokia.interleaved-multimedia
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/ssl.conf b/lib/inets/test/httpd_test_data/server_root/conf/ssl.conf
new file mode 100644
index 0000000000..8b8c57a98b
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/conf/ssl.conf
@@ -0,0 +1,66 @@
+Port 8088
+#ServerName your.server.net
+SocketType ssl
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8088
+TransferLog logs/access_log_8088
+ErrorDiskLog logs/error_disk_log_8088
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8088
+TransferDiskLogSize 200000 10
+MaxClients 150
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+SSLCertificateFile /var/tmp/server_root/ssl/ssl_server.pem
+SSLCertificateKeyFile /var/tmp/server_root/ssl/ssl_server.pem
+SSLVerifyClient 0
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthName Open Area
+AuthMnesiaDB On
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthName Secret Area
+AuthMnesiaDB On
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthName Top Secret Area
+AuthMnesiaDB On
+require group group3
+</Directory>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/config.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/config.shtml
new file mode 100644
index 0000000000..107e3ff610
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/config.shtml
@@ -0,0 +1,70 @@
+<HTML>
+<HEAD>
+<TITLE>/ssi.html (17-Apr-1997)</TITLE>
+</HEAD>
+<BODY>
+<H1>/ssi.html</H1>
+
+<!-- ************* CONFIG ************* -->
+
+<!--#config timefmt="%a %b %e %T %Z %Y" sizefmt="abbrev"-->
+<!--#config errmsg="[an especially ugly error occurred while processing this directive]"-->
+
+<!-- ************* INCLUDE ************* -->
+
+<P>Include /misc/friedrich.html:
+<!--#include virtual="/misc/friedrich.html"-->
+<P>Include /misc/not_defined.html: <!--#include virtual="/misc/not_defined.html"-->
+<P>Include misc/friedrich.html:
+<!--#include file="misc/friedrich.html"-->
+<P>Include not_defined.html: <!--#include file="not_defined.html"-->
+
+<P><HR>
+
+<!-- ************* ECHO ************* -->
+
+<P>DOCUMENT_NAME: <!--#echo var="DOCUMENT_NAME"-->
+<P>DOCUMENT_URI: <!--#echo var="DOCUMENT_URI"-->
+<P>QUERY_STRING_UNESCAPED: <!--#echo var="QUERY_STRING_UNESCAPED"-->
+<P>DATE_LOCAL: <!--#echo var="DATE_LOCAL"-->
+<P>DATE_GMT: <!--#echo var="DATE_GMT"-->
+<P>LAST_MODIFIED: <!--#echo var="LAST_MODIFIED"-->
+<P>NOT_DEFINED: <!--#echo var="NOT_DEFINED"-->
+
+<P><HR>
+
+<!-- ************* FSIZE ************* -->
+
+<P>Size of index.html: <!--#fsize file="index.html"-->
+<P>Size of not_defined.html: <!--#fsize file="not_defined.html"-->
+<!--#config sizefmt="bytes"-->
+<P>Size of /misc/friedrich.html: <!--#fsize virtual="/misc/friedrich.html"-->
+<P>Size of /misc/not_defined.html: <!--#fsize virtual="/misc/not_defined.html"-->
+
+<P><HR>
+
+<!-- ************* FLASTMOD ************* -->
+
+<P>Last modification of index.html: <!--#flastmod file="index.html"-->
+<P>Last modification of not_defined.html: <!--#flastmod file="not_defined.html"-->
+<P>Last modification of /misc/friedrich.html: <!--#flastmod virtual="/misc/friedrich.html"-->
+<P>Last modification of /misc/not_defined.html: <!--#flastmod virtual="/misc/not_defined.html"-->
+
+<!--#exec cmd="ls"-->
+<!--#exec cmd="printenv"-->
+<!--#exec cmd="sunemaja"-->
+
+<!--#exec cgi="/cgi-bin/printenv.sh"-->
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/dets_open/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/top_secret/index.html b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/top_secret/index.html
new file mode 100644
index 0000000000..34db3d5d1a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/echo.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/echo.shtml
new file mode 100644
index 0000000000..141db5be59
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/echo.shtml
@@ -0,0 +1,35 @@
+<HTML>
+<HEAD>
+<TITLE>/echo.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/echo.shtml</H1>
+
+<P>DOCUMENT_NAME: <!--#echo var="DOCUMENT_NAME"-->
+
+<P>DOCUMENT_URI: <!--#echo var="DOCUMENT_URI"-->
+
+<P>QUERY_STRING_UNESCAPED: <!--#echo var="QUERY_STRING_UNESCAPED"-->
+
+<P>DATE_LOCAL: <!--#echo var="DATE_LOCAL"-->
+
+<P>DATE_GMT: <!--#echo var="DATE_GMT"-->
+
+<P>LAST_MODIFIED: <!--#echo var="LAST_MODIFIED"-->
+
+<P>NOT_DEFINED: <!--#echo var="NOT_DEFINED"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/exec.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/exec.shtml
new file mode 100644
index 0000000000..97333da898
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/exec.shtml
@@ -0,0 +1,30 @@
+<HTML>
+<HEAD>
+<TITLE>/exec.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/exec.shtml</H1>
+<PRE>
+<!--#exec cmd="ls"-->
+<HR>
+<!--#exec cmd="printenv"-->
+<HR>
+<!--#exec cmd="sunemaja"-->
+<HR>
+<!--#exec cgi="/cgi-bin/printenv.sh"-->
+</PRE>
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/flastmod.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/flastmod.shtml
new file mode 100644
index 0000000000..d54c36fe50
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/flastmod.shtml
@@ -0,0 +1,29 @@
+<HTML>
+<HEAD>
+<TITLE>/flastmod.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/flastmod.shtml</H1>
+
+<P>Last modification of index.html: <!--#flastmod file="index.html"-->
+
+<P>Last modification of not_defined.html: <!--#flastmod file="not_defined.html"-->
+
+<P>Last modification of /misc/friedrich.html: <!--#flastmod virtual="/misc/friedrich.html"-->
+
+<P>Last modification of /misc/not_defined.html: <!--#flastmod virtual="/misc/not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/fsize.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/fsize.shtml
new file mode 100644
index 0000000000..570ee9cf6d
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/fsize.shtml
@@ -0,0 +1,29 @@
+<HTML>
+<HEAD>
+<TITLE>/fsize.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/fsize.shtml</H1>
+
+<P>Size of index.html: <!--#fsize file="index.html"-->
+
+<P>Size of not_defined.html: <!--#fsize file="not_defined.html"-->
+
+<P>Size of /misc/friedrich.html: <!--#fsize virtual="/misc/friedrich.html"-->
+
+<P>Size of /misc/not_defined.html: <!--#fsize virtual="/misc/not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/include.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/include.shtml
new file mode 100644
index 0000000000..529aad0437
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/include.shtml
@@ -0,0 +1,33 @@
+<HTML>
+<HEAD>
+<TITLE>/include.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/include.shtml</H1>
+
+<P>Include /misc/friedrich.html:
+<!--#include virtual="/misc/friedrich.html"-->
+
+<P>Include /misc/not_defined.html:
+<!--#include virtual="/misc/not_defined.html"-->
+
+<P>Include misc/friedrich.html:
+<!--#include file="misc/friedrich.html"-->
+
+<P>Include not_defined.html:
+<!--#include file="not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/index.html b/lib/inets/test/httpd_test_data/server_root/htdocs/index.html
new file mode 100644
index 0000000000..cfdc9f9ab7
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/index.html
@@ -0,0 +1,25 @@
+<HTML>
+<HEAD>
+<TITLE>/index.html</TITLE>
+</HEAD>
+<BODY>
+<H1>/index.html</H1>
+
+<STRONG>Server-Side Include (SSI) commands:</STRONG><BR>
+<A HREF="config.shtml">config</A><BR>
+<A HREF="echo.shtml">echo</A><BR>
+<A HREF="exec.shtml">exec</A><BR>
+<A HREF="flastmod.shtml">flastmod</A><BR>
+<A HREF="fsize.shtml">fsize</A><BR>
+<A HREF="include.shtml">include</A><BR>
+
+<BR>
+<BR>
+
+<STRONG>ESI callback:</STRING><BR>
+<A HREF="cgi-bin/erl/httpd_example/get">cgi-bin/erl/httpd_example/get</A><BR>
+<A HREF="cgi-bin/erl/httpd_example/yahoo">cgi-bin/erl/httpd_example/yahoo</A><BR>
+<A HREF="cgi-bin/erl/httpd_example/test1">cgi-bin/erl/httpd_example/test1</A><BR>
+
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/last_modified.html b/lib/inets/test/httpd_test_data/server_root/htdocs/last_modified.html
new file mode 100644
index 0000000000..65c1790813
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/last_modified.html
@@ -0,0 +1,22 @@
+<HTML>
+<HEAD>
+<TITLE>/last_modified.html</TITLE>
+</HEAD>
+<BODY>
+<H1>/last_modified.html</H1>
+
+<P>This document is only used for test of illegal last-modified date.</P>
+
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/misc/friedrich.html b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/friedrich.html
new file mode 100644
index 0000000000..d7953d5df4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/friedrich.html
@@ -0,0 +1,7 @@
+<P><CITE>
+Talking much about oneself can also be a means to conceal oneself.<BR>
+-- Friedrich Nietzsche
+</CITE>
+
+<P>Nested Include:
+<!--#include file="misc/oech.html"-->
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/misc/oech.html b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/oech.html
new file mode 100644
index 0000000000..506064bf04
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/oech.html
@@ -0,0 +1,4 @@
+<P><CITE>
+What excuses stand in your way? How can you eliminate them?<BR>
+-- Roger von Oech
+</CITE>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/misc/welcome.html b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/welcome.html
new file mode 100644
index 0000000000..8c17451f91
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/welcome.html
@@ -0,0 +1 @@
+<HTML></HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_open/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/top_secret/index.html b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/top_secret/index.html
new file mode 100644
index 0000000000..2d17e8b596
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/mnesia_secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/mnesia_secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/open/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/secret/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/secret/top_secret/index.html b/lib/inets/test/httpd_test_data/server_root/htdocs/secret/top_secret/index.html
new file mode 100644
index 0000000000..34db3d5d1a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/README b/lib/inets/test/httpd_test_data/server_root/icons/README
new file mode 100644
index 0000000000..a1fc5a5a9c
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/README
@@ -0,0 +1,161 @@
+Public Domain Icons
+
+ These icons were originally made for Mosaic for X and have been
+ included in the NCSA httpd and Apache server distributions in the
+ past. They are in the public domain and may be freely included in any
+ application. The originals were done by Kevin Hughes ([email protected]).
+
+ Many thanks to Andy Polyakov for tuning the icon colors and adding a
+ few new images. If you'd like to contribute additions or ideas to
+ this set, please let me know.
+
+ The distribution site for these icons is at:
+
+ http://www.eit.com/goodies/www.icons/
+
+ Kevin Hughes
+ September 11, 1995
+
+
+Suggested Uses
+
+The following are a few suggestions, to serve as a starting point for ideas.
+Please feel free to tweak and rename the icons as you like.
+
+ a.gif
+ This might be used to represent PostScript or text layout
+ languages.
+
+ alert.black.gif, alert.red.gif
+ These can be used to highlight any important items, such as a
+ README file in a directory.
+
+ back.gif, forward.gif
+ These can be used as links to go to previous and next areas.
+
+ ball.gray.gif, ball.red.gif
+ These might be used as bullets.
+
+ binary.gif
+ This can be used to represent binary files.
+
+ binhex.gif
+ This can represent BinHex-encoded data.
+
+ blank.gif
+ This can be used as a placeholder or a spacing element.
+
+ bomb.gif
+ This can be used to repreesnt core files.
+
+ box1.gif, box2.gif
+ These icons can be used to represent generic 3D applications and
+ related files.
+
+ broken.gif
+ This can represent corrupted data.
+
+ burst.gif
+ This can call attention to new and important items.
+
+ c.gif
+ This might represent C source code.
+
+ comp.blue.gif, comp.red.gif
+ These little computer icons can stand for telnet or FTP
+ sessions.
+
+ compressed.gif
+ This may represent compressed data.
+
+ continued.gif
+ This can be a link to a continued listing of a directory.
+
+ down.gif, up.gif, left.gif, right.gif
+ These can be used to scroll up, down, left and right in a
+ listing or may be used to denote items in an outline.
+
+ dvi.gif
+ This can represent DVI files.
+
+ f.gif
+ This might represent FORTRAN or Forth source code.
+
+ folder.gif, folder.open.gif, folder.sec.gif
+ The folder can represent directories. There is also a version
+ that can represent secure directories or directories that cannot
+ be viewed.
+
+ generic.gif, generic.sec.gif, generic.red.gif
+ These can represent generic files, secure files, and important
+ files, respectively.
+
+ hand.right.gif, hand.up.gif
+ These can point out important items (pun intended).
+
+ image1.gif, image2.gif, image3.gif
+ These can represent image formats of various types.
+
+ index.gif
+ This might represent a WAIS index or search facility.
+
+ layout.gif
+ This might represent files and formats that contain graphics as
+ well as text layout, such as HTML and PDF files.
+
+ link.gif
+ This might represent files that are symbolic links.
+
+ movie.gif
+ This can represent various movie formats.
+
+ p.gif
+ This may stand for Perl or Python source code.
+
+ pie0.gif ... pie8.gif
+ These icons can be used in applications where a list of
+ documents is returned from a search. The little pie chart images
+ can denote how relevant the documents may be to your search
+ query.
+
+ patch.gif
+ This may stand for patches and diff files.
+
+ portal.gif
+ This might be a link to an online service or a 3D world.
+
+ ps.gif, quill.gif
+ These may represent PostScript files.
+
+ screw1.gif, screw2.gif
+ These may represent CAD or engineering data and formats.
+
+ script.gif
+ This can represent any of various interpreted languages, such as
+ Perl, python, TCL, and shell scripts, as well as server
+ configuration files.
+
+ sound1.gif, sound2.gif
+ These can represent sound files.
+
+ sphere1.gif, sphere2.gif
+ These can represent 3D worlds or rendering applications and
+ formats.
+
+ tex.gif
+ This can represent TeX files.
+
+ text.gif
+ This can represent generic (plain) text files.
+
+ transfer.gif
+ This can represent FTP transfers or uploads/downloads.
+
+ unknown.gif
+ This may represent a file of an unknown type.
+
+ uuencoded.gif
+ This can stand for uuencoded data.
+
+ world1.gif, world2.gif
+ These can represent 3D worlds or other 3D formats.
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/a.gif b/lib/inets/test/httpd_test_data/server_root/icons/a.gif
new file mode 100644
index 0000000000..bb23d971f4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/a.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/alert.black.gif b/lib/inets/test/httpd_test_data/server_root/icons/alert.black.gif
new file mode 100644
index 0000000000..eaecd2172a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/alert.black.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/alert.red.gif b/lib/inets/test/httpd_test_data/server_root/icons/alert.red.gif
new file mode 100644
index 0000000000..a423894043
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/alert.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/apache_pb.gif b/lib/inets/test/httpd_test_data/server_root/icons/apache_pb.gif
new file mode 100644
index 0000000000..3a1c139fc4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/apache_pb.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/back.gif b/lib/inets/test/httpd_test_data/server_root/icons/back.gif
new file mode 100644
index 0000000000..a694ae1ec3
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/back.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/ball.gray.gif b/lib/inets/test/httpd_test_data/server_root/icons/ball.gray.gif
new file mode 100644
index 0000000000..eb84268c4c
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/ball.gray.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/ball.red.gif b/lib/inets/test/httpd_test_data/server_root/icons/ball.red.gif
new file mode 100644
index 0000000000..a8425cb574
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/ball.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/binary.gif b/lib/inets/test/httpd_test_data/server_root/icons/binary.gif
new file mode 100644
index 0000000000..9a15cbae04
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/binary.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/binhex.gif b/lib/inets/test/httpd_test_data/server_root/icons/binhex.gif
new file mode 100644
index 0000000000..62d0363108
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/binhex.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/blank.gif b/lib/inets/test/httpd_test_data/server_root/icons/blank.gif
new file mode 100644
index 0000000000..0ccf01e198
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/blank.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/bomb.gif b/lib/inets/test/httpd_test_data/server_root/icons/bomb.gif
new file mode 100644
index 0000000000..270fdb1c06
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/bomb.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/box1.gif b/lib/inets/test/httpd_test_data/server_root/icons/box1.gif
new file mode 100644
index 0000000000..65dcd002ea
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/box1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/box2.gif b/lib/inets/test/httpd_test_data/server_root/icons/box2.gif
new file mode 100644
index 0000000000..c43bc4faec
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/box2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/broken.gif b/lib/inets/test/httpd_test_data/server_root/icons/broken.gif
new file mode 100644
index 0000000000..9f8cbe9f76
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/broken.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/burst.gif b/lib/inets/test/httpd_test_data/server_root/icons/burst.gif
new file mode 100644
index 0000000000..fbdcf575f7
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/burst.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button1.gif b/lib/inets/test/httpd_test_data/server_root/icons/button1.gif
new file mode 100644
index 0000000000..eb97cb7333
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button10.gif b/lib/inets/test/httpd_test_data/server_root/icons/button10.gif
new file mode 100644
index 0000000000..fe0c97998c
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button10.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button2.gif b/lib/inets/test/httpd_test_data/server_root/icons/button2.gif
new file mode 100644
index 0000000000..7698455bf9
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button3.gif b/lib/inets/test/httpd_test_data/server_root/icons/button3.gif
new file mode 100644
index 0000000000..a8b8319232
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button4.gif b/lib/inets/test/httpd_test_data/server_root/icons/button4.gif
new file mode 100644
index 0000000000..0fd15a0d7f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button4.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button5.gif b/lib/inets/test/httpd_test_data/server_root/icons/button5.gif
new file mode 100644
index 0000000000..64241e5c5d
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button5.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button6.gif b/lib/inets/test/httpd_test_data/server_root/icons/button6.gif
new file mode 100644
index 0000000000..867cfd1212
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button6.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button7.gif b/lib/inets/test/httpd_test_data/server_root/icons/button7.gif
new file mode 100644
index 0000000000..b3f5fb248f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button7.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button8.gif b/lib/inets/test/httpd_test_data/server_root/icons/button8.gif
new file mode 100644
index 0000000000..7a308be8f6
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button8.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button9.gif b/lib/inets/test/httpd_test_data/server_root/icons/button9.gif
new file mode 100644
index 0000000000..9acba576c0
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button9.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/buttonl.gif b/lib/inets/test/httpd_test_data/server_root/icons/buttonl.gif
new file mode 100644
index 0000000000..3883088e7a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/buttonl.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/buttonr.gif b/lib/inets/test/httpd_test_data/server_root/icons/buttonr.gif
new file mode 100644
index 0000000000..c4dc3887db
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/buttonr.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/c.gif b/lib/inets/test/httpd_test_data/server_root/icons/c.gif
new file mode 100644
index 0000000000..7555b6c164
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/c.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/comp.blue.gif b/lib/inets/test/httpd_test_data/server_root/icons/comp.blue.gif
new file mode 100644
index 0000000000..f8d76a8c23
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/comp.blue.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/comp.gray.gif b/lib/inets/test/httpd_test_data/server_root/icons/comp.gray.gif
new file mode 100644
index 0000000000..7664cd0364
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/comp.gray.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/compressed.gif b/lib/inets/test/httpd_test_data/server_root/icons/compressed.gif
new file mode 100644
index 0000000000..39e732739f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/compressed.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/continued.gif b/lib/inets/test/httpd_test_data/server_root/icons/continued.gif
new file mode 100644
index 0000000000..b0ffb7e0cc
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/continued.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/dir.gif b/lib/inets/test/httpd_test_data/server_root/icons/dir.gif
new file mode 100644
index 0000000000..48264601ae
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/dir.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/down.gif b/lib/inets/test/httpd_test_data/server_root/icons/down.gif
new file mode 100644
index 0000000000..a354c871cd
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/down.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/dvi.gif b/lib/inets/test/httpd_test_data/server_root/icons/dvi.gif
new file mode 100644
index 0000000000..791be33105
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/dvi.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/f.gif b/lib/inets/test/httpd_test_data/server_root/icons/f.gif
new file mode 100644
index 0000000000..fbe353c282
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/f.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/folder.gif b/lib/inets/test/httpd_test_data/server_root/icons/folder.gif
new file mode 100644
index 0000000000..48264601ae
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/folder.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/folder.open.gif b/lib/inets/test/httpd_test_data/server_root/icons/folder.open.gif
new file mode 100644
index 0000000000..30979cb528
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/folder.open.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/folder.sec.gif b/lib/inets/test/httpd_test_data/server_root/icons/folder.sec.gif
new file mode 100644
index 0000000000..75332d9e59
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/folder.sec.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/forward.gif b/lib/inets/test/httpd_test_data/server_root/icons/forward.gif
new file mode 100644
index 0000000000..b2959b4c85
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/forward.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/generic.gif b/lib/inets/test/httpd_test_data/server_root/icons/generic.gif
new file mode 100644
index 0000000000..de60b2940f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/generic.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/generic.red.gif b/lib/inets/test/httpd_test_data/server_root/icons/generic.red.gif
new file mode 100644
index 0000000000..94743981d9
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/generic.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/generic.sec.gif b/lib/inets/test/httpd_test_data/server_root/icons/generic.sec.gif
new file mode 100644
index 0000000000..88d5240c3c
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/generic.sec.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/hand.right.gif b/lib/inets/test/httpd_test_data/server_root/icons/hand.right.gif
new file mode 100644
index 0000000000..5cdbc7206d
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/hand.right.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/hand.up.gif b/lib/inets/test/httpd_test_data/server_root/icons/hand.up.gif
new file mode 100644
index 0000000000..85a5d68317
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/hand.up.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/htdig.gif b/lib/inets/test/httpd_test_data/server_root/icons/htdig.gif
new file mode 100644
index 0000000000..35443fb63a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/htdig.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/icon.sheet.gif b/lib/inets/test/httpd_test_data/server_root/icons/icon.sheet.gif
new file mode 100644
index 0000000000..ad1686e448
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/icon.sheet.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/image1.gif b/lib/inets/test/httpd_test_data/server_root/icons/image1.gif
new file mode 100644
index 0000000000..01e442bfa9
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/image1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/image2.gif b/lib/inets/test/httpd_test_data/server_root/icons/image2.gif
new file mode 100644
index 0000000000..751faeea36
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/image2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/image3.gif b/lib/inets/test/httpd_test_data/server_root/icons/image3.gif
new file mode 100644
index 0000000000..4f30484ff6
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/image3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/index.gif b/lib/inets/test/httpd_test_data/server_root/icons/index.gif
new file mode 100644
index 0000000000..162478fb3a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/index.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/layout.gif b/lib/inets/test/httpd_test_data/server_root/icons/layout.gif
new file mode 100644
index 0000000000..c96338a152
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/layout.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/left.gif b/lib/inets/test/httpd_test_data/server_root/icons/left.gif
new file mode 100644
index 0000000000..279e6710d4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/left.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/link.gif b/lib/inets/test/httpd_test_data/server_root/icons/link.gif
new file mode 100644
index 0000000000..c5b6889a76
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/link.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/movie.gif b/lib/inets/test/httpd_test_data/server_root/icons/movie.gif
new file mode 100644
index 0000000000..0035183774
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/movie.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/p.gif b/lib/inets/test/httpd_test_data/server_root/icons/p.gif
new file mode 100644
index 0000000000..7b917b4e91
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/p.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/patch.gif b/lib/inets/test/httpd_test_data/server_root/icons/patch.gif
new file mode 100644
index 0000000000..39bc90e795
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/patch.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pdf.gif b/lib/inets/test/httpd_test_data/server_root/icons/pdf.gif
new file mode 100644
index 0000000000..c88fd777c4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pdf.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie0.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie0.gif
new file mode 100644
index 0000000000..6f7a0ae7a7
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie0.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie1.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie1.gif
new file mode 100644
index 0000000000..03aa6be71e
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie2.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie2.gif
new file mode 100644
index 0000000000..b04c5e0908
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie3.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie3.gif
new file mode 100644
index 0000000000..4db9d023ed
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie4.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie4.gif
new file mode 100644
index 0000000000..93471fdd88
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie4.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie5.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie5.gif
new file mode 100644
index 0000000000..57aee93f07
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie5.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie6.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie6.gif
new file mode 100644
index 0000000000..0dc327b569
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie6.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie7.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie7.gif
new file mode 100644
index 0000000000..8661337f06
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie7.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie8.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie8.gif
new file mode 100644
index 0000000000..59ddb34ce0
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie8.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/portal.gif b/lib/inets/test/httpd_test_data/server_root/icons/portal.gif
new file mode 100644
index 0000000000..0e6e506e00
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/portal.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/poweredby.gif b/lib/inets/test/httpd_test_data/server_root/icons/poweredby.gif
new file mode 100644
index 0000000000..d324ab80ea
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/poweredby.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/ps.gif b/lib/inets/test/httpd_test_data/server_root/icons/ps.gif
new file mode 100644
index 0000000000..0f565bc1db
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/ps.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/quill.gif b/lib/inets/test/httpd_test_data/server_root/icons/quill.gif
new file mode 100644
index 0000000000..818a5cdc7e
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/quill.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/right.gif b/lib/inets/test/httpd_test_data/server_root/icons/right.gif
new file mode 100644
index 0000000000..b256e5f75f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/right.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/screw1.gif b/lib/inets/test/httpd_test_data/server_root/icons/screw1.gif
new file mode 100644
index 0000000000..af6ba2b097
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/screw1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/screw2.gif b/lib/inets/test/httpd_test_data/server_root/icons/screw2.gif
new file mode 100644
index 0000000000..06dccb3e44
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/screw2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/script.gif b/lib/inets/test/httpd_test_data/server_root/icons/script.gif
new file mode 100644
index 0000000000..d8a853bc58
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/script.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/sound1.gif b/lib/inets/test/httpd_test_data/server_root/icons/sound1.gif
new file mode 100644
index 0000000000..8efb49f55d
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/sound1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/sound2.gif b/lib/inets/test/httpd_test_data/server_root/icons/sound2.gif
new file mode 100644
index 0000000000..48e6a7fb2f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/sound2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/sphere1.gif b/lib/inets/test/httpd_test_data/server_root/icons/sphere1.gif
new file mode 100644
index 0000000000..7067070da2
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/sphere1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/sphere2.gif b/lib/inets/test/httpd_test_data/server_root/icons/sphere2.gif
new file mode 100644
index 0000000000..a9e462a377
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/sphere2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/star.gif b/lib/inets/test/httpd_test_data/server_root/icons/star.gif
new file mode 100644
index 0000000000..4cfe0a5e0f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/star.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/star_blank.gif b/lib/inets/test/httpd_test_data/server_root/icons/star_blank.gif
new file mode 100644
index 0000000000..a0c83cb85b
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/star_blank.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/tar.gif b/lib/inets/test/httpd_test_data/server_root/icons/tar.gif
new file mode 100644
index 0000000000..617e779efa
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/tar.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/tex.gif b/lib/inets/test/httpd_test_data/server_root/icons/tex.gif
new file mode 100644
index 0000000000..45e43233b8
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/tex.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/text.gif b/lib/inets/test/httpd_test_data/server_root/icons/text.gif
new file mode 100644
index 0000000000..4c623909fb
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/text.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/transfer.gif b/lib/inets/test/httpd_test_data/server_root/icons/transfer.gif
new file mode 100644
index 0000000000..33697dbb66
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/transfer.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/unknown.gif b/lib/inets/test/httpd_test_data/server_root/icons/unknown.gif
new file mode 100644
index 0000000000..32b1ea23fb
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/unknown.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/up.gif b/lib/inets/test/httpd_test_data/server_root/icons/up.gif
new file mode 100644
index 0000000000..6d6d6d1ebf
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/up.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/uu.gif b/lib/inets/test/httpd_test_data/server_root/icons/uu.gif
new file mode 100644
index 0000000000..4387d529f6
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/uu.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/uuencoded.gif b/lib/inets/test/httpd_test_data/server_root/icons/uuencoded.gif
new file mode 100644
index 0000000000..4387d529f6
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/uuencoded.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/world1.gif b/lib/inets/test/httpd_test_data/server_root/icons/world1.gif
new file mode 100644
index 0000000000..05b4ec2058
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/world1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/world2.gif b/lib/inets/test/httpd_test_data/server_root/icons/world2.gif
new file mode 100644
index 0000000000..e3203f7a88
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/world2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/logs/Dummy_File_Needed_By_WinZip b/lib/inets/test/httpd_test_data/server_root/logs/Dummy_File_Needed_By_WinZip
new file mode 100644
index 0000000000..8d1c8b69c3
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/logs/Dummy_File_Needed_By_WinZip
@@ -0,0 +1 @@
+
diff --git a/lib/inets/test/httpd_test_data/server_root/ssl/ssl_client.pem b/lib/inets/test/httpd_test_data/server_root/ssl/ssl_client.pem
new file mode 100644
index 0000000000..8221139eb4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/ssl/ssl_client.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAL6Ym/bgUvhhnPkw08sggGg8Tnp759ThGMEjkmDzhuJ3w3PfnF65
+mgHcgunku4G6LxAQfEUougJWf9Phmjj3oRUCAwEAAQJBAKMjvVvzZxFzfAlP4flc
+OI0AEayFokp04dtvtzuFN09f+aBo2dP18xHmKLCZvxrBOaRAROoQYscALiIVpN07
+GAECIQDfi+sSfAFaDlT3vzpL3xE5UEH6IzY8jWpaZfM1QaToJQIhANpEF50H4wGO
+8Sbh7dUutNd+s+NYUjsMySW2DjLKMsoxAiEAzzb2ftrdsempD0F+O0gZwiPIFKLB
+Kp33YLYyHEKuJtUCIDGi+pvDh2R7VWw6RRQOIyI+tjolg83aAoSI+oGiahqBAiEA
+xzmNNajwoaokvWvlaz0na8rhxu45grOvDrflBT9XvSQ=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD
+VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w
+DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG
+9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzNDM2WhcN
+MDMwMjIyMTUzNDM2WjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s
+bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ
+MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA
+ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC+mJv24FL4
+YZz5MNPLIIBoPE56e+fU4RjBI5Jg84bid8Nz35xeuZoB3ILp5LuBui8QEHxFKLoC
+Vn/T4Zo496EVAgMBAAEwDQYJKoZIhvcNAQEEBQADQQBYxQVfTydyZCE0UXvZd7Ei
+josNsAaWJk9fFIJaG9uyXCEfg2dVgoT2eBk3D9DI+7OB+78isM5CVlFbL7hilvP8
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpd_test_data/server_root/ssl/ssl_server.pem b/lib/inets/test/httpd_test_data/server_root/ssl/ssl_server.pem
new file mode 100644
index 0000000000..fe739c15f7
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/ssl/ssl_server.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBAL9Bozj3BIjL5Cy8b3rjMT2kPZRychX4wz9bHoIIiKnKo1xXHYjw
+g3N9zWM1f1ZzMADwVry1uAInA8q09+7hL20CAwEAAQJACwu2ao7RozjrV64WXimK
+6X131P/7GMvCMwGHNIlbozqoOqmZcYrbKaF61l+XuwA2QvTo3ywW1Ivxcyr6TeAr
+PQIhAOX+WXT6yiqqwjt08kjBCJyMgfZtdAO6pc/6pKjNWiZfAiEA1OH1iPW/OQe5
+tlQXpiRVdLyneNsPygPRJc4Bdwu3hbMCIQDbI5pA56QxOzqOREOGJsb5wrciAfAE
+jZbnr72sSN2YqQIgAWFpvzagw9Tp/mWzNY+cwkIK7/yzsIKv04fveH8p9IMCIQCr
+td4IiukeUwXmPSvYM4uCE/+J89wEL9qU8Mlc3gDLXA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD
+VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w
+DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG
+9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzMzQxWhcN
+MDMwMjIyMTUzMzQxWjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s
+bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ
+MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA
+ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC/QaM49wSI
+y+QsvG964zE9pD2UcnIV+MM/Wx6CCIipyqNcVx2I8INzfc1jNX9WczAA8Fa8tbgC
+JwPKtPfu4S9tAgMBAAEwDQYJKoZIhvcNAQEEBQADQQAmXDY1CyJjzvQZX442kkHG
+ic9QFY1UuVfzokzNMwlHYl1Qx9zaodx0cJCrcH5GF9O9LJbhhV77LzoxT1Q5wZp5
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl
new file mode 100644
index 0000000000..6abee5be2c
--- /dev/null
+++ b/lib/inets/test/httpd_test_lib.erl
@@ -0,0 +1,332 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(httpd_test_lib).
+
+-include("inets_test_lib.hrl").
+
+%% Poll functions
+-export([verify_request/6, verify_request/7, is_expect/1]).
+
+-record(state, {request, % string()
+ socket, % socket()
+ status_line, % {Version, StatusCode, ReasonPharse}
+ headers, % #http_response_h{}
+ body, % binary()
+ mfa = {httpc_response, parse, [nolimit, false]},
+ canceled = [], % [RequestId]
+ max_header_size = nolimit, % nolimit | integer()
+ max_body_size = nolimit, % nolimit | integer()
+ print = false
+ }).
+
+%%% Part of http.hrl - Temporary solution %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Response headers
+-record(http_response_h,{
+%%% --- Standard "General" headers
+ 'cache-control',
+ connection,
+ date,
+ pragma,
+ trailer,
+ 'transfer-encoding',
+ upgrade,
+ via,
+ warning,
+%%% --- Standard "Response" headers
+ 'accept-ranges',
+ age,
+ etag,
+ location,
+ 'proxy-authenticate',
+ 'retry-after',
+ server,
+ vary,
+ 'www-authenticate',
+%%% --- Standard "Entity" headers
+ allow,
+ 'content-encoding',
+ 'content-language',
+ 'content-length' = "0",
+ 'content-location',
+ 'content-md5',
+ 'content-range',
+ 'content-type',
+ expires,
+ 'last-modified',
+ other=[] % list() - Key/Value list with other headers
+ }).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%--------------------------------------------------------------------
+%% API
+%%------------------------------------------------------------------
+verify_request(SocketType, Host, Port, Node, RequestStr, Options) ->
+ verify_request(SocketType, Host, Port, Node, RequestStr, Options, 30000).
+verify_request(SocketType, Host, Port, Node, RequestStr, Options, TimeOut) ->
+ {ok, Socket} = inets_test_lib:connect_bin(SocketType, Host, Port),
+ inets_test_lib:send(SocketType, Socket, RequestStr),
+
+ State = case inets_regexp:match(RequestStr, "printenv") of
+ nomatch ->
+ #state{};
+ _ ->
+ #state{print = true}
+ end,
+
+ case request(State#state{request = RequestStr, socket = Socket}, TimeOut) of
+ {error, Reson} ->
+ {error, Reson};
+ NewState ->
+ ValidateResult = validate(RequestStr, NewState, Options,
+ Node, Port),
+ inets_test_lib:close(SocketType, Socket),
+ ValidateResult
+ end.
+
+request(#state{mfa = {Module, Function, Args},
+ request = RequestStr, socket = Socket} = State, TimeOut) ->
+ HeadRequest = lists:sublist(RequestStr, 1, 4),
+ receive
+ {tcp, Socket, Data} ->
+ print(tcp, Data, State),
+ case Module:Function([Data | Args]) of
+ {ok, Parsed} ->
+ handle_http_msg(Parsed, State);
+ {_, whole_body, _} when HeadRequest == "HEAD" ->
+ State#state{body = <<>>};
+ NewMFA ->
+ request(State#state{mfa = NewMFA}, TimeOut)
+ end;
+ {tcp_closed, Socket} when Function == whole_body ->
+ print(tcp, "closed", State),
+ State#state{body = hd(Args)};
+ {tcp_closed, Socket} ->
+ test_server:fail(connection_closed);
+ {tcp_error, Socket, Reason} ->
+ test_server:fail({tcp_error, Reason});
+ {ssl, Socket, Data} ->
+ print(ssl, Data, State),
+ case Module:Function([Data | Args]) of
+ {ok, Parsed} ->
+ handle_http_msg(Parsed, State);
+ {_, whole_body, _} when HeadRequest == "HEAD" ->
+ State#state{body = <<>>};
+ NewMFA ->
+ request(State#state{mfa = NewMFA}, TimeOut)
+ end;
+ {ssl_closed, Socket} when Function == whole_body ->
+ print(ssl, "closed", State),
+ State#state{body = hd(Args)};
+ {ssl_closed, Socket} ->
+ test_server:fail(connection_closed);
+ {ssl_error, Socket, Reason} ->
+ test_server:fail({ssl_error, Reason})
+ after TimeOut ->
+ test_server:fail(connection_timed_out)
+ end.
+
+handle_http_msg({Version, StatusCode, ReasonPharse, Headers, Body},
+ State = #state{request = RequestStr}) ->
+ case is_expect(RequestStr) of
+ true ->
+ State#state{status_line = {Version,
+ StatusCode,
+ ReasonPharse},
+ headers = Headers};
+ false ->
+ handle_http_body(Body,
+ State#state{status_line = {Version,
+ StatusCode,
+ ReasonPharse},
+ headers = Headers})
+ end;
+
+handle_http_msg({ChunkedHeaders, Body},
+ State = #state{headers = Headers}) ->
+ NewHeaders = http_chunk:handle_headers(Headers, ChunkedHeaders),
+ State#state{headers = NewHeaders, body = Body};
+
+handle_http_msg(Body, State) ->
+ State#state{body = Body}.
+
+handle_http_body(<<>>, State = #state{request = "HEAD" ++ _}) ->
+ State#state{body = <<>>};
+
+handle_http_body(Body, State = #state{headers = Headers,
+ max_body_size = MaxBodySize}) ->
+ case Headers#http_response_h.'transfer-encoding' of
+ "chunked" ->
+ case http_chunk:decode(Body, State#state.max_body_size,
+ State#state.max_header_size) of
+ {Module, Function, Args} ->
+ request(State#state{mfa = {Module, Function, Args}},
+ 30000);
+ {ok, {ChunkedHeaders, NewBody}} ->
+ NewHeaders = http_chunk:handle_headers(Headers,
+ ChunkedHeaders),
+ State#state{headers = NewHeaders, body = NewBody}
+ end;
+ _ ->
+ Length =
+ list_to_integer(Headers#http_response_h.'content-length'),
+ case ((Length =< MaxBodySize) or (MaxBodySize == nolimit)) of
+ true ->
+ case httpc_response:whole_body(Body, Length) of
+ {ok, NewBody} ->
+ State#state{body = NewBody};
+ MFA ->
+ request(State#state{mfa = MFA}, 5000)
+ end;
+ false ->
+ test_server:fail(body_too_big)
+ end
+ end.
+
+validate(RequestStr, #state{status_line = {Version, StatusCode, _},
+ headers = Headers,
+ body = Body}, Options, N, P) ->
+
+ %io:format("Status~p: H:~p B:~p~n", [StatusCode, Headers, Body]),
+ check_version(Version, Options),
+ case lists:keysearch(statuscode, 1, Options) of
+ {value, _} ->
+ check_status_code(StatusCode, Options, Options);
+ _ ->
+ ok
+ end,
+ do_validate(http_response:header_list(Headers), Options, N, P),
+ check_body(RequestStr, StatusCode,
+ Headers#http_response_h.'content-type',
+ list_to_integer(Headers#http_response_h.'content-length'),
+ Body).
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%------------------------------------------------------------------
+check_version(Version, Options) ->
+ case lists:keysearch(version, 1, Options) of
+ {value, {version, Version}} ->
+ ok;
+ {value, {version, Ver}} ->
+ test_server:fail({wrong_version, [{got, Version},
+ {expected, Ver}]});
+ _ ->
+ case Version of
+ "HTTP/1.1" ->
+ ok;
+ _ ->
+ test_server:fail({wrong_version, [{got, Version},
+ {expected, "HTTP/1.1"}]})
+ end
+ end.
+
+check_status_code(StatusCode, [], Options) ->
+ test_server:fail({wrong_status_code, [{got, StatusCode},
+ {expected, Options}]});
+check_status_code(StatusCode, Current = [_ | Rest], Options) ->
+ case lists:keysearch(statuscode, 1, Current) of
+ {value, {statuscode, StatusCode}} ->
+ ok;
+ {value, {statuscode, _OtherStatus}} ->
+ check_status_code(StatusCode, Rest, Options);
+ false ->
+ test_server:fail({wrong_status_code, [{got, StatusCode},
+ {expected, Options}]})
+ end.
+
+do_validate(_, [], _, _) ->
+ ok;
+do_validate(Header, [{statuscode, _Code} | Rest], N, P) ->
+ do_validate(Header, Rest, N, P);
+do_validate(Header, [{header, HeaderField}|Rest], N, P) ->
+ LowerHeaderField = http_util:to_lower(HeaderField),
+ case lists:keysearch(LowerHeaderField, 1, Header) of
+ {value, {LowerHeaderField, _Value}} ->
+ ok;
+ false ->
+ test_server:fail({missing_header_field, LowerHeaderField, Header});
+ _ ->
+ test_server:fail({missing_header_field, LowerHeaderField, Header})
+ end,
+ do_validate(Header, Rest, N, P);
+do_validate(Header, [{header, HeaderField, Value}|Rest],N,P) ->
+ LowerHeaderField = http_util:to_lower(HeaderField),
+ case lists:keysearch(LowerHeaderField, 1, Header) of
+ {value, {LowerHeaderField, Value}} ->
+ ok;
+ false ->
+ test_server:fail({wrong_header_field_value, LowerHeaderField,
+ Header});
+ _ ->
+ test_server:fail({wrong_header_field_value, LowerHeaderField,
+ Header})
+ end,
+ do_validate(Header, Rest, N, P);
+do_validate(Header,[{no_last_modified,HeaderField}|Rest],N,P) ->
+% io:format("Header: ~p~nHeaderField: ~p~n",[Header,HeaderField]),
+ case lists:keysearch(HeaderField,1,Header) of
+ {value,_} ->
+ test_server:fail({wrong_header_field_value, HeaderField,
+ Header});
+ _ ->
+ ok
+ end,
+ do_validate(Header, Rest, N, P);
+do_validate(Header, [_Unknown | Rest], N, P) ->
+ do_validate(Header, Rest, N, P).
+
+is_expect(RequestStr) ->
+
+ case inets_regexp:match(RequestStr, "xpect:100-continue") of
+ {match, _, _}->
+ true;
+ _ ->
+ false
+ end.
+
+%% OTP-5775, content-length
+check_body("GET /cgi-bin/erl/httpd_example:get_bin HTTP/1.0\r\n\r\n", 200, "text/html", Length, _Body) when Length /= 274->
+ test_server:fail(content_length_error);
+check_body("GET /cgi-bin/cgi_echo HTTP/1.0\r\n\r\n", 200, "text/plain",
+ _, Body) ->
+ case size(Body) of
+ 100 ->
+ ok;
+ _ ->
+ test_server:fail(content_length_error)
+ end;
+
+check_body(RequestStr, 200, "text/html", _, Body) ->
+ HeadRequest = lists:sublist(RequestStr, 1, 3),
+ case HeadRequest of
+ "GET" ->
+ inets_test_lib:check_body(binary_to_list(Body));
+ _ ->
+ ok
+ end;
+
+check_body(_, _, _, _,_) ->
+ ok.
+
+print(Proto, Data, #state{print = true}) ->
+ test_server:format("Received ~p: ~p~n", [Proto, Data]);
+print(_, _, #state{print = false}) ->
+ ok.
+
diff --git a/lib/inets/test/httpd_time_test.erl b/lib/inets/test/httpd_time_test.erl
new file mode 100644
index 0000000000..7d6aa08542
--- /dev/null
+++ b/lib/inets/test/httpd_time_test.erl
@@ -0,0 +1,500 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(httpd_time_test).
+
+-export([t/3, t1/2, t2/2]).
+
+-export([do/1, do/2, do/3, do/4, do/5]).
+
+-export([main/5, poller_main/4, poller_loop/4]).
+
+-include("inets_test_lib.hrl").
+
+-record(stat, {pid, time = undefined, count = undefined, res}).
+
+
+%%% -----------------------------------------------------------------
+%%% Test suite interface
+%%%
+
+t1(Host, Port) ->
+ t(ip_comm, Host, Port).
+
+
+t2(Host, Port) ->
+ t(ssl, Host, Port).
+
+
+t(SocketType, Host, Port) ->
+ %% put(dbg,true),
+ main(1, SocketType, Host, Port, 60000).
+
+
+
+%%% -----------------------------------------------------------------
+%%% Public interface when running the time test manually...
+%%%
+
+do(Port) ->
+ do(ip_comm, hostname(), Port).
+
+do(Port, Time) when is_integer(Port) andalso is_integer(Time) ->
+ do(ip_comm, hostname(), Port, Time);
+
+do(Host, Port) ->
+ do(ip_comm, Host, Port).
+
+do(Host, Port, Time) when is_integer(Port) andalso is_integer(Time) ->
+ do(1, ip_comm, Host, Port, Time);
+
+do(SocketType, Host, Port) when is_integer(Port) ->
+ do(1, SocketType, Host, Port, 60000).
+
+do(N, SocketType, Host, Port) when is_integer(N) andalso is_integer(Port) ->
+ do(N, SocketType, Host, Port, 60000);
+
+do(SocketType, Host, Port, Time)
+ when is_integer(Port) andalso is_integer(Time) ->
+ do(1, SocketType, Host, Port, Time).
+
+do(N, SocketType, Host, Port, Time)
+ when is_integer(N) andalso is_integer(Port) andalso is_integer(Time) ->
+ do_it(N, SocketType, Host, Port, Time).
+
+do_it(N, SocketType, Host, Port, Time) ->
+ d("do_it -> entry with"
+ "~n N: ~p"
+ "~n SocketType: ~p"
+ "~n Host: ~p"
+ "~n Port: ~p"
+ "~n Time: ~p", [N, SocketType, Host, Port, Time]),
+ proc_lib:spawn(?MODULE, main, [N, SocketType, Host, Port, Time]).
+
+
+
+%%% -----------------------------------------------------------------
+%%% Controller (main) process
+%%%
+
+main(N, SocketType, Host, Port, Time)
+ when is_integer(N) andalso
+ is_atom(SocketType) andalso
+ is_integer(Port) andalso
+ is_integer(Time) ->
+ process_flag(trap_exit,true),
+ put(sname,ctrl),
+ %% put(dbg,true),
+ d("main -> entry"),
+ Pollers = start_pollers(N, [self(), SocketType, Host, Port]),
+ d("main -> Pollers: ~p", [Pollers]),
+ loop(Pollers, Time).
+
+loop(Pollers, Timeout) ->
+ d("loop -> entry when"
+ "~n Timeout: ~p", [Timeout]),
+ Start = t(),
+ receive
+ {'EXIT', Pid, {poller_stat_failure, Time, Reason}} ->
+ case is_poller(Pid, Pollers) of
+ true ->
+ error_msg("received unexpected exit from poller ~p~n"
+ "befor completion of test "
+ "(after ~p micro sec):~n"
+ "~p~n", [Pid,Time,Reason]),
+ exit({fail, {poller_exit, Pid, Reason}});
+ false ->
+ error_msg("received unexpected ~p from ~p"
+ "befor completion of test", [Reason, Pid]),
+ loop(Pollers, to(Timeout, Start))
+ end;
+
+ {poller_stat_failure, Pid, {Time, Reason}} ->
+ error_msg("received stat failure ~p from poller ~p after ~p "
+ "befor completion of test", [Reason, Pid, Time]),
+ exit({fail, {poller_failure, Pid, Reason}});
+
+ {poller_stat_failure, Pid, Reason} ->
+ error_msg("received stat failure ~p from poller ~p "
+ "befor completion of test", [Reason, Pid]),
+ exit({fail, {poller_failure, Pid, Reason}});
+
+ Any ->
+ error_msg("received unexpected message befor completion of test: "
+ "~n ~p", [Any]),
+ exit({fail, Any})
+
+ after Timeout ->
+ d("loop -> timeout: stop pollers"),
+ stop_pollers(Pollers),
+ d("loop -> collect poller statistics"),
+ Stats = collect_poller_stat(Pollers, []),
+ d("loop -> Stats: ~p", [Stats]),
+ display_poller_stat(Stats, Timeout),
+ ok
+ end.
+
+collect_poller_stat([], PollersStat) ->
+ PollersStat;
+collect_poller_stat(Pollers, PollersStat) ->
+ d("collect_poller_stat -> entry with"
+ "~n Pollers: ~p"
+ "~n PollersStat: ~p", [Pollers, PollersStat]),
+ receive
+ {poller_statistics, Poller, {Time, Count}} ->
+ d("collect_poller_stat -> got statistics from ~p", [Poller]),
+ case lists:keysearch(Poller, 2, Pollers) of
+ {value, PollerStat} ->
+ d("collect_poller_stat -> current statistic record: ~p",
+ [PollerStat]),
+ P = lists:keydelete(Poller, 2, Pollers),
+ d("collect_poller_stat -> P: ~p", [P]),
+ S = PollerStat#stat{time = Time, count = Count, res = ok},
+ d("collect_poller_stat -> S: ~p", [S]),
+ collect_poller_stat(P, [S | PollersStat]);
+ false ->
+ error_msg("statistics already received for ~p", [Poller]),
+ collect_poller_stat(Pollers, PollersStat)
+ end;
+ {poller_stat_failure, Poller, Else} ->
+ error_msg("poller statistics failure for ~p with ~p",
+ [Poller, Else]),
+ case lists:keysearch(Poller, 2, Pollers) of
+ {value, PollerStat} ->
+ P = lists:keydelete(Poller, 2, Pollers),
+ S = PollerStat#stat{res = {error, Else}},
+ collect_poller_stat(P, [S | PollerStat]);
+ false ->
+ error_msg("statistics already received for ~p", [Poller]),
+ collect_poller_stat(Pollers, PollersStat)
+ end
+ end.
+
+
+display_poller_stat(Stats, T) ->
+ display_poller_stat(Stats, 1, T, 0).
+
+display_poller_stat([], _, TestTime, AccCount) ->
+ io:format("Total statistics:~n"
+ " Accumulated count: ~w~n"
+ " Average access time: ~w milli sec~n",
+ [AccCount, (TestTime/AccCount)]);
+display_poller_stat([#stat{res = ok} = Stat | Stats], N, TestTime, AccCount) ->
+ #stat{pid = Pid, time = Time, count = Count} = Stat,
+ io:format("Statistics for poller ~p (~p):~n"
+ " time: ~w seconds~n"
+ " count: ~w~n"
+ " Average access time: ~w milli sec~n",
+ [Pid, N, Time/(1000*1000), Count, (TestTime/Count)]),
+ display_poller_stat(Stats, N + 1, TestTime, AccCount+Count);
+display_poller_stat([Stat | Stats], N, TestTime, AccCount) ->
+ #stat{pid = Pid, res = Error} = Stat,
+ io:format("Statistics failed for poller ~p (~p):~n"
+ " ~p~n", [Pid, N, Error]),
+ display_poller_stat(Stats, N + 1, TestTime, AccCount).
+
+
+
+%%% -----------------------------------------------------------------
+%%% Poller process
+%%%
+
+start_pollers(N, Args) ->
+ start_pollers(N, Args, []).
+
+start_pollers(0, _Args, Pollers) ->
+ Pollers;
+start_pollers(N, Args, Pollers) ->
+ Pid = proc_lib:spawn_link(?MODULE, poller_main, Args),
+ start_pollers(N-1, Args, [#stat{pid = Pid} | Pollers]).
+
+stop_pollers(Pollers) ->
+ [Pid ! stop || #stat{pid = Pid} <- Pollers],
+ await_stop_pollers(Pollers).
+
+await_stop_pollers([]) ->
+ ok;
+await_stop_pollers(Pollers0) ->
+ receive
+ {'EXIT', Pid, _Reason} ->
+ Pollers = lists:keydelete(Pid, 2, Pollers0),
+ await_stop_pollers(Pollers)
+ after 5000 ->
+ [Pid ! shutdown || #stat{pid = Pid} <- Pollers0]
+ end.
+
+
+is_poller(_, []) ->
+ false;
+is_poller(Pid, [#stat{pid = Pid}|_]) ->
+ true;
+is_poller(Pid, [_|Rest]) ->
+ is_poller(Pid, Rest).
+
+
+poller_main(Parent, SocketType, Host, Port) ->
+ process_flag(trap_exit,true),
+ put(sname,poller),
+ case timer:tc(?MODULE, poller_loop, [SocketType, Host, Port, uris()]) of
+ {Time, Count} when is_integer(Time) andalso is_integer(Count) ->
+ Parent ! {poller_statistics, self(), {Time, Count}};
+ {Time, {'EXIT', Reason}} when is_integer(Time) ->
+ exit({poller_stat_failure, Time, Reason});
+ {Time, Other} when is_integer(Time) ->
+ Parent ! {poller_stat_failure, self(), {Time, Other}};
+ Else ->
+ Parent ! {poller_stat_failure, self(), Else}
+ end.
+
+
+uris() ->
+ uris(get(uris)).
+
+uris(L) when is_list(L) ->
+ L;
+uris(_) ->
+ ["/",
+ "/index.html"].
+
+
+poller_loop(SocketType, Host, Port, URIs) ->
+ poller_loop(SocketType, Host, Port, URIs, 0).
+
+poller_loop(SocketType, Host, Port, URIs, Count) ->
+ receive
+ stop ->
+ Count
+ after 0 ->
+ case poller_loop1(SocketType, Host, Port, URIs) of
+ done ->
+ poller_loop(SocketType, Host, Port, URIs,
+ Count + length(URIs));
+ {error, Reason, FailURI, FailURIs} ->
+ SuccessCount =
+ Count + (length(URIs) - (length(FailURIs) + 1)),
+ exit({Reason, FailURI, SuccessCount})
+ end
+ end.
+
+
+poller_loop1(_SocketType, _Host, _Port, []) ->
+ done;
+poller_loop1(SocketType, Host, Port, [URI | URIs]) ->
+ Res = inets_test_lib:connect_byte(SocketType, Host, Port),
+ case (catch poll(Res, SocketType, URI, "200")) of
+ ok ->
+ poller_loop1(SocketType, Host, Port, URIs);
+ {'EXIT', Reason} ->
+ {error, Reason, URI, URIs}
+ end.
+
+poll({ok, Socket}, SocketType, URI, ExpRes) ->
+ Req = "GET " ++ URI ++ " HTTP/1.0\r\n\r\n",
+ Res = inets_test_lib:send(SocketType, Socket, Req),
+ await_poll_response(Res, SocketType, Socket, ExpRes);
+poll({error, Reason}, _SocketType, _URI, _ExpRes) ->
+ exit({failed_creating_socket, Reason});
+poll(Error, _SocketType, _URI, _ExpRes) ->
+ exit({failed_creating_socket, Error}).
+
+await_poll_response(ok, SocketType, Socket, ExpStatusCode) ->
+ receive
+ %% SSL receives
+ {ssl, Socket, Data} ->
+ validate(ExpStatusCode, SocketType, Socket, Data);
+ {ssl_closed, Socket} ->
+ exit(connection_closed);
+ {ssl_error, Socket, Error} ->
+ exit({connection_error, Error});
+
+ %% TCP receives
+ {tcp, Socket, Response} ->
+ validate(ExpStatusCode, SocketType, Socket, Response);
+ {tcp_closed, Socket} ->
+ exit(connection_closed);
+ {tcp_error, Socket, Error} ->
+ exit({connection_error, Error})
+
+ after 10000 ->
+ exit(response_timed_out)
+ end;
+await_poll_response(Error, _SocketType, _Socket, _ExpStatusCode) ->
+ exit(Error).
+
+
+validate(ExpStatusCode, SocketType, Socket, Response) ->
+ Sz = sz(Response),
+ trash_the_rest(Socket, Sz),
+ inets_test_lib:close(SocketType, Socket),
+ case inets_regexp:split(Response," ") of
+ {ok,["HTTP/1.0", ExpStatusCode|_]} ->
+ ok;
+ {ok,["HTTP/1.0", StatusCode|_]} ->
+ error_msg("Unexpected status code: ~p (~s). "
+ "Expected status code: ~p (~s)",
+ [StatusCode, status_to_message(StatusCode),
+ ExpStatusCode, status_to_message(ExpStatusCode)]),
+ exit({unexpected_response_code, StatusCode, ExpStatusCode});
+ {ok,["HTTP/1.1", ExpStatusCode|_]} ->
+ ok;
+ {ok,["HTTP/1.1", StatusCode|_]} ->
+ error_msg("Unexpected status code: ~p (~s). "
+ "Expected status code: ~p (~s)",
+ [StatusCode, status_to_message(StatusCode),
+ ExpStatusCode, status_to_message(ExpStatusCode)]),
+ exit({unexpected_response_code, StatusCode, ExpStatusCode})
+ end.
+
+
+trash_the_rest(Socket, N) ->
+ receive
+ {ssl, Socket, Trash} ->
+ trash_the_rest(Socket, add(N,sz(Trash)));
+ {ssl_closed, Socket} ->
+ N;
+ {ssl_error, Socket, Error} ->
+ exit({connection_error, Error});
+
+ {tcp, Socket, Trash} ->
+ trash_the_rest(Socket, add(N,sz(Trash)));
+ {tcp_closed, Socket} ->
+ N;
+ {tcp_error, Socket, Error} ->
+ exit({connection_error, Error})
+
+ after 10000 ->
+ exit({connection_timed_out, N})
+ end.
+
+
+add(N1,N2) when is_integer(N1) andalso is_integer(N2) ->
+ N1 + N2;
+add(N1,_) when is_integer(N1) ->
+ N1;
+add(_,N2) when is_integer(N2) ->
+ N2.
+
+
+sz(L) when is_list(L) ->
+ length(lists:flatten(L));
+sz(B) when is_binary(B) ->
+ size(B);
+sz(O) ->
+ {unknown_size,O}.
+
+
+%% --------------------------------------------------------------
+%%
+%% Status code to printable string
+%%
+
+status_to_message(L) when is_list(L) ->
+ case (catch list_to_integer(L)) of
+ I when is_integer(I) ->
+ status_to_message(I);
+ _ ->
+ io_lib:format("UNKNOWN STATUS CODE: '~p'",[L])
+ end;
+status_to_message(100) -> "Section 10.1.1: Continue";
+status_to_message(101) -> "Section 10.1.2: Switching Protocols";
+status_to_message(200) -> "Section 10.2.1: OK";
+status_to_message(201) -> "Section 10.2.2: Created";
+status_to_message(202) -> "Section 10.2.3: Accepted";
+status_to_message(203) -> "Section 10.2.4: Non-Authoritative Information";
+status_to_message(204) -> "Section 10.2.5: No Content";
+status_to_message(205) -> "Section 10.2.6: Reset Content";
+status_to_message(206) -> "Section 10.2.7: Partial Content";
+status_to_message(300) -> "Section 10.3.1: Multiple Choices";
+status_to_message(301) -> "Section 10.3.2: Moved Permanently";
+status_to_message(302) -> "Section 10.3.3: Found";
+status_to_message(303) -> "Section 10.3.4: See Other";
+status_to_message(304) -> "Section 10.3.5: Not Modified";
+status_to_message(305) -> "Section 10.3.6: Use Proxy";
+status_to_message(307) -> "Section 10.3.8: Temporary Redirect";
+status_to_message(400) -> "Section 10.4.1: Bad Request";
+status_to_message(401) -> "Section 10.4.2: Unauthorized";
+status_to_message(402) -> "Section 10.4.3: Peyment Required";
+status_to_message(403) -> "Section 10.4.4: Forbidden";
+status_to_message(404) -> "Section 10.4.5: Not Found";
+status_to_message(405) -> "Section 10.4.6: Method Not Allowed";
+status_to_message(406) -> "Section 10.4.7: Not Acceptable";
+status_to_message(407) -> "Section 10.4.8: Proxy Authentication Required";
+status_to_message(408) -> "Section 10.4.9: Request Time-Out";
+status_to_message(409) -> "Section 10.4.10: Conflict";
+status_to_message(410) -> "Section 10.4.11: Gone";
+status_to_message(411) -> "Section 10.4.12: Length Required";
+status_to_message(412) -> "Section 10.4.13: Precondition Failed";
+status_to_message(413) -> "Section 10.4.14: Request Entity Too Large";
+status_to_message(414) -> "Section 10.4.15: Request-URI Too Large";
+status_to_message(415) -> "Section 10.4.16: Unsupported Media Type";
+status_to_message(416) -> "Section 10.4.17: Requested range not satisfiable";
+status_to_message(417) -> "Section 10.4.18: Expectation Failed";
+status_to_message(500) -> "Section 10.5.1: Internal Server Error";
+status_to_message(501) -> "Section 10.5.2: Not Implemented";
+status_to_message(502) -> "Section 10.5.3: Bad Gatteway";
+status_to_message(503) -> "Section 10.5.4: Service Unavailable";
+status_to_message(504) -> "Section 10.5.5: Gateway Time-out";
+status_to_message(505) -> "Section 10.5.6: HTTP Version not supported";
+status_to_message(Code) -> io_lib:format("Unknown status code: ~p",[Code]).
+
+%% ----------------------------------------------------------------
+
+to(To, Start) ->
+ To - (t() - Start).
+
+%% Time in milli seconds
+t() ->
+ {A,B,C} = erlang:now(),
+ A*1000000000+B*1000+(C div 1000).
+
+
+%% ----------------------------------------------------------------
+
+
+
+% close(Socket) ->
+% gen_tcp:close(Socket).
+
+% send(Socket, Data) ->
+% gen_tcp:send(Socket, Data).
+
+
+hostname() ->
+ {ok, Hostname} = inet:gethostname(),
+ hostname(Hostname).
+
+hostname(Hostname) when is_list(Hostname) ->
+ list_to_atom(Hostname);
+hostname(Hostname) ->
+ Hostname.
+
+%% ----------------------------------------------------------------
+
+error_msg(F,A) -> error_logger:error_msg(F ++ "~n",A).
+
+d(F) ->
+ d(get(dbg),F,[]).
+
+d(F,A) ->
+ d(get(dbg),F,A).
+
+d(true, F, A) ->
+ io:format("DBG ~p ~p " ++ F ++ "~n", [self(),get(sname)]++A);
+d(_,_,_) ->
+ ok.
diff --git a/lib/inets/test/inets.config b/lib/inets/test/inets.config
new file mode 100644
index 0000000000..6c9077594d
--- /dev/null
+++ b/lib/inets/test/inets.config
@@ -0,0 +1 @@
+[{inets,[{services,[{httpd,"/ldisk/tests/bmk/inets/priv_dir/8099.conf"}]}]}].
diff --git a/lib/inets/test/inets.spec b/lib/inets/test/inets.spec
new file mode 100644
index 0000000000..a9b4524295
--- /dev/null
+++ b/lib/inets/test/inets.spec
@@ -0,0 +1,2 @@
+{topcase, {dir, "../inets_test"}}.
+{hosts, ["tuor"]}.
diff --git a/lib/inets/test/inets.spec.vxworks b/lib/inets/test/inets.spec.vxworks
new file mode 100644
index 0000000000..6886299226
--- /dev/null
+++ b/lib/inets/test/inets.spec.vxworks
@@ -0,0 +1,5 @@
+{topcase, {dir, "../inets_test"}}.
+{skip, {inets_SUITE, ip_mod_cgi, "Requires processes"}}.
+{skip, {inets_SUITE, ip_mod_all_modules, "Requires processes"}}.
+{skip, {inets_SUITE, ssl, "Requires SSL"}}.
+
diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl
new file mode 100644
index 0000000000..56983caace
--- /dev/null
+++ b/lib/inets/test/inets_SUITE.erl
@@ -0,0 +1,583 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(inets_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("inets_test_lib.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(NUM_DEFAULT_SERVICES, 1).
+
+all(doc) ->
+ ["Test suites for the inets application."];
+
+all(suite) ->
+ [
+ app_test,
+ appup_test,
+ services_test,
+ httpd_reload
+ ].
+
+services_test(suite) ->
+ [
+ start_inets,
+ start_httpc,
+ start_httpd,
+ start_ftpc,
+ start_tftpd
+ ].
+
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, Config) -> Config
+% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ inets:stop(),
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(_, Config) ->
+ Config.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+app_test(suite) ->
+ [{inets_app_test, all}].
+
+appup_test(suite) ->
+ [{inets_appup_test, all}].
+
+
+%%-------------------------------------------------------------------------
+
+start_inets(doc) ->
+ ["Test inets API functions"];
+start_inets(suite) ->
+ [];
+start_inets(Config) when is_list(Config) ->
+ [_|_] = inets:service_names(),
+
+ {error,inets_not_started} = inets:services(),
+ {error,inets_not_started} = inets:services_info(),
+
+ ok = inets:start(),
+
+ %% httpc default profile always started
+ [_|_] = inets:services(),
+ [_|_] = inets:services_info(),
+
+ {error,{already_started,inets}} = inets:start(),
+
+ ok = inets:stop(),
+ {error,{not_started,inets}} = inets:stop(),
+
+ ok = inets:start(transient),
+ ok = inets:stop(),
+
+ ok = inets:start(permanent),
+ ok = inets:stop().
+
+
+%%-------------------------------------------------------------------------
+
+start_httpc(doc) ->
+ ["Start/stop of httpc service"];
+start_httpc(suite) ->
+ [];
+start_httpc(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ tsp("start_httpc -> entry with"
+ "~n Config: ~p", [Config]),
+
+ PrivDir = ?config(priv_dir, Config),
+
+ tsp("start_httpc -> start (empty) inets"),
+ ok = inets:start(),
+
+ tsp("start_httpc -> start httpc (as inets service) with profile foo"),
+ {ok, Pid0} = inets:start(httpc, [{profile, foo}]),
+
+ tsp("start_httpc -> check running services"),
+ Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
+ true = lists:member(Pid0, Pids0),
+ [_|_] = inets:services_info(),
+
+ tsp("start_httpc -> stop httpc"),
+ inets:stop(httpc, Pid0),
+
+ tsp("start_httpc -> sleep some"),
+ test_server:sleep(100),
+
+ tsp("start_httpc -> check running services"),
+ Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid0, Pids1),
+
+ tsp("start_httpc -> start httpc (stand-alone) with profile bar"),
+ {ok, Pid1} = inets:start(httpc, [{profile, bar}], stand_alone),
+
+ tsp("start_httpc -> check running services"),
+ Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid1, Pids2),
+
+ tsp("start_httpc -> stop httpc"),
+ ok = inets:stop(stand_alone, Pid1),
+ receive
+ {'EXIT', Pid1, shutdown} ->
+ ok
+ after 100 ->
+ tsf(stand_alone_not_shutdown)
+ end,
+
+ tsp("start_httpc -> stop inets"),
+ ok = inets:stop(),
+
+ tsp("start_httpc -> unload inets"),
+ application:load(inets),
+
+ tsp("start_httpc -> set inets environment (httpc profile foo)"),
+ application:set_env(inets, services, [{httpc,[{profile, foo},
+ {data_dir, PrivDir}]}]),
+
+ tsp("start_httpc -> start inets"),
+ ok = inets:start(),
+
+ tsp("start_httpc -> check running services"),
+ (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+
+ tsp("start_httpc -> unset inets env"),
+ application:unset_env(inets, services),
+
+ tsp("start_httpc -> stop inets"),
+ ok = inets:stop(),
+
+ tsp("start_httpc -> start (empty) inets"),
+ ok = inets:start(),
+
+ tsp("start_httpc -> start inets httpc service with profile foo"),
+ {ok, Pid3} = inets:start(httpc, [{profile, foo}]),
+
+ tsp("start_httpc -> stop inets service httpc with profile foo"),
+ ok = inets:stop(httpc, foo),
+
+ tsp("start_httpc -> check running services"),
+ Pids3 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid3, Pids3),
+
+ tsp("start_httpc -> stop inets"),
+ ok = inets:stop(),
+
+ tsp("start_httpc -> done"),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+start_httpd(doc) ->
+ ["Start/stop of httpd service"];
+start_httpd(suite) ->
+ [];
+start_httpd(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ i("start_httpd -> entry with"
+ "~n Config: ~p", [Config]),
+ PrivDir = ?config(priv_dir, Config),
+ HttpdConf = [{server_name, "httpd_test"}, {server_root, PrivDir},
+ {document_root, PrivDir}, {bind_address, "localhost"}],
+
+ i("start_httpd -> start inets"),
+ ok = inets:start(),
+
+ i("start_httpd -> start httpd service"),
+ {ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
+ Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
+ true = lists:member(Pid0, Pids0),
+ [_|_] = inets:services_info(),
+
+ i("start_httpd -> stop httpd service"),
+ inets:stop(httpd, Pid0),
+ test_server:sleep(500),
+ Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid0, Pids1),
+ i("start_httpd -> start (stand-alone) httpd service"),
+ {ok, Pid1} =
+ inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf],
+ stand_alone),
+ Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid1, Pids2),
+ i("start_httpd -> stop (stand-alone) httpd service"),
+ ok = inets:stop(stand_alone, Pid1),
+ receive
+ {'EXIT', Pid1, shutdown} ->
+ ok
+ after 100 ->
+ test_server:fail(stand_alone_not_shutdown)
+ end,
+ i("start_httpd -> stop inets"),
+ ok = inets:stop(),
+ File0 = filename:join(PrivDir, "httpd.conf"),
+ {ok, Fd0} = file:open(File0, [write]),
+ Str = io_lib:format("~p.~n", [[{port, 0}, {ipfamily, inet} | HttpdConf]]),
+ ok = file:write(Fd0, Str),
+ file:close(Fd0),
+
+ i("start_httpd -> [application] load inets"),
+ application:load(inets),
+ i("start_httpd -> [application] set httpd services env with proplist-file"),
+ application:set_env(inets,
+ services, [{httpd, [{proplist_file, File0}]}]),
+ i("start_httpd -> start inets"),
+ ok = inets:start(),
+ (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+ i("start_httpd -> [application] unset services env"),
+ application:unset_env(inets, services),
+ i("start_httpd -> stop inets"),
+ ok = inets:stop(),
+
+ File1 = filename:join(PrivDir, "httpd_apache.conf"),
+
+ {ok, Fd1} = file:open(File1, [write]),
+ file:write(Fd1, "ServerName httpd_test\r\n"),
+ file:write(Fd1, "ServerRoot " ++ PrivDir ++ "\r\n"),
+ file:write(Fd1, "DocumentRoot " ++ PrivDir ++" \r\n"),
+ file:write(Fd1, "BindAddress *|inet\r\n"),
+ file:write(Fd1, "Port 0\r\n"),
+ file:close(Fd1),
+
+ i("start_httpd -> [application] load inets"),
+ application:load(inets),
+ i("start_httpd -> [application] set httpd services env with file"),
+ application:set_env(inets,
+ services, [{httpd, [{file, File1}]}]),
+ i("start_httpd -> start inets"),
+ ok = inets:start(),
+ (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+ i("start_httpd -> [application] unset services env"),
+ application:unset_env(inets, services),
+ i("start_httpd -> stop inets"),
+ ok = inets:stop(),
+
+ %% OLD format
+ i("start_httpd -> [application] load inets"),
+ application:load(inets),
+ i("start_httpd -> [application] set httpd services OLD env"),
+ application:set_env(inets,
+ services, [{httpd, File1}]),
+ i("start_httpd -> start inets"),
+ ok = inets:start(),
+ (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+ i("start_httpd -> [application] unset services enc"),
+ application:unset_env(inets, services),
+ i("start_httpd -> stop inets"),
+ ok = inets:stop(),
+
+ i("start_httpd -> start inets"),
+ ok = inets:start(),
+ i("start_httpd -> try (and fail) start httpd service - server_name"),
+ {error, {missing_property, server_name}} =
+ inets:start(httpd, [{port, 0},
+ {server_root, PrivDir},
+ {document_root, PrivDir},
+ {bind_address, "localhost"}]),
+ i("start_httpd -> try (and fail) start httpd service - missing document_root"),
+ {error, {missing_property, document_root}} =
+ inets:start(httpd, [{port, 0},
+ {server_name, "httpd_test"},
+ {server_root, PrivDir},
+ {bind_address, "localhost"}]),
+ i("start_httpd -> try (and fail) start httpd service - missing server_root"),
+ {error, {missing_property, server_root}} =
+ inets:start(httpd, [{port, 0},
+ {server_name, "httpd_test"},
+ {document_root, PrivDir},
+ {bind_address, "localhost"}]),
+ i("start_httpd -> try (and fail) start httpd service - missing port"),
+ {error, {missing_property, port}} =
+ inets:start(httpd, HttpdConf),
+ i("start_httpd -> stop inets"),
+ ok = inets:stop(),
+ i("start_httpd -> done"),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+start_ftpc(doc) ->
+ ["Start/stop of ftpc service"];
+start_ftpc(suite) ->
+ [];
+start_ftpc(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ inets:disable_trace(),
+ inets:enable_trace(max, io, ftpc),
+ ok = inets:start(),
+ try
+ begin
+ {_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config),
+ case inets:start(ftpc, [{host, FtpdHost}]) of
+ {ok, Pid0} ->
+ Pids0 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ true = lists:member(Pid0, Pids0),
+ [_|_] = inets:services_info(),
+ inets:stop(ftpc, Pid0),
+ test_server:sleep(100),
+ Pids1 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ false = lists:member(Pid0, Pids1),
+ {ok, Pid1} =
+ inets:start(ftpc, [{host, FtpdHost}], stand_alone),
+ Pids2 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ false = lists:member(Pid1, Pids2),
+ ok = inets:stop(stand_alone, Pid1),
+ receive
+ {'EXIT', Pid1, shutdown} ->
+ ok
+ after 100 ->
+ tsf(stand_alone_not_shutdown)
+ end,
+ ok = inets:stop(),
+ inets:disable_trace(),
+ ok;
+ _ ->
+ inets:disable_trace(),
+ {skip, "Unable to reach selected FTP server " ++ FtpdHost}
+ end
+ end
+ catch
+ throw:{error, not_found} ->
+ inets:disable_trace(),
+ {skip, "No available FTP servers"}
+ end.
+
+
+
+%%-------------------------------------------------------------------------
+
+start_tftpd(doc) ->
+ ["Start/stop of tfpd service"];
+start_tftpd(suite) ->
+ [];
+start_tftpd(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ok = inets:start(),
+ {ok, Pid0} = inets:start(tftpd, [{host, "localhost"}, {port, 0}]),
+ Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
+ true = lists:member(Pid0, Pids0),
+ [_|_] = inets:services_info(),
+ inets:stop(tftpd, Pid0),
+ test_server:sleep(100),
+ Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid0, Pids1),
+ {ok, Pid1} =
+ inets:start(tftpd, [{host, "localhost"}, {port, 0}], stand_alone),
+ Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid1, Pids2),
+ ok = inets:stop(stand_alone, Pid1),
+ receive
+ {'EXIT', Pid1, shutdown} ->
+ ok
+ after 100 ->
+ test_server:fail(stand_alone_not_shutdown)
+ end,
+ ok = inets:stop(),
+ application:load(inets),
+ application:set_env(inets, services, [{tftpd,[{host, "localhost"},
+ {port, 0}]}]),
+ ok = inets:start(),
+ (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+ application:unset_env(inets, services),
+ ok = inets:stop().
+
+
+%%-------------------------------------------------------------------------
+
+httpd_reload(doc) ->
+ ["Reload httpd configuration without restarting service"];
+httpd_reload(suite) ->
+ [];
+httpd_reload(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ i("httpd_reload -> starting"),
+ PrivDir = ?config(priv_dir, Config),
+ DataDir = ?config(data_dir, Config),
+ HttpdConf = [{server_name, "httpd_test"},
+ {server_root, PrivDir},
+ {document_root, PrivDir},
+ {bind_address, "localhost"}],
+
+ inets:enable_trace(max, io),
+
+ i("httpd_reload -> start inets"),
+
+ ok = inets:start(),
+ test_server:sleep(5000),
+ i("httpd_reload -> inets started - start httpd service"),
+
+ {ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
+ test_server:sleep(5000),
+ i("httpd_reload -> httpd service started (~p) - get port", [Pid0]),
+
+ [{port, Port0}] = httpd:info(Pid0, [port]),
+ test_server:sleep(5000),
+ i("httpd_reload -> Port: ~p - get document root", [Port0]),
+
+ [{document_root, PrivDir}] = httpd:info(Pid0, [document_root]),
+ test_server:sleep(5000),
+ i("httpd_reload -> document root: ~p - reload config", [PrivDir]),
+
+ ok = httpd:reload_config([{port, Port0}, {ipfamily, inet},
+ {server_name, "httpd_test"},
+ {server_root, PrivDir},
+ {document_root, DataDir},
+ {bind_address, "localhost"}], non_disturbing),
+ test_server:sleep(5000),
+ io:format("~w:~w:httpd_reload - reloaded - get document root~n", [?MODULE, ?LINE]),
+
+ [{document_root, DataDir}] = httpd:info(Pid0, [document_root]),
+ test_server:sleep(5000),
+ i("httpd_reload -> document root: ~p - reload config", [DataDir]),
+
+ ok = httpd:reload_config([{port, Port0}, {ipfamily, inet},
+ {server_name, "httpd_test"},
+ {server_root, PrivDir},
+ {document_root, PrivDir},
+ {bind_address, "localhost"}], disturbing),
+
+ [{document_root, PrivDir}] = httpd:info(Pid0, [document_root]),
+ ok = inets:stop(httpd, Pid0),
+ ok = inets:stop(),
+
+ File = filename:join(PrivDir, "httpd_apache.conf"),
+
+ {ok, Fd0} = file:open(File, [write]),
+ file:write(Fd0, "ServerName httpd_test\r\n"),
+ file:write(Fd0, "ServerRoot " ++ PrivDir ++ "\r\n"),
+ file:write(Fd0, "DocumentRoot " ++ PrivDir ++" \r\n"),
+ file:write(Fd0, "BindAddress *\r\n"),
+ file:write(Fd0, "Port 0\r\n"),
+ file:close(Fd0),
+
+ application:load(inets),
+ application:set_env(inets,
+ services, [{httpd, [{file, File}]}]),
+
+ ok = inets:start(),
+ [Pid1] = [HttpdPid || {httpd, HttpdPid} <- inets:services()],
+ [{server_name, "httpd_test"}] = httpd:info(Pid1, [server_name]),
+ [{port, Port1}] = httpd:info(Pid1, [port]),
+ {ok, Fd1} = file:open(File, [write]),
+ file:write(Fd1, "ServerName httpd_test2\r\n"),
+ file:write(Fd1, "ServerRoot " ++ PrivDir ++ "\r\n"),
+ file:write(Fd1, "DocumentRoot " ++ PrivDir ++" \r\n"),
+ file:write(Fd1, "BindAddress *\r\n"),
+ file:write(Fd1, "Port " ++ integer_to_list(Port1) ++ "\r\n"),
+ file:close(Fd1),
+
+ ok = httpd:reload_config(File, non_disturbing),
+ [{server_name, "httpd_test2"}] = httpd:info(Pid1, [server_name]),
+
+ {ok, Fd2} = file:open(File, [write]),
+ file:write(Fd2, "ServerName httpd_test\r\n"),
+ file:write(Fd2, "ServerRoot " ++ PrivDir ++ "\r\n"),
+ file:write(Fd2, "DocumentRoot " ++ PrivDir ++" \r\n"),
+ file:write(Fd2, "BindAddress *\r\n"),
+ file:write(Fd2, "Port " ++ integer_to_list(Port1) ++ "\r\n"),
+ file:close(Fd2),
+ ok = httpd:reload_config(File, disturbing),
+ [{server_name, "httpd_test"}] = httpd:info(Pid1, [server_name]),
+
+ ok = inets:stop(httpd, Pid1),
+ application:unset_env(inets, services),
+ ok = inets:stop(),
+ i("httpd_reload -> starting"),
+ ok.
+
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ Timestamp = formated_timestamp(),
+ test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n", [Timestamp, self(), ?MODULE | A]).
+
+i(F) ->
+ i(F, []).
+
+i(F, A) ->
+ Timestamp = formated_timestamp(),
+ io:format("*** ~s ~w:" ++ F ++ "~n", [Timestamp, ?MODULE | A]).
+
+formated_timestamp() ->
+ format_timestamp( os:timestamp() ).
+
+format_timestamp({_N1, _N2, N3} = Now) ->
+ {Date, Time} = calendar:now_to_datetime(Now),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
+
diff --git a/lib/inets/test/inets_SUITE_data/.gitignore b/lib/inets/test/inets_SUITE_data/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/inets/test/inets_SUITE_data/.gitignore
diff --git a/lib/inets/test/inets_app_test.erl b/lib/inets/test/inets_app_test.erl
new file mode 100644
index 0000000000..6bdb9bb308
--- /dev/null
+++ b/lib/inets/test/inets_app_test.erl
@@ -0,0 +1,296 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Verify the application specifics of the inets application
+%%----------------------------------------------------------------------
+-module(inets_app_test).
+
+-compile(export_all).
+
+-include("inets_test_lib.hrl").
+
+
+% t() -> megaco_test_lib:t(?MODULE).
+% t(Case) -> megaco_test_lib:t({?MODULE, Case}).
+
+
+%% Test server callbacks
+init_per_testcase(undef_funcs, Config) ->
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ Dog = test_server:timetrap(inets_test_lib:minutes(10)),
+ [{watchdog, Dog}| NewConfig];
+init_per_testcase(_, Config) ->
+ Config.
+
+fin_per_testcase(_Case, Config) ->
+ Config.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(suite) ->
+ Cases =
+ [
+ fields,
+ modules,
+ exportall,
+ app_depend,
+ undef_funcs
+ ],
+ {req, [], {conf, app_init, Cases, app_fin}}.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+app_init(suite) -> [];
+app_init(doc) -> [];
+app_init(Config) when is_list(Config) ->
+ case is_app(inets) of
+ {ok, AppFile} ->
+ io:format("AppFile: ~n~p~n", [AppFile]),
+ inets:print_version_info(),
+ [{app_file, AppFile}|Config];
+ {error, Reason} ->
+ fail(Reason)
+ end.
+
+is_app(App) ->
+ LibDir = code:lib_dir(App),
+ File = filename:join([LibDir, "ebin", atom_to_list(App) ++ ".app"]),
+ case file:consult(File) of
+ {ok, [{application, App, AppFile}]} ->
+ {ok, AppFile};
+ Error ->
+ {error, {invalid_format, Error}}
+ end.
+
+
+app_fin(suite) -> [];
+app_fin(doc) -> [];
+app_fin(Config) when is_list(Config) ->
+ Config.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+fields(suite) ->
+ [];
+fields(doc) ->
+ [];
+fields(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Fields = [vsn, description, modules, registered, applications],
+ case check_fields(Fields, AppFile, []) of
+ [] ->
+ ok;
+ Missing ->
+ fail({missing_fields, Missing})
+ end.
+
+check_fields([], _AppFile, Missing) ->
+ Missing;
+check_fields([Field|Fields], AppFile, Missing) ->
+ check_fields(Fields, AppFile, check_field(Field, AppFile, Missing)).
+
+check_field(Name, AppFile, Missing) ->
+ io:format("checking field: ~p~n", [Name]),
+ case lists:keymember(Name, 1, AppFile) of
+ true ->
+ Missing;
+ false ->
+ [Name|Missing]
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+modules(suite) ->
+ [];
+modules(doc) ->
+ [];
+modules(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ EbinList = get_ebin_mods(inets),
+ case missing_modules(Mods, EbinList, []) of
+ [] ->
+ ok;
+ Missing ->
+ throw({error, {missing_modules, Missing}})
+ end,
+ case extra_modules(Mods, EbinList, []) of
+ [] ->
+ ok;
+ Extra ->
+ throw({error, {extra_modules, Extra}})
+ end,
+ {ok, Mods}.
+
+get_ebin_mods(App) ->
+ LibDir = code:lib_dir(App),
+ EbinDir = filename:join([LibDir,"ebin"]),
+ {ok, Files0} = file:list_dir(EbinDir),
+ Files1 = [lists:reverse(File) || File <- Files0],
+ [list_to_atom(lists:reverse(Name)) || [$m,$a,$e,$b,$.|Name] <- Files1].
+
+
+missing_modules([], _Ebins, Missing) ->
+ Missing;
+missing_modules([Mod|Mods], Ebins, Missing) ->
+ case lists:member(Mod, Ebins) of
+ true ->
+ missing_modules(Mods, Ebins, Missing);
+ false ->
+ io:format("missing module: ~p~n", [Mod]),
+ missing_modules(Mods, Ebins, [Mod|Missing])
+ end.
+
+
+extra_modules(_Mods, [], Extra) ->
+ Extra;
+extra_modules(Mods, [Mod|Ebins], Extra) ->
+ case lists:member(Mod, Mods) of
+ true ->
+ extra_modules(Mods, Ebins, Extra);
+ false ->
+ io:format("supefluous module: ~p~n", [Mod]),
+ extra_modules(Mods, Ebins, [Mod|Extra])
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+exportall(suite) ->
+ [];
+exportall(doc) ->
+ [];
+exportall(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ check_export_all(Mods).
+
+
+check_export_all([]) ->
+ ok;
+check_export_all([Mod|Mods]) ->
+ case (catch apply(Mod, module_info, [compile])) of
+ {'EXIT', {undef, _}} ->
+ check_export_all(Mods);
+ O ->
+ case lists:keysearch(options, 1, O) of
+ false ->
+ check_export_all(Mods);
+ {value, {options, List}} ->
+ case lists:member(export_all, List) of
+ true ->
+ throw({error, {export_all, Mod}});
+ false ->
+ check_export_all(Mods)
+ end
+ end
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+app_depend(suite) ->
+ [];
+app_depend(doc) ->
+ [];
+app_depend(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Apps = key1search(applications, AppFile),
+ check_apps(Apps).
+
+
+check_apps([]) ->
+ ok;
+check_apps([App|Apps]) ->
+ case is_app(App) of
+ {ok, _} ->
+ check_apps(Apps);
+ Error ->
+ throw({error, {missing_app, {App, Error}}})
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+undef_funcs(suite) ->
+ [];
+undef_funcs(doc) ->
+ [];
+undef_funcs(Config) when is_list(Config) ->
+ App = inets,
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ Root = code:root_dir(),
+ LibDir = code:lib_dir(App),
+ EbinDir = filename:join([LibDir,"ebin"]),
+ XRefTestName = undef_funcs_make_name(App, xref_test_name),
+ {ok, XRef} = xref:start(XRefTestName),
+ ok = xref:set_default(XRef,
+ [{verbose,false},{warnings,false}]),
+ XRefName = undef_funcs_make_name(App, xref_name),
+ {ok, XRefName} = xref:add_release(XRef, Root, {name,XRefName}),
+ {ok, App} = xref:replace_application(XRef, App, EbinDir),
+ {ok, Undefs} = xref:analyze(XRef, undefined_function_calls),
+ xref:stop(XRef),
+ analyze_undefined_function_calls(Undefs, Mods, []).
+
+analyze_undefined_function_calls([], _, []) ->
+ ok;
+analyze_undefined_function_calls([], _, AppUndefs) ->
+ exit({suite_failed, {undefined_function_calls, AppUndefs}});
+analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs],
+ AppModules, AppUndefs) ->
+ %% Check that this module is our's
+ case lists:member(Mod,AppModules) of
+ true ->
+ {Calling,Called} = AppUndef,
+ {Mod1,Func1,Ar1} = Calling,
+ {Mod2,Func2,Ar2} = Called,
+ io:format("undefined function call: "
+ "~n ~w:~w/~w calls ~w:~w/~w~n",
+ [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
+ analyze_undefined_function_calls(Undefs, AppModules,
+ [AppUndef|AppUndefs]);
+ false ->
+ io:format("dropping ~p~n", [Mod]),
+ analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
+ end.
+
+%% This function is used simply to avoid cut-and-paste errors later...
+undef_funcs_make_name(App, PostFix) ->
+ list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+fail(Reason) ->
+ exit({suite_failed, Reason}).
+
+key1search(Key, L) ->
+ case lists:keysearch(Key, 1, L) of
+ undefined ->
+ fail({not_found, Key, L});
+ {value, {Key, Value}} ->
+ Value
+ end.
diff --git a/lib/inets/test/inets_appup_test.erl b/lib/inets/test/inets_appup_test.erl
new file mode 100644
index 0000000000..d580c6c4c5
--- /dev/null
+++ b/lib/inets/test/inets_appup_test.erl
@@ -0,0 +1,336 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Verify the application specifics of the Megaco application
+%%----------------------------------------------------------------------
+-module(inets_appup_test).
+
+-compile(export_all).
+
+-include("inets_test_lib.hrl").
+
+
+% t() -> megaco_test_lib:t(?MODULE).
+% t(Case) -> megaco_test_lib:t({?MODULE, Case}).
+
+
+%% Test server callbacks
+init_per_testcase(_Case, Config) ->
+ Config.
+
+fin_per_testcase(_Case, Config) ->
+ Config.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(suite) ->
+ Cases =
+ [
+ appup
+ ],
+ {req, [], {conf, appup_init, Cases, appup_fin}}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+appup_init(suite) -> [];
+appup_init(doc) -> [];
+appup_init(Config) when is_list(Config) ->
+ AppFile = file_name(inets, ".app"),
+ AppupFile = file_name(inets, ".appup"),
+ [{app_file, AppFile}, {appup_file, AppupFile}|Config].
+
+
+file_name(App, Ext) ->
+ LibDir = code:lib_dir(App),
+ filename:join([LibDir, "ebin", atom_to_list(App) ++ Ext]).
+
+
+appup_fin(suite) -> [];
+appup_fin(doc) -> [];
+appup_fin(Config) when is_list(Config) ->
+ Config.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+appup(suite) ->
+ [];
+appup(doc) ->
+ "perform a simple check of the appup file";
+appup(Config) when is_list(Config) ->
+ AppupFile = key1search(appup_file, Config),
+ AppFile = key1search(app_file, Config),
+ Modules = modules(AppFile),
+ check_appup(AppupFile, Modules).
+
+modules(File) ->
+ case file:consult(File) of
+ {ok, [{application,inets,Info}]} ->
+ case lists:keysearch(modules,1,Info) of
+ {value, {modules, Modules}} ->
+ Modules;
+ false ->
+ fail({bad_appinfo, Info})
+ end;
+ Error ->
+ fail({bad_appfile, Error})
+ end.
+
+
+check_appup(AppupFile, Modules) ->
+ case file:consult(AppupFile) of
+ {ok, [{V, UpFrom, DownTo}]} ->
+% io:format("~p => "
+% "~n ~p"
+% "~n ~p"
+% "~n", [V, UpFrom, DownTo]),
+ check_appup(V, UpFrom, DownTo, Modules);
+ Else ->
+ fail({bad_appupfile, Else})
+ end.
+
+
+check_appup(V, UpFrom, DownTo, Modules) ->
+ check_version(V),
+ check_depends(up, UpFrom, Modules),
+ check_depends(down, DownTo, Modules),
+ ok.
+
+
+check_depends(_, [], _) ->
+ ok;
+check_depends(UpDown, [Dep|Deps], Modules) ->
+ check_depend(UpDown, Dep, Modules),
+ check_depends(UpDown, Deps, Modules).
+
+
+check_depend(UpDown, {V, Instructions}, Modules) ->
+ check_version(V),
+ case check_instructions(UpDown,
+ Instructions, Instructions, [], [], Modules) of
+ {_Good, []} ->
+ ok;
+ {_, Bad} ->
+ fail({bad_instructions, Bad, UpDown})
+ end.
+
+
+check_instructions(_, [], _, Good, Bad, _) ->
+ {lists:reverse(Good), lists:reverse(Bad)};
+check_instructions(UpDown, [Instr|Instrs], AllInstr, Good, Bad, Modules) ->
+ case (catch check_instruction(UpDown, Instr, AllInstr, Modules)) of
+ ok ->
+ check_instructions(UpDown, Instrs, AllInstr,
+ [Instr|Good], Bad, Modules);
+ {error, Reason} ->
+ check_instructions(UpDown, Instrs, AllInstr, Good,
+ [{Instr, Reason}|Bad], Modules)
+ end;
+check_instructions(UpDown, Instructions, _, _, _, _) ->
+ fail({bad_instructions, {UpDown, Instructions}}).
+
+%% A new module is added
+check_instruction(up, {add_module, Module}, _, Modules)
+ when is_atom(Module) ->
+ check_module(Module, Modules);
+
+%% An old module is re-added
+check_instruction(down, {add_module, Module}, _, Modules)
+ when is_atom(Module) ->
+ case (catch check_module(Module, Modules)) of
+ {error, {unknown_module, Module, Modules}} ->
+ ok;
+ ok ->
+ error({existing_readded_module, Module})
+ end;
+
+%% Removing a module on upgrade:
+%% - the module has been removed from the app-file.
+%% - check that no module depends on this (removed) module
+check_instruction(up, {remove, {Module, Pre, Post}}, _, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post) ->
+ case (catch check_module(Module, Modules)) of
+ {error, {unknown_module, Module, Modules}} ->
+ check_purge(Pre),
+ check_purge(Post);
+ ok ->
+ error({existing_removed_module, Module})
+ end;
+
+%% Removing a module on downgrade: the module exist
+%% in the app-file.
+check_instruction(down, {remove, {Module, Pre, Post}}, AllInstr, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post) ->
+ case (catch check_module(Module, Modules)) of
+ ok ->
+ check_purge(Pre),
+ check_purge(Post),
+ check_no_remove_depends(Module, AllInstr);
+ {error, {unknown_module, Module, Modules}} ->
+ error({nonexisting_removed_module, Module})
+ end;
+
+check_instruction(up, {load_module, Module, Pre, Post, Depend}, _, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
+ check_module(Module, Modules),
+ check_module_depend(Module, Depend, Modules),
+ check_purge(Pre),
+ check_purge(Post);
+
+check_instruction(down, {load_module, Module, Pre, Post, Depend}, _, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
+ check_module(Module, Modules),
+ % Can not be sure that the the dependent module exists in the new appfile
+ %%check_module_depend(Module, Depend, Modules),
+ check_purge(Pre),
+ check_purge(Post);
+
+
+
+check_instruction(up, {delete_module, Module}, _, Modules)
+ when is_atom(Module) ->
+ case (catch check_module(Module, Modules)) of
+ {error, {unknown_module, Module, Modules}} ->
+ ok;
+ ok ->
+ error({existing_module_deleted, Module})
+ end;
+
+check_instruction(down, {delete_module, Module}, _, Modules)
+ when is_atom(Module) ->
+ check_module(Module, Modules);
+
+
+check_instruction(_, {apply, {Module, Function, Args}}, _, _) when is_atom(Module), is_atom(Function), is_list(Args) ->
+ ok;
+
+check_instruction(_, {update, Module, supervisor}, _, Modules) when is_atom(Module) ->
+ check_module(Module, Modules);
+
+check_instruction(_, {update, Module, {advanced, _}, DepMods}, _, Modules) when is_atom(Module), is_list(DepMods) ->
+ check_module(Module, Modules),
+ check_module_depend(Module, DepMods, Modules);
+
+check_instruction(_, {update, Module, Change, Pre, Post, Depend}, _, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
+ check_module(Module, Modules),
+ check_module_depend(Module, Depend, Modules),
+ check_change(Change),
+ check_purge(Pre),
+ check_purge(Post);
+
+check_instruction(_, {restart_application, inets}, _AllInstr, _Modules) ->
+ ok;
+
+check_instruction(_, {update, Module, {advanced, _}}, _, Modules) ->
+ check_module(Module, Modules);
+
+check_instruction(_, Instr, _AllInstr, _Modules) ->
+ error({error, {unknown_instruction, Instr}}).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+check_version(V) when is_list(V) ->
+ ok;
+check_version(V) ->
+ error({bad_version, V}).
+
+
+check_module(M, Modules) when is_atom(M) ->
+ case lists:member(M,Modules) of
+ true ->
+ ok;
+ false ->
+ error({unknown_module, M, Modules})
+ end;
+check_module(M, _) ->
+ error({bad_module, M}).
+
+
+check_module_depend(M, [], _) when is_atom(M) ->
+ ok;
+check_module_depend(M, Deps, Modules) when is_atom(M), is_list(Deps) ->
+ case [Dep || Dep <- Deps, lists:member(Dep, Modules) == false] of
+ [] ->
+ ok;
+ Unknown ->
+ error({unknown_depend_modules, Unknown})
+ end;
+check_module_depend(_M, D, _Modules) ->
+ error({bad_depend, D}).
+
+
+check_no_remove_depends(_Module, []) ->
+ ok;
+check_no_remove_depends(Module, [Instr|Instrs]) ->
+ check_no_remove_depend(Module, Instr),
+ check_no_remove_depends(Module, Instrs).
+
+check_no_remove_depend(Module, {load_module, Mod, _Pre, _Post, Depend}) ->
+ case lists:member(Module, Depend) of
+ true ->
+ error({removed_module_in_depend, load_module, Mod, Module});
+ false ->
+ ok
+ end;
+check_no_remove_depend(Module, {update, Mod, _Change, _Pre, _Post, Depend}) ->
+ case lists:member(Module, Depend) of
+ true ->
+ error({removed_module_in_depend, update, Mod, Module});
+ false ->
+ ok
+ end;
+check_no_remove_depend(_, _) ->
+ ok.
+
+
+check_change(soft) ->
+ ok;
+check_change({advanced, _Something}) ->
+ ok;
+check_change(Change) ->
+ error({bad_change, Change}).
+
+
+check_purge(soft_purge) ->
+ ok;
+check_purge(brutal_purge) ->
+ ok;
+check_purge(Purge) ->
+ error({bad_purge, Purge}).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+error(Reason) ->
+ throw({error, Reason}).
+
+fail(Reason) ->
+ exit({suite_failed, Reason}).
+
+key1search(Key, L) ->
+ case lists:keysearch(Key, 1, L) of
+ undefined ->
+ fail({not_found, Key, L});
+ {value, {Key, Value}} ->
+ Value
+ end.
diff --git a/lib/inets/test/inets_internal.hrl b/lib/inets/test/inets_internal.hrl
new file mode 120000
index 0000000000..3228d7ef6a
--- /dev/null
+++ b/lib/inets/test/inets_internal.hrl
@@ -0,0 +1 @@
+../src/inets_app/inets_internal.hrl \ No newline at end of file
diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl
new file mode 100644
index 0000000000..ba41e0960c
--- /dev/null
+++ b/lib/inets/test/inets_sup_SUITE.erl
@@ -0,0 +1,414 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(inets_sup_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+all(doc) ->
+ ["Test that the inets supervisorstructur is the expected one."];
+all(suite) ->
+ [
+ default_tree,
+ ftpc_worker,
+ tftpd_worker,
+ httpd_subtree,
+ httpc_subtree
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_) ->
+ inets:stop(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_testcase(httpd_subtree, Config) ->
+ io:format("init_per_testcase(httpd_subtree) -> entry with"
+ "~n Config: ~p"
+ "~n", [Config]),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ServerROOT = filename:join(PrivDir, "server_root"),
+ DocROOT = filename:join(PrivDir, "htdocs"),
+ ConfDir = filename:join(ServerROOT, "conf"),
+
+ io:format("init_per_testcase(httpd_subtree) -> create dir(s)"
+ "~n", []),
+ file:make_dir(ServerROOT), %% until http_test is cleaned up!
+ ok = file:make_dir(DocROOT),
+ ok = file:make_dir(ConfDir),
+
+ io:format("init_per_testcase(httpd_subtree) -> copy file(s)"
+ "~n", []),
+ {ok, _} = inets_test_lib:copy_file("simple.conf", DataDir, PrivDir),
+ {ok, _} = inets_test_lib:copy_file("mime.types", DataDir, ConfDir),
+
+ io:format("init_per_testcase(httpd_subtree) -> write file(s)"
+ "~n", []),
+ ConfFile = filename:join(PrivDir, "simple.conf"),
+ {ok, Fd} = file:open(ConfFile, [append]),
+ ok = file:write(Fd, "ServerRoot " ++ ServerROOT ++ "\n"),
+ ok = file:write(Fd, "DocumentRoot " ++ DocROOT ++ "\n"),
+ ok = file:close(Fd),
+
+ %% To make sure application:set_env is not overwritten by any
+ %% app-file settings.
+ io:format("init_per_testcase(httpd_subtree) -> load inets app"
+ "~n", []),
+ application:load(inets),
+ io:format("init_per_testcase(httpd_subtree) -> update inets env"
+ "~n", []),
+ ok = application:set_env(inets, services, [{httpd, ConfFile}]),
+
+ try
+ io:format("init_per_testcase(httpd_subtree) -> start inets app"
+ "~n", []),
+ ok = inets:start(),
+ io:format("init_per_testcase(httpd_subtree) -> done"
+ "~n", []),
+ [{watchdog, Dog}, {server_root, ServerROOT}, {doc_root, DocROOT},
+ {conf_dir, ConfDir}| NewConfig]
+ catch
+ _:Reason ->
+ io:format("init_per_testcase(httpd_subtree) -> "
+ "failed starting inets - cleanup"
+ "~n Reason: ~p"
+ "~n", [Reason]),
+ application:unset_env(inets, services),
+ application:unload(inets),
+ exit({failed_starting_inets, Reason})
+ end;
+
+
+init_per_testcase(Case, Config) ->
+ io:format("init_per_testcase(~p) -> entry with"
+ "~n Config: ~p"
+ "~n", [Case, Config]),
+ Dog = test_server:timetrap(?t:minutes(5)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ Stop = inets:stop(),
+ io:format("init_per_testcase(~p) -> Stop: ~p"
+ "~n", [Case, Stop]),
+ ok = inets:start(),
+ [{watchdog, Dog} | NewConfig].
+
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(httpd_subtree, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ PrivDir = ?config(priv_dir, Config),
+ inets_test_lib:del_dirs(PrivDir),
+ ok;
+
+end_per_testcase(_, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ inets:stop(),
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+
+
+%%-------------------------------------------------------------------------
+%% default_tree
+%%-------------------------------------------------------------------------
+default_tree(doc) ->
+ ["Makes sure the correct processes are started and linked,"
+ "in the default case."];
+default_tree(suite) ->
+ [];
+default_tree(Config) when is_list(Config) ->
+ TopSupChildren = supervisor:which_children(inets_sup),
+ 4 = length(TopSupChildren),
+ {value, {httpd_sup, _, supervisor,[httpd_sup]}} =
+ lists:keysearch(httpd_sup, 1, TopSupChildren),
+ {value, {httpc_sup, _,supervisor,[httpc_sup]}} =
+ lists:keysearch(httpc_sup, 1, TopSupChildren),
+ {value, {ftp_sup,_,supervisor,[ftp_sup]}} =
+ lists:keysearch(ftp_sup, 1, TopSupChildren),
+ {value, {tftp_sup,_,supervisor,[tftp_sup]}} =
+ lists:keysearch(tftp_sup, 1, TopSupChildren),
+
+ HttpcSupChildren = supervisor:which_children(httpc_sup),
+ {value, {httpc_profile_sup,_, supervisor, [httpc_profile_sup]}} =
+ lists:keysearch(httpc_profile_sup, 1, HttpcSupChildren),
+ {value, {httpc_handler_sup,_, supervisor, [httpc_handler_sup]}} =
+ lists:keysearch(httpc_handler_sup, 1, HttpcSupChildren),
+
+ [] = supervisor:which_children(ftp_sup),
+
+ [] = supervisor:which_children(httpd_sup),
+
+ %% Default profile
+ [{httpc_manager, _, worker,[httpc_manager]}]
+ = supervisor:which_children(httpc_profile_sup),
+
+ [] = supervisor:which_children(httpc_handler_sup),
+
+ [] = supervisor:which_children(tftp_sup),
+
+ ok.
+
+
+%%-------------------------------------------------------------------------
+%% ftpc_worker
+%%-------------------------------------------------------------------------
+ftpc_worker(doc) ->
+ ["Makes sure the ftp worker processes are added and removed "
+ "appropriatly to/from the supervison tree."];
+ftpc_worker(suite) ->
+ [];
+ftpc_worker(Config) when is_list(Config) ->
+ inets:disable_trace(),
+ inets:enable_trace(max, io, ftpc),
+ [] = supervisor:which_children(ftp_sup),
+ try
+ begin
+ {_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config),
+ case inets:start(ftpc, [{host, FtpdHost}]) of
+ {ok, Pid} ->
+ case supervisor:which_children(ftp_sup) of
+ [{_,_, worker, [ftp]}] ->
+ inets:stop(ftpc, Pid),
+ test_server:sleep(5000),
+ [] = supervisor:which_children(ftp_sup),
+ inets:disable_trace(),
+ ok;
+ Children ->
+ inets:disable_trace(),
+ exit({unexpected_children, Children})
+ end;
+ _ ->
+ inets:disable_trace(),
+ {skip, "Unable to reach test FTP server"}
+ end
+ end
+ catch
+ throw:{error, not_found} ->
+ inets:disable_trace(),
+ {skip, "No available FTP servers"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+%% tftpd_worker
+%%-------------------------------------------------------------------------
+tftpd_worker(doc) ->
+ ["Makes sure the tftp sub tree is correct."];
+tftpd_worker(suite) ->
+ [];
+tftpd_worker(Config) when is_list(Config) ->
+ [] = supervisor:which_children(tftp_sup),
+ {ok, Pid0} = inets:start(tftpd, [{host, "localhost"},
+ {port, inet_port()}]),
+ {ok, _Pid1} = inets:start(tftpd, [{host, "localhost"},
+ {port, inet_port()}], stand_alone),
+
+ [{_,Pid0, worker, _}] = supervisor:which_children(tftp_sup),
+ inets:stop(tftpd, Pid0),
+ test_server:sleep(5000),
+ [] = supervisor:which_children(tftp_sup),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+%% httpd_subtree
+%%-------------------------------------------------------------------------
+httpd_subtree(doc) ->
+ ["Makes sure the httpd sub tree is correct."];
+httpd_subtree(suite) ->
+ [];
+httpd_subtree(Config) when is_list(Config) ->
+ io:format("httpd_subtree -> entry with"
+ "~n Config: ~p"
+ "~n", [Config]),
+
+ %% Check that we have the httpd top supervisor
+ io:format("httpd_subtree -> verify inets~n", []),
+ {ok, _} = verify_child(inets_sup, httpd_sup, supervisor),
+
+ %% Check that we have the httpd instance supervisor
+ io:format("httpd_subtree -> verify httpd~n", []),
+ {ok, Id} = verify_child(httpd_sup, httpd_instance_sup, supervisor),
+ {httpd_instance_sup, Addr, Port} = Id,
+ Instance = httpd_util:make_name("httpd_instance_sup", Addr, Port),
+
+ %% Check that we have the expected httpd instance children
+ io:format("httpd_subtree -> verify httpd instance children "
+ "(acceptor, misc and manager)~n", []),
+ {ok, _} = verify_child(Instance, httpd_acceptor_sup, supervisor),
+ {ok, _} = verify_child(Instance, httpd_misc_sup, supervisor),
+ {ok, _} = verify_child(Instance, httpd_manager, worker),
+
+ %% Check that the httpd instance acc supervisor has children
+ io:format("httpd_subtree -> verify acc~n", []),
+ InstanceAcc = httpd_util:make_name("httpd_acc_sup", Addr, Port),
+ case supervisor:which_children(InstanceAcc) of
+ [_ | _] ->
+ ok;
+ InstanceAccUnexpectedChildren ->
+ exit({unexpected_children,
+ InstanceAcc, InstanceAccUnexpectedChildren})
+ end,
+
+ %% Check that the httpd instance misc supervisor has no children
+ io:format("httpd_subtree -> verify misc~n", []),
+ InstanceMisc = httpd_util:make_name("httpd_misc_sup", Addr, Port),
+ case supervisor:which_children(InstanceMisc) of
+ [] ->
+ ok;
+ InstanceMiscUnexpectedChildren ->
+ exit({unexpected_children,
+ InstanceMisc, InstanceMiscUnexpectedChildren})
+ end,
+ io:format("httpd_subtree -> done~n", []),
+ ok.
+
+
+verify_child(Parent, Child, Type) ->
+%% io:format("verify_child -> entry with"
+%% "~n Parent: ~p"
+%% "~n Child: ~p"
+%% "~n Type: ~p"
+%% "~n", [Parent, Child, Type]),
+ Children = supervisor:which_children(Parent),
+%% io:format("verify_child -> which children"
+%% "~n Children: ~p"
+%% "~n", [Children]),
+ verify_child(Children, Parent, Child, Type).
+
+verify_child([], Parent, Child, _Type) ->
+ {error, {child_not_found, Child, Parent}};
+verify_child([{Id, _Pid, Type2, Mods}|Children], Parent, Child, Type) ->
+ case lists:member(Child, Mods) of
+ true when (Type2 =:= Type) ->
+%% io:format("verify_child -> found with expected type"
+%% "~n Id: ~p"
+%% "~n", [Id]),
+ {ok, Id};
+ true when (Type2 =/= Type) ->
+%% io:format("verify_child -> found with unexpected type"
+%% "~n Type2: ~p"
+%% "~n Id: ~p"
+%% "~n", [Type2, Id]),
+ {error, {wrong_type, Type2, Child, Parent}};
+ false ->
+ verify_child(Children, Parent, Child, Type)
+ end.
+
+
+
+%%-------------------------------------------------------------------------
+%% httpc_subtree
+%%-------------------------------------------------------------------------
+httpc_subtree(doc) ->
+ ["Makes sure the httpc sub tree is correct."];
+httpc_subtree(suite) ->
+ [];
+httpc_subtree(Config) when is_list(Config) ->
+ tsp("httpc_subtree -> entry with"
+ "~n Config: ~p", [Config]),
+
+ tsp("httpc_subtree -> start inets service httpc with profile foo"),
+ {ok, Foo} = inets:start(httpc, [{profile, foo}]),
+
+ tsp("httpc_subtree -> "
+ "start stand-alone inets service httpc with profile bar"),
+ {ok, Bar} = inets:start(httpc, [{profile, bar}], stand_alone),
+
+ tsp("httpc_subtree -> retreive list of httpc instances"),
+ HttpcChildren = supervisor:which_children(httpc_profile_sup),
+ tsp("httpc_subtree -> HttpcChildren: ~n~p", [HttpcChildren]),
+
+ tsp("httpc_subtree -> verify httpc stand-alone instances"),
+ {value, {httpc_manager, _, worker, [httpc_manager]}} =
+ lists:keysearch(httpc_manager, 1, HttpcChildren),
+
+ tsp("httpc_subtree -> verify httpc (named) instances"),
+ {value,{{httpc,foo}, Pid, worker, [httpc_manager]}} =
+ lists:keysearch({httpc, foo}, 1, HttpcChildren),
+ false = lists:keysearch({httpc, bar}, 1, HttpcChildren),
+
+ tsp("httpc_subtree -> stop inets"),
+ inets:stop(httpc, Pid),
+
+ tsp("httpc_subtree -> done"),
+ ok.
+
+inet_port() ->
+ {ok, Socket} = gen_tcp:listen(0, [{reuseaddr, true}]),
+ {ok, Port} = inet:port(Socket),
+ gen_tcp:close(Socket),
+ Port.
+
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+
diff --git a/lib/inets/test/inets_sup_SUITE_data/mime.types b/lib/inets/test/inets_sup_SUITE_data/mime.types
new file mode 100644
index 0000000000..e52d345ff7
--- /dev/null
+++ b/lib/inets/test/inets_sup_SUITE_data/mime.types
@@ -0,0 +1,3 @@
+# MIME type Extension
+text/html html htm
+text/plain asc txt
diff --git a/lib/inets/test/inets_sup_SUITE_data/simple.conf b/lib/inets/test/inets_sup_SUITE_data/simple.conf
new file mode 100644
index 0000000000..e1429b4a28
--- /dev/null
+++ b/lib/inets/test/inets_sup_SUITE_data/simple.conf
@@ -0,0 +1,6 @@
+Port 8888
+ServerName www.test
+SocketType ip_comm
+Modules mod_get
+ServerAdmin [email protected]
+
diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl
new file mode 100644
index 0000000000..6af2ad32f7
--- /dev/null
+++ b/lib/inets/test/inets_test_lib.erl
@@ -0,0 +1,302 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(inets_test_lib).
+
+-include("inets_test_lib.hrl").
+
+%% Various small utility functions
+-export([start_http_server/1, start_http_server_ssl/1]).
+-export([hostname/0]).
+-export([connect_bin/3, connect_byte/3, send/3, close/2]).
+-export([copy_file/3, copy_files/2, copy_dirs/2, del_dirs/1]).
+-export([info/4, log/4, debug/4, print/4]).
+-export([check_body/1]).
+-export([millis/0, millis_diff/2, hours/1, minutes/1, seconds/1, sleep/1]).
+-export([non_pc_tc_maybe_skip/4, os_based_skip/1]).
+
+start_http_server(Conf) ->
+ application:load(inets),
+ ok = application:set_env(inets, services, [{httpd, Conf}]),
+ ok = application:start(inets).
+
+start_http_server_ssl(FileName) ->
+ application:start(ssl),
+ catch start_http_server(FileName).
+
+%% ----------------------------------------------------------------------
+%% print functions
+%%
+
+info(F, A, Mod, Line) ->
+ print("INF ", F, A, Mod, Line).
+
+log(F, A, Mod, Line) ->
+ print("LOG ", F, A, Mod, Line).
+
+debug(F, A, Mod, Line) ->
+ print("DBG ", F, A, Mod, Line).
+
+print(P, F, A, Mod, Line) ->
+ io:format("~s[~p:~p:~p] : " ++ F ++ "~n", [P, self(), Mod, Line| A]).
+
+print(F, A, Mod, Line) ->
+ print("", F, A, Mod, Line).
+
+hostname() ->
+ from($@, atom_to_list(node())).
+from(H, [H | T]) -> T;
+from(H, [_ | T]) -> from(H, T);
+from(_, []) -> [].
+
+
+copy_file(File, From, To) ->
+ file:copy(filename:join(From, File), filename:join(To, File)).
+
+copy_files(FromDir, ToDir) ->
+ {ok, Files} = file:list_dir(FromDir),
+ lists:foreach(fun(File) ->
+ FullPath = filename:join(FromDir, File),
+ case filelib:is_file(FullPath) of
+ true ->
+ file:copy(FullPath,
+ filename:join(ToDir, File));
+ false ->
+ ok
+ end
+ end, Files).
+
+
+copy_dirs(FromDirRoot, ToDirRoot) ->
+%% io:format("~w:copy_dirs -> entry with"
+%% "~n FromDirRoot: ~p"
+%% "~n ToDirRoot: ~p"
+%% "~n", [?MODULE, FromDirRoot, ToDirRoot]),
+ {ok, Files} = file:list_dir(FromDirRoot),
+ lists:foreach(
+ fun(FileOrDir) ->
+ %% Check if it's a directory or a file
+%% io:format("~w:copy_dirs -> check ~p"
+%% "~n", [?MODULE, FileOrDir]),
+ case filelib:is_dir(filename:join(FromDirRoot, FileOrDir)) of
+ true ->
+%% io:format("~w:copy_dirs -> ~p is a directory"
+%% "~n", [?MODULE, FileOrDir]),
+ FromDir = filename:join([FromDirRoot, FileOrDir]),
+ ToDir = filename:join([ToDirRoot, FileOrDir]),
+ ok = file:make_dir(ToDir),
+ copy_dirs(FromDir, ToDir);
+ false ->
+%% io:format("~w:copy_dirs -> ~p is a file"
+%% "~n", [?MODULE, FileOrDir]),
+ copy_file(FileOrDir, FromDirRoot, ToDirRoot)
+ end
+ end, Files).
+
+del_dirs(Dir) ->
+ case file:list_dir(Dir) of
+ {ok, []} ->
+ file:del_dir(Dir);
+ {ok, Files} ->
+ lists:foreach(fun(File) ->
+ FullPath = filename:join(Dir,File),
+ case filelib:is_dir(FullPath) of
+ true ->
+ del_dirs(FullPath),
+ file:del_dir(FullPath);
+ false ->
+ file:delete(FullPath)
+ end
+ end, Files);
+ _ ->
+ ok
+ end.
+
+check_body(Body) ->
+ case string:rstr(Body, "</html>") of
+ 0 ->
+ case string:rstr(Body, "</HTML>") of
+ 0 ->
+ test_server:format("Body ~p~n", [Body]),
+ test_server:fail(did_not_receive_whole_body);
+ _ ->
+ ok
+ end;
+ _ ->
+ ok
+ end.
+
+%% ----------------------------------------------------------------
+%% Conditional skip of testcases
+%%
+
+non_pc_tc_maybe_skip(Config, Condition, File, Line)
+ when is_list(Config) andalso is_function(Condition) ->
+ %% Check if we shall skip the skip
+ case os:getenv("TS_OS_BASED_SKIP") of
+ "false" ->
+ ok;
+ _ ->
+ case lists:keysearch(ts, 1, Config) of
+ {value, {ts, inets}} ->
+ %% Always run the testcase if we are using our own
+ %% test-server...
+ ok;
+ _ ->
+ case (catch Condition()) of
+ true ->
+ skip(non_pc_testcase, File, Line);
+ _ ->
+ ok
+ end
+ end
+ end.
+
+
+os_based_skip(any) ->
+ true;
+os_based_skip(Skippable) when is_list(Skippable) ->
+ {OsFam, OsName} =
+ case os:type() of
+ {_Fam, _Name} = FamAndName ->
+ FamAndName;
+ Fam ->
+ {Fam, undefined}
+ end,
+ case lists:member(OsFam, Skippable) of
+ true ->
+ true;
+ false ->
+ case lists:keysearch(OsFam, 1, Skippable) of
+ {value, {OsFam, OsName}} ->
+ true;
+ {value, {OsFam, OsNames}} when is_list(OsNames) ->
+ lists:member(OsName, OsNames);
+ _ ->
+ false
+ end
+ end;
+os_based_skip(_) ->
+ false.
+
+
+%% ----------------------------------------------------------------------
+%% Socket functions:
+%% open(SocketType, Host, Port) -> {ok, Socket} | {error, Reason}
+%% SocketType -> ssl | ip_comm
+%% Host -> atom() | string() | {A, B, C, D}
+%% Port -> integer()
+
+connect_bin(ssl, Host, Port) ->
+ ssl:start(),
+ %% Does not support ipv6 in old ssl
+ case ssl:connect(Host, Port, [binary, {packet,0}]) of
+ {ok, Socket} ->
+ {ok, Socket};
+ {error, Reason} ->
+ {error, Reason};
+ Error ->
+ Error
+ end;
+connect_bin(ip_comm, Host, Port) ->
+ Opts = [inet6, binary, {packet,0}],
+ connect(ip_comm, Host, Port, Opts).
+
+
+connect(ip_comm, Host, Port, Opts) ->
+ test_server:format("gen_tcp:connect(~p, ~p, ~p) ~n", [Host, Port, Opts]),
+ case gen_tcp:connect(Host,Port, Opts) of
+ {ok, Socket} ->
+ test_server:format("connect success~n", []),
+ {ok, Socket};
+ {error, nxdomain} ->
+ test_server:format("nxdomain opts: ~p~n", [Opts]),
+ connect(ip_comm, Host, Port, lists:delete(inet6, Opts));
+ {error, eafnosupport} ->
+ test_server:format("eafnosupport opts: ~p~n", [Opts]),
+ connect(ip_comm, Host, Port, lists:delete(inet6, Opts));
+ {error, {enfile,_}} ->
+ test_server:format("Error enfile~n", []),
+ {error, enfile};
+ Error ->
+ test_server:format("Unexpected error: "
+ "~n Error: ~p"
+ "~nwhen"
+ "~n Host: ~p"
+ "~n Port: ~p"
+ "~n Opts: ~p"
+ "~n", [Error, Host, Port, Opts]),
+ Error
+ end.
+
+connect_byte(ip_comm, Host, Port) ->
+ Opts = [inet6, {packet,0}],
+ connect(ip_comm, Host, Port, Opts);
+
+connect_byte(ssl, Host, Port) ->
+ ssl:start(),
+ %% Does not support ipv6 in old ssl
+ case ssl:connect(Host,Port,[{packet,0}]) of
+ {ok,Socket} ->
+ {ok,Socket};
+ {error,{enfile,_}} ->
+ {error, enfile};
+ Error ->
+ Error
+ end.
+
+send(ssl, Socket, Data) ->
+ ssl:send(Socket, Data);
+send(ip_comm,Socket,Data) ->
+ gen_tcp:send(Socket,Data).
+
+
+close(ssl,Socket) ->
+ catch ssl:close(Socket);
+close(ip_comm,Socket) ->
+ catch gen_tcp:close(Socket).
+
+millis() ->
+ erlang:now().
+
+millis_diff(A,B) ->
+ T1 = (element(1,A)*1000000) + element(2,A) + (element(3,A)/1000000),
+ T2 = (element(1,B)*1000000) + element(2,B) + (element(3,B)/1000000),
+ T1 - T2.
+
+hours(N) -> trunc(N * 1000 * 60 * 60).
+minutes(N) -> trunc(N * 1000 * 60).
+seconds(N) -> trunc(N * 1000).
+
+
+sleep(infinity) ->
+ receive
+ after infinity ->
+ ok
+ end;
+sleep(MSecs) ->
+ receive
+ after trunc(MSecs) ->
+ ok
+ end,
+ ok.
+
+
+skip(Reason, File, Line) ->
+ exit({skipped, {Reason, File, Line}}).
diff --git a/lib/inets/test/inets_test_lib.hrl b/lib/inets/test/inets_test_lib.hrl
new file mode 100644
index 0000000000..12a43fa136
--- /dev/null
+++ b/lib/inets/test/inets_test_lib.hrl
@@ -0,0 +1,104 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Define common macros for testing
+%%----------------------------------------------------------------------
+
+%% - Print macros -
+
+-ifdef(inets_debug).
+-define(DEBUG(F,A), inets_test_lib:debug(F, A, ?MODULE, ?LINE)).
+-else.
+-define(DEBUG(F,A),ok).
+-endif.
+
+-ifdef(inets_log).
+-define(LOG(F,A), inets_test_lib:log(F, A, ?MODULE, ?LINE)).
+-else.
+-define(LOG(F,A),ok).
+-endif.
+
+-define(INFO(F,A), inets_test_lib:info(F, A, ?MODULE, ?LINE)).
+-define(PRINT(F,A), inets_test_lib:print(F, A, ?MODULE, ?LINE)).
+
+
+%% - Macros stolen from the test server -
+
+-ifndef(line).
+-define(line,put(test_server_loc,{?MODULE,?LINE}),).
+-endif.
+
+
+%% - Test case macros -
+
+-define(EXPANDABLE(I, C, F), inets_test_lib:expandable(I, C, F)).
+-define(OS_BASED_SKIP(Skippable),
+ inets_test_lib:os_based_skip(Skippable)).
+
+-define(NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ inets_test_lib:non_pc_tc_maybe_skip(Config, Condition, ?MODULE, ?LINE)).
+
+
+
+%% - Misc macros -
+
+-define(UPDATE(K,V,C), inets_test_lib:update_config(K,V,C)).
+-define(CONFIG(K,C), inets_test_lib:get_config(K,C)).
+-define(HOSTNAME(), inets_test_lib:hostname()).
+-define(SZ(X), inets_test_lib:sz(X)).
+
+
+%% - Test case macros -
+
+-define(SKIP(Reason), inets_test_lib:skip(Reason)).
+-define(FAIL(Reason), inets_test_lib:fail(Reason, ?MODULE, ?LINE)).
+
+
+%% - Socket macros -
+
+-define(CONNECT(M,H,P), inets_test_lib:connect(M,H,P)).
+-define(SEND(M,S,D), inets_test_lib:send(M,S,D)).
+-define(CSEND(M,S,D,C,T), inets_test_lib:csend(M,S,D,C,T)).
+-define(CLOSE(M,S), inets_test_lib:close(M,S)).
+
+
+%% - Time macros -
+
+-define(HOURS(N), inets_test_lib:hours(N)).
+-define(MINS(N), inets_test_lib:minutes(N)).
+-define(SECS(N), inets_test_lib:seconds(N)).
+
+-define(WD_START(T), inets_test_lib:watchdog_start(T)).
+-define(WD_STOP(P), inets_test_lib:watchdog_stop(P)).
+
+-define(SLEEP(MSEC), inets_test_lib:sleep(MSEC)).
+-define(M(), inets_test_lib:millis()).
+-define(MDIFF(A,B), inets_test_lib:millis_diff(A,B)).
+
+
+%% - Process utility macros -
+
+-define(FLUSH(), inets_test_lib:flush_mqueue()).
+-define(ETRAP_GET(), inets_test_lib:trap_exit()).
+-define(ETRAP_SET(O), inets_test_lib:trap_exit(O)).
+
+
+
+
diff --git a/lib/inets/test/rules.mk b/lib/inets/test/rules.mk
new file mode 100644
index 0000000000..047c03b267
--- /dev/null
+++ b/lib/inets/test/rules.mk
@@ -0,0 +1,59 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+# ----------------------------------------------------
+# Make include file for otp
+#
+# Copyright (C) 1996, Ericsson Telecommunications
+# Author: Lars Thorsen
+# ----------------------------------------------------
+.SUFFIXES: .hrl .erl .jam .beam
+
+
+# ----------------------------------------------------
+# Common macros
+# ----------------------------------------------------
+DEFAULT_TARGETS = opt debug instr release release_docs clean docs
+
+# ----------------------------------------------------
+# Erlang language section
+# ----------------------------------------------------
+EMULATOR = beam
+ifeq ($(findstring vxworks,$(TARGET)),vxworks)
+# VxWorks object files should be compressed.
+# Other object files should have debug_info.
+ERL_COMPILE_FLAGS += +compressed
+else
+ifdef BOOTSTRAP
+ERL_COMPILE_FLAGS += +slim
+else
+ERL_COMPILE_FLAGS += +debug_info
+endif
+endif
+ERLC_WFLAGS = -W
+ERLC = erlc $(ERLC_WFLAGS) $(ERLC_FLAGS)
+ERL.beam = erl.beam -boot start_clean
+ERL.jam = erl -boot start_clean
+ERL = $(ERL.$(EMULATOR))
+
+ifeq ($(EBIN),)
+EBIN = .
+endif
+
+ESRC = .
+
+
+$(EBIN)/%.jam: $(ESRC)/%.erl
+ $(ERLC) -bjam $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+
+$(EBIN)/%.beam: $(ESRC)/%.erl
+ $(ERLC) -bbeam $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+
+.erl.jam:
+ $(ERLC) -bjam $(ERL_COMPILE_FLAGS) -o$(dir $@) $<
+
+.erl.beam:
+ $(ERLC) -bbeam $(ERL_COMPILE_FLAGS) -o$(dir $@) $<
+
+
+
+
+
diff --git a/lib/inets/test/tftp_SUITE.erl b/lib/inets/test/tftp_SUITE.erl
new file mode 100644
index 0000000000..5768fff88b
--- /dev/null
+++ b/lib/inets/test/tftp_SUITE.erl
@@ -0,0 +1,903 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(tftp_SUITE).
+
+-compile(export_all).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Includes and defines
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-include("tftp_test_lib.hrl").
+
+-define(START_DAEMON(PortX, OptionsX),
+ fun(Port, Options) ->
+ {ok, Pid} = ?VERIFY({ok, _Pid}, tftp:start([{port, Port} | Options])),
+ if
+ Port == 0 ->
+ {ok, ActualOptions} = ?IGNORE(tftp:info(Pid)),
+ {value, {port, ActualPort}} =
+ lists:keysearch(port, 1, ActualOptions),
+ {ActualPort, Pid};
+ true ->
+ {Port, Pid}
+ end
+ end(PortX, OptionsX)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% API
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+t() ->
+ tftp_test_lib:t([{?MODULE, all}]).
+
+t(Cases) ->
+ tftp_test_lib:t(Cases, default_config()).
+
+t(Cases, Config) ->
+ tftp_test_lib:t(Cases, Config).
+
+default_config() ->
+ [].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Test server callbacks
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_testcase(Case, Config) ->
+ tftp_test_lib:init_per_testcase(Case, Config).
+
+fin_per_testcase(Case, Config) when is_list(Config) ->
+ tftp_test_lib:fin_per_testcase(Case, Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Top test case
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(doc) ->
+ ["Test suites for TFTP."];
+
+all(suite) ->
+ [
+ simple,
+ extra,
+ reuse_connection,
+ resend_client,
+ resend_server
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Simple
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+simple(doc) ->
+ ["Start the daemon and perform simple a read and write."];
+simple(suite) ->
+ [];
+simple(Config) when is_list(Config) ->
+ ?VERIFY(ok, application:start(inets)),
+
+ {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, brief}])),
+
+ %% Read fail
+ RemoteFilename = "tftp_temporary_remote_test_file.txt",
+ LocalFilename = "tftp_temporary_local_test_file.txt",
+ Blob = list_to_binary(lists:duplicate(2000, $1)),
+ %% Blob = <<"Some file contents\n">>,
+ Size = size(Blob),
+ ?IGNORE(file:delete(RemoteFilename)),
+ ?VERIFY({error, {client_open, enoent, _}},
+ tftp:read_file(RemoteFilename, binary, [{port, Port}])),
+
+ %% Write and read
+ ?VERIFY({ok, Size}, tftp:write_file(RemoteFilename, Blob, [{port, Port}])),
+ ?VERIFY({ok, Blob}, tftp:read_file(RemoteFilename, binary, [{port, Port}])),
+ ?IGNORE(file:delete(LocalFilename)),
+ ?VERIFY({ok, Size}, tftp:read_file(RemoteFilename, LocalFilename, [{port, Port}])),
+
+ %% Cleanup
+ unlink(DaemonPid),
+ exit(DaemonPid, kill),
+ ?VERIFY(ok, file:delete(LocalFilename)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+ ?VERIFY(ok, application:stop(inets)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Extra
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+extra(doc) ->
+ ["Verify new stuff for IS 1.2."];
+extra(suite) ->
+ [];
+extra(Config) when is_list(Config) ->
+ ?VERIFY({'EXIT', {badarg,{fake_key, fake_flag}}},
+ tftp:start([{port, 0}, {fake_key, fake_flag}])),
+
+ {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, brief}])),
+
+ RemoteFilename = "tftp_extra_temporary_remote_test_file.txt",
+ LocalFilename = "tftp_extra_temporary_local_test_file.txt",
+ Blob = <<"Some file contents\n">>,
+ Size = size(Blob),
+ Host = "127.0.0.1",
+ Peer = {inet, Host, Port},
+ Generic =
+ [
+ {state, []},
+ {prepare, fun extra_prepare/6},
+ {open, fun extra_open/6},
+ {read, fun extra_read/1},
+ {write, fun extra_write/2},
+ {abort, fun extra_abort/3 }
+ ],
+ Options = [{host, Host},
+ {port, Port},
+ %%{ debug,all},
+ {callback, {".*", tftp_test_lib, Generic}}],
+ ?VERIFY(ok, file:write_file(LocalFilename, Blob)),
+ ?VERIFY({ok, [{count, Size}, Peer]},
+ tftp:write_file(RemoteFilename, LocalFilename, Options)),
+ ?VERIFY(ok, file:delete(LocalFilename)),
+
+ ?VERIFY({ok,[{bin, Blob}, Peer]},
+ tftp:read_file(RemoteFilename, LocalFilename, Options)),
+
+ %% Cleanup
+ unlink(DaemonPid),
+ exit(DaemonPid, kill),
+ ?VERIFY(ok, file:delete(LocalFilename)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+ ok.
+
+-record(extra_state, {file, blksize, count, acc, peer}).
+
+%%-------------------------------------------------------------------
+%% Prepare
+%%-------------------------------------------------------------------
+
+extra_prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, []) ->
+ %% Client side
+ BlkSize = list_to_integer(tftp_test_lib:lookup_option("blksize", "512", SuggestedOptions)),
+ State = #extra_state{blksize = BlkSize, peer = Peer},
+ extra_open(Peer, Access, LocalFilename, Mode, SuggestedOptions, State),
+ {ok, SuggestedOptions, State};
+extra_prepare(_Peer, _Access, _Bin, _Mode, _SuggestedOptions, _Initial) ->
+ {error, {undef, "Illegal callback options."}}.
+
+%%-------------------------------------------------------------------
+%% Open
+%%-------------------------------------------------------------------
+
+extra_open(Peer, Access, LocalFilename, Mode, SuggestedOptions, []) ->
+ %% Server side
+ case extra_prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, []) of
+ {ok, AcceptedOptions, []} ->
+ BlkSize = list_to_integer(tftp_test_lib:lookup_option("blksize", "512", AcceptedOptions)),
+ State = #extra_state{blksize = BlkSize, peer = Peer},
+ extra_open(Peer, Access, LocalFilename, Mode, AcceptedOptions, State);
+ {error, {Code, Text}} ->
+ {error, {Code, Text}}
+ end;
+extra_open(_Peer, Access, LocalFilename, _Mode, NegotiatedOptions, #extra_state{} = State) ->
+ {File, Acc} =
+ case Access of
+ read ->
+ if
+ is_binary(LocalFilename) ->
+ {undefined, LocalFilename};
+ is_list(LocalFilename) ->
+ {ok, Bin} = file:read_file(LocalFilename),
+ {LocalFilename, Bin}
+ end;
+ write ->
+ {LocalFilename, []}
+ end,
+ %% Both sides
+ State2 = State#extra_state{file = File, acc = Acc, count = 0},
+ {ok, NegotiatedOptions, State2}.
+
+%%-------------------------------------------------------------------
+%% Read
+%%-------------------------------------------------------------------
+
+extra_read(#extra_state{acc = Bin} = State) when is_binary(Bin) ->
+ BlkSize = State#extra_state.blksize,
+ Count = State#extra_state.count + size(Bin),
+ if
+ size(Bin) >= BlkSize ->
+ <<Block:BlkSize/binary, Bin2/binary>> = Bin,
+ State2 = State#extra_state{acc = Bin2, count = Count},
+ {more, Block, State2};
+ size(Bin) < BlkSize ->
+ Res = [{count, Count}, State#extra_state.peer],
+ {last, Bin, Res}
+ end.
+
+%%-------------------------------------------------------------------
+%% Write
+%%-------------------------------------------------------------------
+
+extra_write(Bin, #extra_state{acc = List} = State) when is_binary(Bin), is_list(List) ->
+ Size = size(Bin),
+ BlkSize = State#extra_state.blksize,
+ if
+ Size == BlkSize ->
+ {more, State#extra_state{acc = [Bin | List]}};
+ Size < BlkSize ->
+ Bin2 = list_to_binary(lists:reverse([Bin | List])),
+ Res = [{bin, Bin2}, State#extra_state.peer],
+ file:write_file(State#extra_state.file, Bin2),
+ {last, Res}
+ end.
+
+%%-------------------------------------------------------------------
+%% Abort
+%%-------------------------------------------------------------------
+
+extra_abort(_Code, _Text, #extra_state{}) ->
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Re-send client
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+resend_client(doc) ->
+ ["Verify that the server behaves correctly when the client re-sends packets."];
+resend_client(suite) ->
+ [];
+resend_client(Config) when is_list(Config) ->
+ Host = {127, 0, 0, 1},
+ {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, all}])),
+
+ ?VERIFY(ok, resend_read_client(Host, Port, 10)),
+ ?VERIFY(ok, resend_read_client(Host, Port, 512)),
+ ?VERIFY(ok, resend_read_client(Host, Port, 1025)),
+
+ ?VERIFY(ok, resend_write_client(Host, Port, 10)),
+ ?VERIFY(ok, resend_write_client(Host, Port, 512)),
+ ?VERIFY(ok, resend_write_client(Host, Port, 1025)),
+
+ %% Cleanup
+ unlink(DaemonPid),
+ exit(DaemonPid, kill),
+ ok.
+
+resend_read_client(Host, Port, BlkSize) ->
+ RemoteFilename = "tftp_resend_read_client.tmp",
+ Block1 = lists:duplicate(BlkSize, $1),
+ Block2 = lists:duplicate(BlkSize, $2),
+ Block3 = lists:duplicate(BlkSize, $3),
+ Block4 = lists:duplicate(BlkSize, $4),
+ Block5 = lists:duplicate(BlkSize, $5),
+ Blocks = [Block1, Block2, Block3, Block4, Block5],
+ Blob = list_to_binary(Blocks),
+ ?VERIFY(ok, file:write_file(RemoteFilename, Blob)),
+
+ Timeout = timer:seconds(3),
+ ?VERIFY(timeout, recv(0)),
+
+ %% Open socket
+ {ok, Socket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+
+ ReadList = [0, 1, RemoteFilename, 0, "octet", 0],
+ Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]),
+ NewPort =
+ if
+ BlkSize =:= 512 ->
+ %% Send READ
+ ReadBin = list_to_binary(ReadList),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)),
+
+ %% Sleep a while in order to provoke the server to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv DATA #1 (the packet that the server think that we have lost)
+ {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, Data1Bin}, recv(Timeout)),
+ NewPort0;
+ true ->
+ %% Send READ
+ BlkSizeList = integer_to_list(BlkSize),
+ Options = ["blksize", 0, BlkSizeList, 0],
+ ReadBin = list_to_binary([ReadList | Options]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)),
+
+ %% Recv OACK
+ OptionAckBin = list_to_binary([0, 6 | Options]),
+ {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)),
+
+ %% Send ACK #0
+ Ack0Bin = <<0, 4, 0, 0>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort0, Ack0Bin)),
+
+ %% Send ACK #0 AGAIN (pretend that we timed out)
+ timer:sleep(timer:seconds(1)),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort0, Ack0Bin)),
+
+ %% Recv DATA #1 (the packet that the server think that we have lost)
+ ?VERIFY({udp, Socket, Host, NewPort0, Data1Bin}, recv(Timeout)),
+ NewPort0
+ end,
+
+ %% Recv DATA #1 AGAIN (the re-sent package)
+ ?VERIFY({udp, Socket, Host, NewPort, Data1Bin}, recv(Timeout)),
+
+ %% Send ACK #1
+ Ack1Bin = <<0, 4, 0, 1>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack1Bin)),
+
+ %% Recv DATA #2
+ Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]),
+ ?VERIFY({udp, Socket, Host, NewPort, Data2Bin}, recv(Timeout)),
+
+ %% Send ACK #2
+ Ack2Bin = <<0, 4, 0, 2>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack2Bin)),
+
+ %% Recv DATA #3
+ Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]),
+ ?VERIFY({udp, Socket, Host, NewPort, Data3Bin}, recv(Timeout)),
+
+ %% Send ACK #3
+ Ack3Bin = <<0, 4, 0, 3>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack3Bin)),
+
+ %% Send ACK #3 AGAIN (pretend that we timed out)
+ timer:sleep(timer:seconds(1)),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack3Bin)),
+
+ %% Recv DATA #4 (the packet that the server think that we have lost)
+ Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]),
+ ?VERIFY({udp, Socket, Host, NewPort, Data4Bin}, recv(Timeout)),
+
+ %% Recv DATA #4 AGAIN (the re-sent package)
+ ?VERIFY({udp, Socket, Host, NewPort, Data4Bin}, recv(Timeout)),
+
+ %% Send ACK #2 which is out of range
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack2Bin)),
+
+ %% Send ACK #4
+ Ack4Bin = <<0, 4, 0, 4>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack4Bin)),
+
+ %% Recv DATA #5
+ Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]),
+ ?VERIFY({udp, Socket, Host, NewPort, Data5Bin}, recv(Timeout)),
+
+ %% Send ACK #5
+ Ack5Bin = <<0, 4, 0, 5>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack5Bin)),
+
+ %% Close socket
+ ?VERIFY(ok, gen_udp:close(Socket)),
+
+ ?VERIFY(timeout, recv(Timeout)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+ ok.
+
+resend_write_client(Host, Port, BlkSize) ->
+ RemoteFilename = "tftp_resend_write_client.tmp",
+ Block1 = lists:duplicate(BlkSize, $1),
+ Block2 = lists:duplicate(BlkSize, $2),
+ Block3 = lists:duplicate(BlkSize, $3),
+ Block4 = lists:duplicate(BlkSize, $4),
+ Block5 = lists:duplicate(BlkSize, $5),
+ Blocks = [Block1, Block2, Block3, Block4, Block5],
+ Blob = list_to_binary(Blocks),
+ ?IGNORE(file:delete(RemoteFilename)),
+ ?VERIFY({error, enoent}, file:read_file(RemoteFilename)),
+
+ Timeout = timer:seconds(3),
+ ?VERIFY(timeout, recv(0)),
+
+ %% Open socket
+ {ok, Socket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+
+ WriteList = [0, 2, RemoteFilename, 0, "octet", 0],
+ NewPort =
+ if
+ BlkSize =:= 512 ->
+ %% Send WRITE
+ WriteBin = list_to_binary(WriteList),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, WriteBin)),
+
+ %% Sleep a while in order to provoke the server to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv ACK #0 (the packet that the server think that we have lost)
+ Ack0Bin = <<0, 4, 0, 0>>,
+ ?VERIFY({udp, Socket, Host, _, Ack0Bin}, recv(Timeout)),
+
+ %% Recv ACK #0 AGAIN (the re-sent package)
+ {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, Ack0Bin}, recv(Timeout)),
+ NewPort0;
+ true ->
+ %% Send WRITE
+ BlkSizeList = integer_to_list(BlkSize),
+ WriteBin = list_to_binary([WriteList, "blksize", 0, BlkSizeList, 0]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, WriteBin)),
+
+ %% Sleep a while in order to provoke the server to re-send the packet
+ timer:sleep(timer:seconds(1)),
+
+ %% Recv OACK (the packet that the server think that we have lost)
+ OptionAckBin = list_to_binary([0, 6, "blksize",0, BlkSizeList, 0]),
+ ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)),
+
+ %% Recv OACK AGAIN (the re-sent package)
+ {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)),
+ NewPort0
+ end,
+
+ %% Send DATA #1
+ Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data1Bin)),
+
+ %% Recv ACK #1
+ Ack1Bin = <<0, 4, 0, 1>>,
+ ?VERIFY({udp, Socket, Host, NewPort, Ack1Bin}, recv(Timeout)),
+
+ %% Send DATA #2
+ Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data2Bin)),
+
+ %% Recv ACK #2
+ Ack2Bin = <<0, 4, 0, 2>>,
+ ?VERIFY({udp, Socket, Host, NewPort, Ack2Bin}, recv(Timeout)),
+
+ %% Send DATA #3
+ Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data3Bin)),
+
+ %% Recv ACK #3
+ Ack3Bin = <<0, 4, 0, 3>>,
+ ?VERIFY({udp, Socket, Host, NewPort, Ack3Bin}, recv(Timeout)),
+
+ %% Send DATA #3 AGAIN (pretend that we timed out)
+ timer:sleep(timer:seconds(1)),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data3Bin)),
+
+ %% Recv ACK #3 AGAIN (the packet that the server think that we have lost)
+ ?VERIFY({udp, Socket, Host, NewPort, Ack3Bin}, recv(Timeout)),
+
+ %% Send DATA #2 which is out of range
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data2Bin)),
+
+ %% Send DATA #4
+ Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data4Bin)),
+
+ %% Recv ACK #4
+ Ack4Bin = <<0, 4, 0, 4>>,
+ ?VERIFY({udp, Socket, Host, NewPort, Ack4Bin}, recv(Timeout)),
+
+ %% Send DATA #5
+ Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data5Bin)),
+
+ %% Recv ACK #5
+ Ack5Bin = <<0, 4, 0, 5>>,
+ ?VERIFY({udp, Socket, Host, NewPort, Ack5Bin}, recv(Timeout)),
+
+ %% Close socket
+ ?VERIFY(ok, gen_udp:close(Socket)),
+
+ ?VERIFY(timeout, recv(Timeout)),
+ ?VERIFY({ok, Blob}, file:read_file(RemoteFilename)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Re-send server
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+resend_server(doc) ->
+ ["Verify that the server behaves correctly when the server re-sends packets."];
+resend_server(suite) ->
+ [];
+resend_server(Config) when is_list(Config) ->
+ Host = {127, 0, 0, 1},
+
+ ?VERIFY(ok, resend_read_server(Host, 10)),
+ ?VERIFY(ok, resend_read_server(Host, 512)),
+ ?VERIFY(ok, resend_read_server(Host, 1025)),
+
+ ?VERIFY(ok, resend_write_server(Host, 10)),
+ ?VERIFY(ok, resend_write_server(Host, 512)),
+ ?VERIFY(ok, resend_write_server(Host, 1025)),
+ ok.
+
+resend_read_server(Host, BlkSize) ->
+ RemoteFilename = "tftp_resend_read_server.tmp",
+ Block1 = lists:duplicate(BlkSize, $1),
+ Block2 = lists:duplicate(BlkSize, $2),
+ Block3 = lists:duplicate(BlkSize, $3),
+ Block4 = lists:duplicate(BlkSize, $4),
+ Block5 = lists:duplicate(BlkSize, $5),
+ Block6 = [],
+ Blocks = [Block1, Block2, Block3, Block4, Block5, Block6],
+ Blob = list_to_binary(Blocks),
+
+ Timeout = timer:seconds(3),
+ ?VERIFY(timeout, recv(0)),
+
+ %% Open daemon socket
+ {ok, DaemonSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+ {ok, DaemonPort} = ?IGNORE(inet:port(DaemonSocket)),
+
+ %% Open server socket
+ {ok, ServerSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+ ?IGNORE(inet:port(ServerSocket)),
+
+ %% Prepare client process
+ ReplyTo = self(),
+ ClientFun =
+ fun(Extra) ->
+ Options = [{port, DaemonPort}, {debug, brief}] ++ Extra,
+ Res = ?VERIFY({ok, Blob}, tftp:read_file(RemoteFilename, binary, Options)),
+ ReplyTo ! {self(), {tftp_client_reply, Res}},
+ exit(normal)
+ end,
+
+ ReadList = [0, 1, RemoteFilename, 0, "octet", 0],
+ Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]),
+ Ack1Bin = <<0, 4, 0, 1>>,
+ {ClientPort, ClientPid} =
+ if
+ BlkSize =:= 512 ->
+ %% Start client process
+ ClientPid0 = spawn_link(fun() -> ClientFun([]) end),
+
+ %% Recv READ
+ ReadBin = list_to_binary(ReadList),
+ {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, ReadBin}, recv(Timeout)),
+
+ %% Send DATA #1
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, Data1Bin)),
+
+ %% Sleep a while in order to provoke the client to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv ACK #1 (the packet that the server think that we have lost)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Ack1Bin}, recv(Timeout)),
+
+ %% Recv ACK #1 AGAIN (the re-sent package)
+ ?VERIFY({udp, ServerSocket, Host, _, Ack1Bin}, recv(Timeout)),
+ {ClientPort0, ClientPid0};
+ true ->
+ %% Start client process
+ BlkSizeList = integer_to_list(BlkSize),
+ ClientPid0 = spawn_link(fun() -> ClientFun([{"blksize", BlkSizeList}]) end),
+
+ %% Recv READ
+ Options = ["blksize", 0, BlkSizeList, 0],
+ ReadBin = list_to_binary([ReadList | Options]),
+ {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, ReadBin}, recv(Timeout)),
+
+ %% Send OACK
+ BlkSizeList = integer_to_list(BlkSize),
+ OptionAckBin = list_to_binary([0, 6, "blksize",0, BlkSizeList, 0]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, OptionAckBin)),
+
+ %% Sleep a while in order to provoke the client to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv ACK #0 (the packet that the server think that we have lost)
+ Ack0Bin = <<0, 4, 0, 0>>,
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Ack0Bin}, recv(Timeout)),
+
+ %% Recv ACK #0 AGAIN (the re-sent package)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Ack0Bin}, recv(Timeout)),
+
+ %% Send DATA #1
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, Data1Bin)),
+
+ %% Recv ACK #1
+ ?VERIFY({udp, ServerSocket, Host, _, Ack1Bin}, recv(Timeout)),
+ {ClientPort0, ClientPid0}
+ end,
+
+ %% Send DATA #2
+ Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data2Bin)),
+
+ %% Recv ACK #2
+ Ack2Bin = <<0, 4, 0, 2>>,
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack2Bin}, recv(Timeout)),
+
+ %% Send DATA #3
+ Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data3Bin)),
+
+ %% Recv ACK #3
+ Ack3Bin = <<0, 4, 0, 3>>,
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack3Bin}, recv(Timeout)),
+
+ %% Send DATA #3 AGAIN (pretend that we timed out)
+ timer:sleep(timer:seconds(1)),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data3Bin)),
+
+ %% Recv ACK #3 AGAIN (the packet that the server think that we have lost)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack3Bin}, recv(Timeout)),
+
+ %% Send DATA #4
+ Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data4Bin)),
+
+ %% Recv ACK #4
+ Ack4Bin = <<0, 4, 0, 4>>,
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack4Bin}, recv(Timeout)),
+
+ %% Send DATA #3 which is out of range
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data3Bin)),
+
+ %% Send DATA #5
+ Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data5Bin)),
+
+ %% Recv ACK #5
+ Ack5Bin = <<0, 4, 0, 5>>,
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack5Bin}, recv(Timeout)),
+
+ %% Send DATA #6
+ Data6Bin = list_to_binary([0, 3, 0, 6 | Block6]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data6Bin)),
+
+ %% Close daemon and server sockets
+ ?VERIFY(ok, gen_udp:close(ServerSocket)),
+ ?VERIFY(ok, gen_udp:close(DaemonSocket)),
+
+ ?VERIFY({ClientPid, {tftp_client_reply, {ok, Blob}}}, recv(Timeout)),
+
+ ?VERIFY(timeout, recv(Timeout)),
+ ok.
+
+resend_write_server(Host, BlkSize) ->
+ RemoteFilename = "tftp_resend_write_server.tmp",
+ Block1 = lists:duplicate(BlkSize, $1),
+ Block2 = lists:duplicate(BlkSize, $2),
+ Block3 = lists:duplicate(BlkSize, $3),
+ Block4 = lists:duplicate(BlkSize, $4),
+ Block5 = lists:duplicate(BlkSize, $5),
+ Block6 = [],
+ Blocks = [Block1, Block2, Block3, Block4, Block5, Block6],
+ Blob = list_to_binary(Blocks),
+ Size = size(Blob),
+
+ Timeout = timer:seconds(3),
+ ?VERIFY(timeout, recv(0)),
+
+ %% Open daemon socket
+ {ok, DaemonSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+ {ok, DaemonPort} = ?IGNORE(inet:port(DaemonSocket)),
+
+ %% Open server socket
+ {ok, ServerSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+ ?IGNORE(inet:port(ServerSocket)),
+
+ %% Prepare client process
+ ReplyTo = self(),
+ ClientFun =
+ fun(Extra) ->
+ Options = [{port, DaemonPort}, {debug, brief}] ++ Extra,
+ Res = ?VERIFY({ok, Size}, tftp:write_file(RemoteFilename, Blob, Options)),
+ ReplyTo ! {self(), {tftp_client_reply, Res}},
+ exit(normal)
+ end,
+
+ WriteList = [0, 2, RemoteFilename, 0, "octet", 0],
+ Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]),
+ {ClientPort, ClientPid} =
+ if
+ BlkSize =:= 512 ->
+ %% Start client process
+ ClientPid0 = spawn_link(fun() -> ClientFun([]) end),
+
+ %% Recv WRITE
+ WriteBin = list_to_binary(WriteList),
+ io:format("WriteBin ~p\n", [WriteBin]),
+ {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, WriteBin}, recv(Timeout)),
+
+ %% Send ACK #1
+ Ack0Bin = <<0, 4, 0, 0>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, Ack0Bin)),
+
+ %% Sleep a while in order to provoke the client to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv DATA #1 (the packet that the server think that we have lost)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Data1Bin}, recv(Timeout)),
+
+ %% Recv DATA #1 AGAIN (the re-sent package)
+ ?VERIFY({udp, ServerSocket, Host, _, Data1Bin}, recv(Timeout)),
+ {ClientPort0, ClientPid0};
+ true ->
+ %% Start client process
+ BlkSizeList = integer_to_list(BlkSize),
+ ClientPid0 = spawn_link(fun() -> ClientFun([{"blksize", BlkSizeList}]) end),
+
+ %% Recv WRITE
+ Options = ["blksize", 0, BlkSizeList, 0],
+ WriteBin = list_to_binary([WriteList | Options]),
+ {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, WriteBin}, recv(Timeout)),
+
+ %% Send OACK
+ BlkSizeList = integer_to_list(BlkSize),
+ OptionAckBin = list_to_binary([0, 6, "blksize",0, BlkSizeList, 0]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, OptionAckBin)),
+
+ %% Sleep a while in order to provoke the client to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv DATA #1 (the packet that the server think that we have lost)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Data1Bin}, recv(Timeout)),
+
+ %% Recv DATA #1 AGAIN (the re-sent package)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Data1Bin}, recv(Timeout)),
+ {ClientPort0, ClientPid0}
+ end,
+
+ %% Send ACK #1
+ Ack1Bin = <<0, 4, 0, 1>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack1Bin)),
+
+ %% Recv DATA #2
+ Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]),
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data2Bin}, recv(Timeout)),
+
+ %% Send ACK #2
+ Ack2Bin = <<0, 4, 0, 2>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack2Bin)),
+
+ %% Recv DATA #3
+ Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]),
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data3Bin}, recv(Timeout)),
+
+ %% Send ACK #3
+ Ack3Bin = <<0, 4, 0, 3>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack3Bin)),
+
+ %% Send ACK #3 AGAIN (pretend that we timed out)
+ timer:sleep(timer:seconds(1)),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack3Bin)),
+
+ %% Recv DATA #4 (the packet that the server think that we have lost)
+ Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]),
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data4Bin}, recv(Timeout)),
+
+ %% Recv DATA #4 AGAIN (the re-sent package)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data4Bin}, recv(Timeout)),
+
+ %% Send ACK #4
+ Ack4Bin = <<0, 4, 0, 4>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack4Bin)),
+
+ %% Recv DATA #5
+ Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]),
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data5Bin}, recv(Timeout)),
+
+ %% Send ACK #3 which is out of range
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack3Bin)),
+
+ %% Send ACK #5
+ Ack5Bin = <<0, 4, 0, 5>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack5Bin)),
+
+ %% Recv DATA #6
+ Data6Bin = list_to_binary([0, 3, 0, 6 | Block6]),
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data6Bin}, recv(Timeout)),
+
+ %% Send ACK #6
+ Ack6Bin = <<0, 4, 0, 6>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack6Bin)),
+
+ %% Close daemon and server sockets
+ ?VERIFY(ok, gen_udp:close(ServerSocket)),
+ ?VERIFY(ok, gen_udp:close(DaemonSocket)),
+
+ ?VERIFY({ClientPid, {tftp_client_reply, {ok, Size}}}, recv(Timeout)),
+
+ ?VERIFY(timeout, recv(Timeout)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+reuse_connection(doc) ->
+ ["Verify that the server can reuse an ongiong connection when same client resends request."];
+reuse_connection(suite) ->
+ [];
+reuse_connection(Config) when is_list(Config) ->
+ Host = {127, 0, 0, 1},
+ {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, all}])),
+
+ RemoteFilename = "reuse_connection.tmp",
+ BlkSize = 512,
+ Block1 = lists:duplicate(BlkSize, $1),
+ Block2 = lists:duplicate(BlkSize div 2, $2),
+ Blocks = [Block1, Block2],
+ Blob = list_to_binary(Blocks),
+ ?VERIFY(ok, file:write_file(RemoteFilename, Blob)),
+
+ Seconds = 3,
+ Timeout = timer:seconds(Seconds),
+ ?VERIFY(timeout, recv(0)),
+
+ %% Open socket
+ {ok, Socket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+
+ ReadList = [0, 1, RemoteFilename, 0, "octet", 0],
+ Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]),
+
+ %% Send READ
+ TimeoutList = integer_to_list(Seconds),
+ Options = ["timeout", 0, TimeoutList, 0],
+ ReadBin = list_to_binary([ReadList | Options]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)),
+
+ %% Send yet another READ for same file
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)),
+
+ %% Recv OACK
+ OptionAckBin = list_to_binary([0, 6 | Options]),
+ {udp, _, _, NewPort, _} = ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)),
+
+ %% Send ACK #0
+ Ack0Bin = <<0, 4, 0, 0>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack0Bin)),
+
+ %% Recv DATA #1
+ ?VERIFY({udp, Socket, Host, NewPort, Data1Bin}, recv(Timeout)),
+
+ %% Send ACK #1
+ Ack1Bin = <<0, 4, 0, 1>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack1Bin)),
+
+ %% Recv DATA #2
+ Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]),
+ ?VERIFY({udp, Socket, Host, NewPort, Data2Bin}, recv(Timeout)),
+
+ %% Send ACK #2
+ Ack2Bin = <<0, 4, 0, 2>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack2Bin)),
+
+ %% Close socket
+ ?VERIFY(ok, gen_udp:close(Socket)),
+
+ ?VERIFY(timeout, recv(Timeout)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+
+ %% Cleanup
+ unlink(DaemonPid),
+ exit(DaemonPid, kill),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Goodies
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+recv(Timeout) ->
+ receive
+ Msg ->
+ Msg
+ after Timeout ->
+ timeout
+ end.
diff --git a/lib/inets/test/tftp_test_lib.erl b/lib/inets/test/tftp_test_lib.erl
new file mode 100644
index 0000000000..3729309b0e
--- /dev/null
+++ b/lib/inets/test/tftp_test_lib.erl
@@ -0,0 +1,307 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(tftp_test_lib).
+
+-compile(export_all).
+
+-include("tftp_test_lib.hrl").
+
+%%
+%% -----
+%%
+
+init_per_testcase(_Case, Config) when is_list(Config) ->
+ io:format("\n ", []),
+ ?IGNORE(application:stop(inets)),
+ Config.
+
+fin_per_testcase(_Case, Config) when is_list(Config) ->
+ ?IGNORE(application:stop(inets)),
+ Config.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Infrastructure for test suite
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+error(Actual, Mod, Line) ->
+ (catch global:send(tftp_global_logger, {failed, Mod, Line})),
+ log("<ERROR> Bad result: ~p\n", [Actual], Mod, Line),
+ Label = lists:concat([Mod, "(", Line, ") unexpected result"]),
+ et:report_event(60, Mod, Mod, Label,
+ [{line, Mod, Line}, {error, Actual}]),
+ case global:whereis_name(tftp_test_case_sup) of
+ undefined ->
+ ignore;
+ Pid ->
+ Fail = #'REASON'{mod = Mod, line = Line, desc = Actual},
+ Pid ! {fail, self(), Fail}
+ end,
+ Actual.
+
+log(Format, Args, Mod, Line) ->
+ case global:whereis_name(tftp_global_logger) of
+ undefined ->
+ io:format(user, "~p(~p): " ++ Format,
+ [Mod, Line] ++ Args);
+ Pid ->
+ io:format(Pid, "~p(~p): " ++ Format,
+ [Mod, Line] ++ Args)
+ end.
+
+default_config() ->
+ [].
+
+t() ->
+ t([{?MODULE, all}]).
+
+t(Cases) ->
+ t(Cases, default_config()).
+
+t(Cases, Config) ->
+ process_flag(trap_exit, true),
+ Res = lists:flatten(do_test(Cases, Config)),
+ io:format("Res: ~p\n", [Res]),
+ display_result(Res),
+ Res.
+
+do_test({Mod, Fun}, Config) when is_atom(Mod), is_atom(Fun) ->
+ case catch apply(Mod, Fun, [suite]) of
+ [] ->
+ io:format("Eval: ~p:", [{Mod, Fun}]),
+ Res = eval(Mod, Fun, Config),
+ {R, _, _} = Res,
+ io:format(" ~p\n", [R]),
+ Res;
+
+ Cases when is_list(Cases) ->
+ io:format("Expand: ~p ...\n", [{Mod, Fun}]),
+ Map = fun(Case) when is_atom(Case)-> {Mod, Case};
+ (Case) -> Case
+ end,
+ do_test(lists:map(Map, Cases), Config);
+
+ {req, _, {conf, Init, Cases, Finish}} ->
+ case (catch apply(Mod, Init, [Config])) of
+ Conf when is_list(Conf) ->
+ io:format("Expand: ~p ...\n", [{Mod, Fun}]),
+ Map = fun(Case) when is_atom(Case)-> {Mod, Case};
+ (Case) -> Case
+ end,
+ Res = do_test(lists:map(Map, Cases), Conf),
+ (catch apply(Mod, Finish, [Conf])),
+ Res;
+
+ {'EXIT', {skipped, Reason}} ->
+ io:format(" => skipping: ~p\n", [Reason]),
+ [{skipped, {Mod, Fun}, Reason}];
+
+ Error ->
+ io:format(" => failed: ~p\n", [Error]),
+ [{failed, {Mod, Fun}, Error}]
+ end;
+
+ {'EXIT', {undef, _}} ->
+ io:format("Undefined: ~p\n", [{Mod, Fun}]),
+ [{nyi, {Mod, Fun}, ok}];
+
+ Error ->
+ io:format("Ignoring: ~p: ~p\n", [{Mod, Fun}, Error]),
+ [{failed, {Mod, Fun}, Error}]
+ end;
+do_test(Mod, Config) when is_atom(Mod) ->
+ Res = do_test({Mod, all}, Config),
+ Res;
+do_test(Cases, Config) when is_list(Cases) ->
+ [do_test(Case, Config) || Case <- Cases];
+do_test(Bad, _Config) ->
+ [{badarg, Bad, ok}].
+
+eval(Mod, Fun, Config) ->
+ TestCase = {?MODULE, Mod, Fun},
+ Label = lists:concat(["TEST CASE: ", Fun]),
+ et:report_event(40, ?MODULE, Mod, Label ++ " started",
+ [TestCase, Config]),
+ global:register_name(tftp_test_case_sup, self()),
+ Flag = process_flag(trap_exit, true),
+ Config2 = Mod:init_per_testcase(Fun, Config),
+ Pid = spawn_link(?MODULE, do_eval, [self(), Mod, Fun, Config2]),
+ R = wait_for_evaluator(Pid, Mod, Fun, Config2, []),
+ Mod:fin_per_testcase(Fun, Config2),
+ global:unregister_name(tftp_test_case_sup),
+ process_flag(trap_exit, Flag),
+ R.
+
+wait_for_evaluator(Pid, Mod, Fun, Config, Errors) ->
+ TestCase = {?MODULE, Mod, Fun},
+ Label = lists:concat(["TEST CASE: ", Fun]),
+ receive
+ {done, Pid, ok} when Errors == [] ->
+ et:report_event(40, Mod, ?MODULE, Label ++ " ok",
+ [TestCase, Config]),
+ {ok, {Mod, Fun}, Errors};
+ {done, Pid, {ok, _}} when Errors == [] ->
+ et:report_event(40, Mod, ?MODULE, Label ++ " ok",
+ [TestCase, Config]),
+ {ok, {Mod, Fun}, Errors};
+ {done, Pid, Fail} ->
+ et:report_event(20, Mod, ?MODULE, Label ++ " failed",
+ [TestCase, Config, {return, Fail}, Errors]),
+ {failed, {Mod,Fun}, Fail};
+ {'EXIT', Pid, {skipped, Reason}} ->
+ et:report_event(20, Mod, ?MODULE, Label ++ " skipped",
+ [TestCase, Config, {skipped, Reason}]),
+ {skipped, {Mod, Fun}, Errors};
+ {'EXIT', Pid, Reason} ->
+ et:report_event(20, Mod, ?MODULE, Label ++ " crashed",
+ [TestCase, Config, {'EXIT', Reason}]),
+ {crashed, {Mod, Fun}, [{'EXIT', Reason} | Errors]};
+ {fail, Pid, Reason} ->
+ wait_for_evaluator(Pid, Mod, Fun, Config, Errors ++ [Reason])
+ end.
+
+do_eval(ReplyTo, Mod, Fun, Config) ->
+ case (catch apply(Mod, Fun, [Config])) of
+ {'EXIT', {skipped, Reason}} ->
+ ReplyTo ! {'EXIT', self(), {skipped, Reason}};
+ Other ->
+ ReplyTo ! {done, self(), Other}
+ end,
+ unlink(ReplyTo),
+ exit(shutdown).
+
+display_result([]) ->
+ io:format("OK\n", []);
+display_result(Res) when is_list(Res) ->
+ Ok = [MF || {ok, MF, _} <- Res],
+ Nyi = [MF || {nyi, MF, _} <- Res],
+ Skipped = [{MF, Reason} || {skipped, MF, Reason} <- Res],
+ Failed = [{MF, Reason} || {failed, MF, Reason} <- Res],
+ Crashed = [{MF, Reason} || {crashed, MF, Reason} <- Res],
+ display_summary(Ok, Nyi, Skipped, Failed, Crashed),
+ display_skipped(Skipped),
+ display_failed(Failed),
+ display_crashed(Crashed).
+
+display_summary(Ok, Nyi, Skipped, Failed, Crashed) ->
+ io:format("\nTest case summary:\n", []),
+ display_summary(Ok, "successful"),
+ display_summary(Nyi, "not yet implemented"),
+ display_summary(Skipped, "skipped"),
+ display_summary(Failed, "failed"),
+ display_summary(Crashed, "crashed"),
+ io:format("\n", []).
+
+display_summary(Res, Info) ->
+ io:format(" ~w test cases ~s\n", [length(Res), Info]).
+
+display_skipped([]) ->
+ ok;
+display_skipped(Skipped) ->
+ io:format("Skipped test cases:\n", []),
+ F = fun({MF, Reason}) -> io:format(" ~p => ~p\n", [MF, Reason]) end,
+ lists:foreach(F, Skipped),
+ io:format("\n", []).
+
+
+display_failed([]) ->
+ ok;
+display_failed(Failed) ->
+ io:format("Failed test cases:\n", []),
+ F = fun({MF, Reason}) -> io:format(" ~p => ~p\n", [MF, Reason]) end,
+ lists:foreach(F, Failed),
+ io:format("\n", []).
+
+display_crashed([]) ->
+ ok;
+display_crashed(Crashed) ->
+ io:format("Crashed test cases:\n", []),
+ F = fun({MF, Reason}) -> io:format(" ~p => ~p\n", [MF, Reason]) end,
+ lists:foreach(F, Crashed),
+ io:format("\n", []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% generic callback
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-record(generic_state, {state, prepare, open, read, write, abort}).
+
+prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, Initial) when is_list(Initial) ->
+ State = lookup_option(state, mandatory, Initial),
+ Prepare = lookup_option(prepare, mandatory, Initial),
+ Open = lookup_option(open, mandatory, Initial),
+ Read = lookup_option(read, mandatory, Initial),
+ Write = lookup_option(write, mandatory, Initial),
+ Abort = lookup_option(abort, mandatory, Initial),
+ case Prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, State) of
+ {ok, AcceptedOptions, NewState} ->
+ {ok,
+ AcceptedOptions,
+ #generic_state{state = NewState,
+ prepare = Prepare,
+ open = Open,
+ read = Read,
+ write = Write,
+ abort = Abort}};
+ Other ->
+ Other
+ end.
+
+open(Peer, Access, LocalFilename, Mode, SuggestedOptions, Initial) when is_list(Initial) ->
+ case prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, Initial) of
+ {ok, SuggestedOptions2, GenericState} ->
+ open(Peer, Access, LocalFilename, Mode, SuggestedOptions2, GenericState);
+ Other ->
+ Other
+ end;
+open(Peer, Access, LocalFilename, Mode, SuggestedOptions, #generic_state{state = State, open = Open} = GenericState) ->
+ case Open(Peer, Access, LocalFilename, Mode, SuggestedOptions, State) of
+ {ok, SuggestedOptions2, NewState} ->
+ {ok, SuggestedOptions2, GenericState#generic_state{state = NewState}};
+ Other ->
+ Other
+ end.
+
+read(#generic_state{state = State, read = Read} = GenericState) ->
+ case Read(State) of
+ {more, DataBlock, NewState} ->
+ {more, DataBlock, GenericState#generic_state{state = NewState}};
+ Other ->
+ Other
+ end.
+
+write(DataBlock, #generic_state{state = State, write = Write} = GenericState) ->
+ case Write(DataBlock, State) of
+ {more, NewState} ->
+ {more, GenericState#generic_state{state = NewState}};
+ Other ->
+ Other
+ end.
+
+abort(Code, Text, #generic_state{state = State, abort = Abort}) ->
+ Abort(Code, Text, State).
+
+lookup_option(Key, Default, Options) ->
+ case lists:keysearch(Key, 1, Options) of
+ {value, {_, Val}} ->
+ Val;
+ false ->
+ Default
+ end.
+
diff --git a/lib/inets/test/tftp_test_lib.hrl b/lib/inets/test/tftp_test_lib.hrl
new file mode 100644
index 0000000000..da4b065976
--- /dev/null
+++ b/lib/inets/test/tftp_test_lib.hrl
@@ -0,0 +1,43 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-record('REASON', {mod, line, desc}).
+
+-define(LOG(Format, Args),
+ tftp_test_lib:log(Format, Args, ?MODULE, ?LINE)).
+
+-define(ERROR(Reason),
+ tftp_test_lib:error(Reason, ?MODULE, ?LINE)).
+
+-define(VERIFY(Expected, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Expected -> ?LOG("Ok, ~p\n", [AcTuAlReS]);
+ _ -> ?ERROR(AcTuAlReS)
+ end,
+ AcTuAlReS
+ end()).
+
+-define(IGNORE(Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ ?LOG("Ok, ~p\n", [AcTuAlReS]),
+ AcTuAlReS
+ end()).
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index 8ed4f0c192..746517eed5 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -1,27 +1,42 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
-INETS_VSN = 5.2.0.1
-PRE_VSN =
-APP_VSN = "inets-$(INETS_VSN)$(PRE_VSN)"
+APPLICATION = inets
+INETS_VSN = 5.3
+PRE_VSN =-p13
+APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
+
+TICKETS = \
+ OTP-8016 \
+ OTP-8056 \
+ OTP-8103 \
+ OTP-8106 \
+ OTP-8312 \
+ OTP-8315 \
+ OTP-8327 \
+ OTP-8349 \
+ OTP-8351 \
+ OTP-8352 \
+ OTP-8359 \
+ OTP-8371
-TICKETS = OTP-8204 OTP-8206 OTP-8247 OTP-8248 OTP-8249 OTP-8258 OTP-8280
+TICKETS_5_2 = OTP-8204 OTP-8206 OTP-8247 OTP-8248 OTP-8249 OTP-8258 OTP-8280
TICKETS_5_1_3 = OTP-8154
diff --git a/lib/jinterface/doc/src/Makefile b/lib/jinterface/doc/src/Makefile
index c4cfde0e9c..acd5307dee 100644
--- a/lib/jinterface/doc/src/Makefile
+++ b/lib/jinterface/doc/src/Makefile
@@ -2,20 +2,20 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
@@ -53,6 +53,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES = \
notes.gif \
ref_man.gif \
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index ef280058fb..cd011f09fe 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -154,7 +154,7 @@ debug opt: $(TARGET_FILES)
# Note: In the open-source build clean must not destroyed the preloaded
# beam files.
clean:
- rm -f $(NON_PRECIOUS_TARGETS)
+ rm -f $(TARGET_FILES)
rm -f core
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index fef11d7e6e..89d893f8c1 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(code).
@@ -63,7 +63,7 @@
which/1,
where_is_file/1,
where_is_file/2,
- set_primary_archive/2,
+ set_primary_archive/3,
clash/0]).
-include_lib("kernel/include/file.hrl").
@@ -101,7 +101,7 @@
%% unstick_dir(Dir) -> ok | error
%% is_sticky(Module) -> true | false
%% which(Module) -> Filename
-%% set_primary_archive((FileName, Bin) -> ok | {error, Reason}
+%% set_primary_archive((FileName, Bin, FileInfo) -> ok | {error, Reason}
%% clash() -> -> print out
%%----------------------------------------------------------------------------
@@ -420,11 +420,15 @@ where_is_file(Path, File) when is_list(Path), is_list(File) ->
which(File, ".", Path)
end.
--spec set_primary_archive(ArchiveFile :: file:filename(), ArchiveBin :: binary()) -> 'ok' | {'error', atom()}.
+-spec set_primary_archive(ArchiveFile :: file:filename(),
+ ArchiveBin :: binary(),
+ FileInfo :: #file_info{})
+ -> 'ok' | {'error', atom()}.
-set_primary_archive(ArchiveFile0, ArchiveBin) when is_list(ArchiveFile0), is_binary(ArchiveBin) ->
+set_primary_archive(ArchiveFile0, ArchiveBin, FileInfo)
+ when is_list(ArchiveFile0), is_binary(ArchiveBin), is_record(FileInfo, file_info) ->
ArchiveFile = filename:absname(ArchiveFile0),
- case call({set_primary_archive, ArchiveFile, ArchiveBin}) of
+ case call({set_primary_archive, ArchiveFile, ArchiveBin, FileInfo}) of
{ok, []} ->
ok;
{ok, _Mode, Ebins} ->
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index d4e3f0bcf8..7aeddb73d1 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(code_server).
@@ -384,8 +384,8 @@ handle_call(stop,{_From,_Tag}, S) ->
handle_call({is_cached,_File}, {_From,_Tag}, S=#state{cache=no_cache}) ->
{reply, no, S};
-handle_call({set_primary_archive, File, ArchiveBin}, {_From,_Tag}, S=#state{mode=Mode}) ->
- case erl_prim_loader:set_primary_archive(File, ArchiveBin) of
+handle_call({set_primary_archive, File, ArchiveBin, FileInfo}, {_From,_Tag}, S=#state{mode=Mode}) ->
+ case erl_prim_loader:set_primary_archive(File, ArchiveBin, FileInfo) of
{ok, Files} ->
{reply, {ok, Mode, Files}, S};
{error, Reason} ->
diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl
index 7e26d57ced..42eab67478 100644
--- a/lib/kernel/src/hipe_unified_loader.erl
+++ b/lib/kernel/src/hipe_unified_loader.erl
@@ -96,6 +96,14 @@ load_hipe_modules() ->
%% code:load_file/1) and the atom `no_native' on failure.
load_native_code(Mod, Bin) when is_atom(Mod), is_binary(Bin) ->
+ erlang:system_flag(multi_scheduling, block),
+ try
+ load_native_code_nosmp(Mod, Bin)
+ after
+ erlang:system_flag(multi_scheduling, unblock)
+ end.
+
+load_native_code_nosmp(Mod, Bin) ->
Architecture = erlang:system_info(hipe_architecture),
try chunk_name(Architecture) of
ChunkTag ->
@@ -120,6 +128,14 @@ load_native_code(Mod, Bin) when is_atom(Mod), is_binary(Bin) ->
-spec post_beam_load(atom()) -> 'ok'.
post_beam_load(Mod) when is_atom(Mod) ->
+ erlang:system_flag(multi_scheduling, block),
+ try
+ post_beam_load_nosmp(Mod)
+ after
+ erlang:system_flag(multi_scheduling, unblock)
+ end.
+
+post_beam_load_nosmp(Mod) ->
Architecture = erlang:system_info(hipe_architecture),
try chunk_name(Architecture) of _ChunkTag -> patch_to_emu(Mod)
catch _:_ -> ok
@@ -141,6 +157,14 @@ version_check(Version, Mod) when is_atom(Mod) ->
-spec load_module(Mod, binary(), _) -> 'bad_crc' | {'module',Mod}
when is_subtype(Mod,atom()).
load_module(Mod, Bin, Beam) ->
+ erlang:system_flag(multi_scheduling, block),
+ try
+ load_module_nosmp(Mod, Bin, Beam)
+ after
+ erlang:system_flag(multi_scheduling, unblock)
+ end.
+
+load_module_nosmp(Mod, Bin, Beam) ->
load_module(Mod, Bin, Beam, []).
load_module(Mod, Bin, Beam, OldReferencesToPatch) ->
@@ -154,6 +178,14 @@ load_module(Mod, Bin, Beam, OldReferencesToPatch) ->
-spec load(Mod, binary()) -> 'bad_crc' | {'module',Mod}
when is_subtype(Mod,atom()).
load(Mod, Bin) ->
+ erlang:system_flag(multi_scheduling, block),
+ try
+ load_nosmp(Mod, Bin)
+ after
+ erlang:system_flag(multi_scheduling, unblock)
+ end.
+
+load_nosmp(Mod, Bin) ->
?debug_msg("********* Loading funs in module ~w *********\n",[Mod]),
%% Loading just some functions in a module; patch closures separately.
put(hipe_patch_closures, true),
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index ffad998d96..293c368e2a 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
@@ -116,7 +116,7 @@ EBIN = .
make_emakefile:
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' \
- >> $(EMAKEFILE)
+ > $(EMAKEFILE)
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
>> $(EMAKEFILE)
diff --git a/lib/kernel/test/bif_SUITE.erl b/lib/kernel/test/bif_SUITE.erl
index c78d82659f..ae2a3a08ff 100644
--- a/lib/kernel/test/bif_SUITE.erl
+++ b/lib/kernel/test/bif_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(bif_SUITE).
@@ -66,7 +66,7 @@ spawn_opt_tests(suite) ->
spawn1(doc) -> ["Test spawn/1"];
spawn1(suite) ->
[];
-spawn1(Config) when list(Config) ->
+spawn1(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -83,7 +83,7 @@ spawn1(Config) when list(Config) ->
spawn2(doc) -> ["Test spawn/2"];
spawn2(suite) ->
[];
-spawn2(Config) when list(Config) ->
+spawn2(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn2),
?line Parent = self(),
@@ -105,7 +105,7 @@ spawn2(Config) when list(Config) ->
spawn3(doc) -> ["Test spawn/3"];
spawn3(suite) ->
[];
-spawn3(Config) when list(Config) ->
+spawn3(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
@@ -127,7 +127,7 @@ spawn3(Config) when list(Config) ->
spawn4(doc) -> ["Test spawn/4"];
spawn4(suite) ->
[];
-spawn4(Config) when list(Config) ->
+spawn4(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn4),
?line Parent = self(),
@@ -154,7 +154,7 @@ spawn4(Config) when list(Config) ->
spawn_link1(doc) -> ["Test spawn_link/1"];
spawn_link1(suite) ->
[];
-spawn_link1(Config) when list(Config) ->
+spawn_link1(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -171,7 +171,7 @@ spawn_link1(Config) when list(Config) ->
spawn_link2(doc) -> ["Test spawn_link/2"];
spawn_link2(suite) ->
[];
-spawn_link2(Config) when list(Config) ->
+spawn_link2(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn_link2),
?line Parent = self(),
@@ -192,7 +192,7 @@ spawn_link2(Config) when list(Config) ->
spawn_link3(doc) -> ["Test spawn_link/3"];
spawn_link3(suite) ->
[];
-spawn_link3(Config) when list(Config) ->
+spawn_link3(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
@@ -214,7 +214,7 @@ spawn_link3(Config) when list(Config) ->
spawn_link4(doc) -> ["Test spawn_link/4"];
spawn_link4(suite) ->
[];
-spawn_link4(Config) when list(Config) ->
+spawn_link4(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn_link4),
?line Parent = self(),
@@ -240,7 +240,7 @@ spawn_link4(Config) when list(Config) ->
spawn_opt2(doc) -> ["Test spawn_opt/2"];
spawn_opt2(suite) ->
[];
-spawn_opt2(Config) when list(Config) ->
+spawn_opt2(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -275,7 +275,7 @@ spawn_opt2(Config) when list(Config) ->
spawn_opt3(doc) -> ["Test spawn_opt/3"];
spawn_opt3(suite) ->
[];
-spawn_opt3(Config) when list(Config) ->
+spawn_opt3(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn_opt3),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -312,7 +312,7 @@ spawn_opt3(Config) when list(Config) ->
spawn_opt4(doc) -> ["Test spawn_opt/4"];
spawn_opt4(suite) ->
[];
-spawn_opt4(Config) when list(Config) ->
+spawn_opt4(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -352,7 +352,7 @@ spawn_opt4(Config) when list(Config) ->
spawn_opt5(doc) -> ["Test spawn_opt/5"];
spawn_opt5(suite) ->
[];
-spawn_opt5(Config) when list(Config) ->
+spawn_opt5(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn_opt5),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -396,7 +396,7 @@ spawn_failures(doc) ->
["Test failure behavior of spawn bifs"];
spawn_failures(suite) ->
[];
-spawn_failures(Config) when list(Config) ->
+spawn_failures(Config) when is_list(Config) ->
?line ThisNode = node(),
?line {ok, Node} = start_node(spawn_remote_failure),
@@ -556,7 +556,7 @@ wilderness(doc) ->
"wilderness of the heap are interpreted correct by the emulator "];
wilderness(suite) ->
[];
-wilderness(Config) when list(Config) ->
+wilderness(Config) when is_list(Config) ->
?line Dog = ?t:timetrap(?default_timeout),
?line OKParams = {512, 8},
?line Alloc = erlang:system_info(allocator),
@@ -604,11 +604,11 @@ run_wilderness_test({Set_tt, Set_tp}, {Exp_tt, Exp_tp}) ->
end,
stop_node(Node).
-to_string(X) when integer(X) ->
+to_string(X) when is_integer(X) ->
integer_to_list(X);
-to_string(X) when atom(X) ->
+to_string(X) when is_atom(X) ->
atom_to_list(X);
-to_string(X) when list(X) ->
+to_string(X) when is_list(X) ->
X.
get_nodenames(N, T) ->
diff --git a/lib/kernel/test/cleanup.erl b/lib/kernel/test/cleanup.erl
index 6e1a1edeac..831ceba8f5 100644
--- a/lib/kernel/test/cleanup.erl
+++ b/lib/kernel/test/cleanup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(cleanup).
@@ -31,7 +31,7 @@ cleanup(_) ->
?line case nodes() of
[] ->
ok;
- Nodes when list(Nodes) ->
+ Nodes when is_list(Nodes) ->
Kill = fun(Node) -> spawn(Node, erlang, halt, []) end,
?line lists:foreach(Kill, Nodes),
?line test_server:fail({nodes_left, Nodes})
diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index 8f2e2512e0..d15f6aa0d5 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(erl_distribution_SUITE).
@@ -62,7 +62,7 @@ all(suite) ->
table_waste, net_setuptime,
monitor_nodes].
-init_per_testcase(Func, Config) when atom(Func), list(Config) ->
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(4)),
[{watchdog, Dog}|Config].
@@ -72,7 +72,7 @@ fin_per_testcase(_Func, Config) ->
tick(suite) -> [];
tick(doc) -> [];
-tick(Config) when list(Config) ->
+tick(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(120)),
PaDir = filename:dirname(code:which(erl_distribution_SUITE)),
@@ -119,7 +119,7 @@ tick(Config) when list(Config) ->
monitor_node(Node, true),
receive
- {tick_test, T} when integer(T) ->
+ {tick_test, T} when is_integer(T) ->
stop_node(ServNode),
stop_node(Node),
T;
@@ -141,7 +141,7 @@ table_waste(doc) ->
["Checks that pinging nonexistyent nodes does not waste space in distribution table"];
table_waste(suite) ->
[];
-table_waste(Config) when list(Config) ->
+table_waste(Config) when is_list(Config) ->
?line {ok, HName} = inet:gethostname(),
F = fun(0,_F) -> [];
(N,F) ->
@@ -161,7 +161,7 @@ illegal_nodenames(doc) ->
["Test that pinging an illegal nodename does not kill the node"];
illegal_nodenames(suite) ->
[];
-illegal_nodenames(Config) when list(Config) ->
+illegal_nodenames(Config) when is_list(Config) ->
?line Dog=?t:timetrap(?t:minutes(2)),
PaDir = filename:dirname(code:which(erl_distribution_SUITE)),
?line {ok, Node}=start_node(illegal_nodenames, "-pa " ++ PaDir),
@@ -269,12 +269,12 @@ tick_cli_test1(Node) ->
tick_change(doc) -> ["OTP-4255"];
tick_change(suite) -> [];
-tick_change(Config) when list(Config) ->
+tick_change(Config) when is_list(Config) ->
?line PaDir = filename:dirname(code:which(?MODULE)),
?line [BN, CN] = get_nodenames(2, tick_change),
?line DefaultTT = net_kernel:get_net_ticktime(),
?line case DefaultTT of
- I when integer(I) -> ?line ok;
+ I when is_integer(I) -> ?line ok;
_ -> ?line ?t:fail(DefaultTT)
end,
@@ -445,7 +445,7 @@ hidden_node(doc) ->
["Basic test of hidden node"];
hidden_node(suite) ->
[];
-hidden_node(Config) when list(Config) ->
+hidden_node(Config) when is_list(Config) ->
?line Dog = ?t:timetrap(?t:seconds(40)),
PaDir = filename:dirname(code:which(?MODULE)),
VArgs = "-pa " ++ PaDir,
@@ -548,7 +548,7 @@ monitor_nodes(suite) ->
monitor_nodes_nodedown_reason(doc) -> [];
monitor_nodes_nodedown_reason(suite) -> [];
-monitor_nodes_nodedown_reason(Config) when list(Config) ->
+monitor_nodes_nodedown_reason(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line ok = net_kernel:monitor_nodes(true),
?line ok = net_kernel:monitor_nodes(true, [nodedown_reason]),
@@ -603,7 +603,7 @@ monitor_nodes_nodedown_reason(Config) when list(Config) ->
monitor_nodes_complex_nodedown_reason(doc) -> [];
monitor_nodes_complex_nodedown_reason(suite) -> [];
-monitor_nodes_complex_nodedown_reason(Config) when list(Config) ->
+monitor_nodes_complex_nodedown_reason(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line Me = self(),
?line ok = net_kernel:monitor_nodes(true, [nodedown_reason]),
@@ -885,7 +885,7 @@ monitor_nodes_errors(doc) ->
[];
monitor_nodes_errors(suite) ->
[];
-monitor_nodes_errors(Config) when list(Config) ->
+monitor_nodes_errors(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line error = net_kernel:monitor_nodes(asdf),
?line {error,
@@ -922,7 +922,7 @@ monitor_nodes_combinations(doc) ->
[];
monitor_nodes_combinations(suite) ->
[];
-monitor_nodes_combinations(Config) when list(Config) ->
+monitor_nodes_combinations(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line monitor_nodes_all_comb(true),
?line [VisibleName, HiddenName] = get_nodenames(2,
@@ -1044,7 +1044,7 @@ monitor_nodes_cleanup(doc) ->
[];
monitor_nodes_cleanup(suite) ->
[];
-monitor_nodes_cleanup(Config) when list(Config) ->
+monitor_nodes_cleanup(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line Me = self(),
?line No = monitor_nodes_all_comb(true),
@@ -1076,7 +1076,7 @@ monitor_nodes_many(doc) ->
[];
monitor_nodes_many(suite) ->
[];
-monitor_nodes_many(Config) when list(Config) ->
+monitor_nodes_many(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line [Name] = get_nodenames(1, monitor_nodes_many),
%% We want to perform more than 2^16 net_kernel:monitor_nodes
@@ -1139,10 +1139,10 @@ start_node(Name, Param, this) ->
start_node(Name, Param, "this") ->
NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
?t:start_node(Name, peer, [{args, NewParam}, {erl, [this]}]);
-start_node(Name, Param, Rel) when atom(Rel) ->
+start_node(Name, Param, Rel) when is_atom(Rel) ->
NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
?t:start_node(Name, peer, [{args, NewParam}, {erl, [{release, atom_to_list(Rel)}]}]);
-start_node(Name, Param, Rel) when list(Rel) ->
+start_node(Name, Param, Rel) when is_list(Rel) ->
NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
?t:start_node(Name, peer, [{args, NewParam}, {erl, [{release, Rel}]}]).
@@ -1216,9 +1216,9 @@ wait_until(Fun) ->
end
end.
-repeat(Fun, 0) when function(Fun) ->
+repeat(Fun, 0) when is_function(Fun) ->
ok;
-repeat(Fun, N) when function(Fun), integer(N), N > 0 ->
+repeat(Fun, N) when is_function(Fun), is_integer(N), N > 0 ->
Fun(),
repeat(Fun, N-1).
diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl
index 4d090f4db5..19c84ab34c 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(erl_prim_loader_SUITE).
@@ -27,7 +27,7 @@
inet_existing/1, inet_coming_up/1, inet_disconnects/1,
multiple_slaves/1, file_requests/1,
local_archive/1, remote_archive/1,
- primary_archive/1]).
+ primary_archive/1, virtual_dir_in_archive/1]).
-export([init_per_testcase/2, fin_per_testcase/2]).
@@ -41,10 +41,11 @@ all(suite) ->
inet_existing, inet_coming_up,
inet_disconnects, multiple_slaves,
file_requests, local_archive,
- remote_archive, primary_archive
+ remote_archive, primary_archive,
+ virtual_dir_in_archive
].
-init_per_testcase(Func, Config) when atom(Func), list(Config) ->
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(3)),
[{watchdog, Dog}|Config].
@@ -81,7 +82,7 @@ set_path(Config) when is_list(Config) ->
get_file(doc) -> [];
get_file(Config) when is_list(Config) ->
?line case erl_prim_loader:get_file("lists" ++ code:objfile_extension()) of
- {ok,Bin,File} when binary(Bin), list(File) ->
+ {ok,Bin,File} when is_binary(Bin), is_list(File) ->
ok;
_ ->
test_server:fail(get_valid_file)
@@ -344,8 +345,9 @@ local_archive(Config) when is_list(Config) ->
Node = node(),
BeamName = "inet.beam",
?line ok = test_archive(Node, Archive, KernelDir, BeamName),
- ?line ok = rpc:call(Node, erl_prim_loader, release_archives, []),
+ %% Cleanup
+ ?line ok = rpc:call(Node, erl_prim_loader, release_archives, []),
?line ok = file:delete(Archive),
ok.
@@ -365,6 +367,7 @@ remote_archive(Config) when is_list(Config) ->
BeamName = "inet.beam",
?line ok = test_archive(Node, Archive, KernelDir, BeamName),
+ %% Cleanup
?line stop_node(Node),
?line unlink(BootPid),
?line exit(BootPid, kill),
@@ -401,21 +404,22 @@ primary_archive(Config) when is_list(Config) ->
?line Args = " -setcookie " ++ Cookie,
?line {ok,Node} = start_node(primary_archive, Args),
?line wait_really_started(Node, 25),
+ ?line {_,_,_} = rpc:call(Node, erlang, date, []),
%% Set primary archive
- ?line {_,_,_} = rpc:call(Node, erlang, date, []),
- ?line {ok, Ebins} = rpc:call(Node, erl_prim_loader, set_primary_archive, [Archive, ArchiveBin]),
ExpectedEbins = [Archive, DictDir ++ "/ebin", DummyDir ++ "/ebin"],
io:format("ExpectedEbins: ~p\n", [ExpectedEbins]),
- ?line ExpectedEbins = lists:sort(Ebins),
+ ?line {ok, FileInfo} = prim_file:read_file_info(Archive),
+ ?line {ok, Ebins} = rpc:call(Node, erl_prim_loader, set_primary_archive, [Archive, ArchiveBin, FileInfo]),
+ ?line ExpectedEbins = lists:sort(Ebins), % assert
?line {ok, TopFiles2} = rpc:call(Node, erl_prim_loader, list_dir, [Archive]),
?line [DictDir, DummyDir] = lists:sort(TopFiles2),
BeamName = "primary_archive_dict_app.beam",
?line ok = test_archive(Node, Archive, DictDir, BeamName),
- ?line {ok, []} = rpc:call(Node, erl_prim_loader, set_primary_archive, [undefined, undefined]),
-
+ %% Cleanup
+ ?line {ok, []} = rpc:call(Node, erl_prim_loader, set_primary_archive, [undefined, undefined, undefined]),
?line stop_node(Node),
?line ok = file:delete(Archive),
ok.
@@ -461,6 +465,46 @@ create_archive(Archive, AppDirs) ->
io:format("zip:create(~p,\n\t~p,\n\t~p).\n", [Archive, AppDirs, Opts]),
zip:create(Archive, AppDirs, Opts).
+
+virtual_dir_in_archive(suite) ->
+ [];
+virtual_dir_in_archive(doc) ->
+ ["Read virtual directories from archive."];
+virtual_dir_in_archive(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Data = <<"A little piece of data.">>,
+ ArchiveBase = "archive_with_virtual_dirs",
+ Archive = filename:join([PrivDir, ArchiveBase ++ init:archive_extension()]),
+ FileBase = "a_data_file.beam",
+ EbinBase = "ebin",
+ FileInArchive = filename:join([ArchiveBase, EbinBase, FileBase]),
+ BinFiles = [{FileInArchive, Data}],
+ Opts = [{compress, []}],
+ ?line file:delete(Archive),
+ io:format("zip:create(~p,\n\t~p,\n\t~p).\n", [Archive, BinFiles, Opts]),
+ ?line {ok, Archive} = zip:create(Archive, BinFiles, Opts),
+
+ %% Verify that there is no directories
+ ?line {ok, BinFiles} = zip:unzip(Archive, [memory]),
+
+ FullPath = filename:join([Archive, FileInArchive]),
+ ?line {ok, _} = erl_prim_loader:read_file_info(FullPath),
+
+ %% Read one virtual dir
+ EbinDir = filename:dirname(FullPath),
+ ?line {ok, _} = erl_prim_loader:read_file_info(EbinDir),
+ ?line {ok, [FileBase]} = erl_prim_loader:list_dir(EbinDir),
+
+ %% Read another virtual dir
+ AppDir = filename:dirname(EbinDir),
+ ?line {ok, _} = erl_prim_loader:read_file_info(AppDir),
+ ?line {ok, [EbinBase]} = erl_prim_loader:list_dir(AppDir),
+
+ %% Cleanup
+ ?line ok = erl_prim_loader:release_archives(),
+ ?line ok = file:delete(Archive),
+ ok.
+
%% Misc. functions
ip_str({A, B, C, D}) ->
diff --git a/lib/kernel/test/error_logger_SUITE.erl b/lib/kernel/test/error_logger_SUITE.erl
index a737949bbb..eda86861d5 100644
--- a/lib/kernel/test/error_logger_SUITE.erl
+++ b/lib/kernel/test/error_logger_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(error_logger_SUITE).
@@ -45,7 +45,7 @@ all(suite) ->
error_report(suite) -> [];
error_report(doc) -> [];
-error_report(Config) when list(Config) ->
+error_report(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
Rep1 = [{tag1,"data1"},{tag2,data2},{tag3,3}],
Rep2 = [testing,"testing",{tag1,"tag1"}],
@@ -85,7 +85,7 @@ error_report(Config) when list(Config) ->
info_report(suite) -> [];
info_report(doc) -> [];
-info_report(Config) when list(Config) ->
+info_report(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
Rep1 = [{tag1,"data1"},{tag2,data2},{tag3,3}],
Rep2 = [testing,"testing",{tag1,"tag1"}],
@@ -125,7 +125,7 @@ info_report(Config) when list(Config) ->
error(suite) -> [];
error(doc) -> [];
-error(Config) when list(Config) ->
+error(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
Msg1 = "This is a plain text string~n",
Msg2 = "This is a text with arguments ~p~n",
@@ -160,7 +160,7 @@ error(Config) when list(Config) ->
info(suite) -> [];
info(doc) -> [];
-info(Config) when list(Config) ->
+info(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
Msg1 = "This is a plain text string~n",
Msg2 = "This is a text with arguments ~p~n",
@@ -188,7 +188,7 @@ info(Config) when list(Config) ->
emulator(suite) -> [];
emulator(doc) -> [];
-emulator(Config) when list(Config) ->
+emulator(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
spawn(?MODULE, generate_error, []),
reported(emulator),
@@ -215,7 +215,7 @@ tty(Config) when is_list(Config) ->
logfile(suite) -> [];
logfile(doc) -> [];
-logfile(Config) when list(Config) ->
+logfile(Config) when is_list(Config) ->
?line case error_logger:logfile(filename) of
{error, no_log_file} -> % Ok, we continues.
do_logfile();
@@ -236,7 +236,7 @@ do_logfile() ->
add(suite) -> [];
add(doc) -> [];
-add(Config) when list(Config) ->
+add(Config) when is_list(Config) ->
?line {'EXIT',_} = (catch error_logger:add_report_handler("dummy")),
?line {'EXIT',_} = error_logger:add_report_handler(non_existing),
?line my_error = error_logger:add_report_handler(?MODULE, [error]),
@@ -246,7 +246,7 @@ add(Config) when list(Config) ->
delete(suite) -> [];
delete(doc) -> [];
-delete(Config) when list(Config) ->
+delete(Config) when is_list(Config) ->
?line {'EXIT',_} = (catch error_logger:delete_report_handler("dummy")),
?line {error,_} = error_logger:delete_report_handler(non_existing),
ok.
@@ -265,7 +265,7 @@ reported(Tag, Type, Report) ->
reported(emulator) ->
receive
- {error, "~s~n", String} when list(String) ->
+ {error, "~s~n", String} when is_list(String) ->
test_server:messages_get(),
ok
after 1000 ->
@@ -277,9 +277,9 @@ reported(emulator) ->
%% Sends a notification to the Tester process about the events
%% generated by the Tester process.
%%-----------------------------------------------------------------
-init(Tester) when pid(Tester) ->
+init(Tester) when is_pid(Tester) ->
{ok, Tester};
-init(Config) when list(Config) ->
+init(Config) when is_list(Config) ->
my_error.
handle_event({Tag, _GL, {_EPid, Type, Report}}, Tester) ->
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index c645d0f842..d01e1f1fcf 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -3371,7 +3371,7 @@ read_line_create_files(TestData) ->
[ Function(File) || {Function,File,_,_} <- TestData ].
read_line_remove_files(TestData) ->
- [ file:delete(File) || {Function,File,_,_} <- TestData ].
+ [ file:delete(File) || {_Function,File,_,_} <- TestData ].
read_line_1(suite) ->
[];
diff --git a/lib/kernel/test/global_group_SUITE.erl b/lib/kernel/test/global_group_SUITE.erl
index a8b87390eb..430cc61267 100644
--- a/lib/kernel/test/global_group_SUITE.erl
+++ b/lib/kernel/test/global_group_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -42,7 +42,7 @@ all(suite) ->
-define(TESTCASE, testcase_name).
-define(testcase, ?config(?TESTCASE, Config)).
-init_per_testcase(Case, Config) when atom(Case), list(Config) ->
+init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(5)),
[{?TESTCASE, Case}, {watchdog, Dog}|Config].
@@ -59,7 +59,7 @@ fin_per_testcase(_Func, Config) ->
start_gg_proc(suite) -> [];
start_gg_proc(doc) -> ["Check that the global_group processes are started automatically. "];
-start_gg_proc(Config) when list(Config) ->
+start_gg_proc(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(120)),
?line Dir = ?config(priv_dir, Config),
@@ -94,7 +94,7 @@ start_gg_proc(Config) when list(Config) ->
no_gg_proc(suite) -> [];
no_gg_proc(doc) -> ["Start a system without global groups. Nodes are not "
"synced at start (sync_nodes_optional is not defined)"];
-no_gg_proc(Config) when list(Config) ->
+no_gg_proc(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(200)),
?line Dir = ?config(priv_dir, Config),
@@ -267,7 +267,7 @@ no_gg_proc_sync(suite) -> [];
no_gg_proc_sync(doc) ->
["Start a system without global groups, but syncing the nodes by using "
"sync_nodes_optional."];
-no_gg_proc_sync(Config) when list(Config) ->
+no_gg_proc_sync(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(200)),
?line Dir = ?config(priv_dir, Config),
@@ -441,7 +441,7 @@ no_gg_proc_sync(Config) when list(Config) ->
compatible(suite) -> [];
compatible(doc) ->
["Check that a system without global groups is compatible with the old R4 system."];
-compatible(Config) when list(Config) ->
+compatible(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(200)),
?line Dir = ?config(priv_dir, Config),
@@ -614,7 +614,7 @@ compatible(Config) when list(Config) ->
one_grp(suite) -> [];
one_grp(doc) -> ["Test a system with only one global group. "];
-one_grp(Config) when list(Config) ->
+one_grp(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(120)),
?line Dir = ?config(priv_dir, Config),
@@ -701,7 +701,7 @@ one_grp(Config) when list(Config) ->
one_grp_x(suite) -> [];
one_grp_x(doc) -> ["Check a system with only one global group. "
"Start the nodes with different time intervals. "];
-one_grp_x(Config) when list(Config) ->
+one_grp_x(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(120)),
?line Dir = ?config(priv_dir, Config),
@@ -763,7 +763,7 @@ one_grp_x(Config) when list(Config) ->
two_grp(suite) -> [];
two_grp(doc) -> ["Test a two global group system. "];
-two_grp(Config) when list(Config) ->
+two_grp(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(200)),
?line Dir = ?config(priv_dir, Config),
@@ -1063,7 +1063,7 @@ two_grp(Config) when list(Config) ->
hidden_groups(suite) -> [];
hidden_groups(doc) -> ["Test hidden global groups."];
-hidden_groups(Config) when list(Config) ->
+hidden_groups(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(200)),
?line Dir = ?config(priv_dir, Config),
@@ -1138,7 +1138,7 @@ hidden_groups(Config) when list(Config) ->
test_exit(suite) -> [];
test_exit(doc) -> ["Checks when the search process exits. "];
-test_exit(Config) when list(Config) ->
+test_exit(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(120)),
?line NN = node_name(atom_to_list(node())),
diff --git a/lib/kernel/test/heart_SUITE.erl b/lib/kernel/test/heart_SUITE.erl
index b06244db3c..0d0296238b 100644
--- a/lib/kernel/test/heart_SUITE.erl
+++ b/lib/kernel/test/heart_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(heart_SUITE).
@@ -80,7 +80,7 @@ start_check(Type, Name) ->
end,
erlang:monitor_node(Node, true),
case rpc:call(Node, erlang, whereis, [heart]) of
- Pid when pid(Pid) ->
+ Pid when is_pid(Pid) ->
ok;
_ ->
test_server:fail(heart_not_started)
@@ -355,7 +355,7 @@ erl() ->
end.
name(Node) when is_list(Node) -> name(Node,[]);
-name(Node) when atom(Node) -> name(atom_to_list(Node),[]).
+name(Node) when is_atom(Node) -> name(atom_to_list(Node),[]).
name([$@|Node], Name) ->
case lists:member($., Node) of
@@ -368,7 +368,7 @@ name([H|T], Name) ->
name(T, [H|Name]).
-atom_conv(A) when atom(A) ->
+atom_conv(A) when is_atom(A) ->
atom_to_list(A);
atom_conv(A) when is_list(A) ->
A.
diff --git a/lib/kernel/test/init_SUITE.erl b/lib/kernel/test/init_SUITE.erl
index 3d777f93a4..bbd8261197 100644
--- a/lib/kernel/test/init_SUITE.erl
+++ b/lib/kernel/test/init_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(init_SUITE).
@@ -44,7 +44,7 @@ all(suite) ->
restart,
get_status, script_id, boot].
-init_per_testcase(Func, Config) when atom(Func), list(Config) ->
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:seconds(?DEFAULT_TIMEOUT_SEC)),
[{watchdog, Dog}|Config].
@@ -477,7 +477,7 @@ script_id(Config) when is_list(Config) ->
?line {Name, Vsn} = init:script_id(),
?line if
- list(Name), list(Vsn) ->
+ is_list(Name), is_list(Vsn) ->
ok;
true ->
?t:fail(not_standard_script)
diff --git a/lib/kernel/test/kernel_SUITE.erl b/lib/kernel/test/kernel_SUITE.erl
index 225bc38b05..bb1d905de3 100644
--- a/lib/kernel/test/kernel_SUITE.erl
+++ b/lib/kernel/test/kernel_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%%----------------------------------------------------------------
@@ -56,6 +56,6 @@ app_test(doc) ->
["Tests the applications consistency."];
app_test(suite) ->
[];
-app_test(Config) when list(Config) ->
+app_test(Config) when is_list(Config) ->
?line ok=?t:app_test(kernel),
ok.
diff --git a/lib/kernel/test/kernel_config_SUITE.erl b/lib/kernel/test/kernel_config_SUITE.erl
index 6b7d788e60..c72fc3f02d 100644
--- a/lib/kernel/test/kernel_config_SUITE.erl
+++ b/lib/kernel/test/kernel_config_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(kernel_config_SUITE).
@@ -56,7 +56,7 @@ from(_, []) -> [].
%%-----------------------------------------------------------------
sync(doc) -> [];
sync(suite) -> [];
-sync(Conf) when list(Conf) ->
+sync(Conf) when is_list(Conf) ->
?line Dog = ?t:timetrap(?t:seconds(120)),
% Write a config file
Dir = ?config(priv_dir,Conf),
diff --git a/lib/kernel/test/loose_node.erl b/lib/kernel/test/loose_node.erl
index ac1ddb8d9a..87a4ef01c0 100644
--- a/lib/kernel/test/loose_node.erl
+++ b/lib/kernel/test/loose_node.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -55,7 +55,7 @@
%% Exported functions.
%%
-stop(Node) when atom(Node) ->
+stop(Node) when is_atom(Node) ->
rpc:cast(Node, erlang, halt, []),
io:format("Stopped loose node ~p~n", [Node]),
ok.
@@ -63,9 +63,10 @@ stop(Node) when atom(Node) ->
start(Name, Args) ->
start(Name, Args, -1).
-start(Name, Args, TimeOut) when atom(Name) ->
+start(Name, Args, TimeOut) when is_atom(Name) ->
start(atom_to_list(Name), Args, TimeOut);
-start(Name, Args, TimeOut) when list(Name), list(Args), integer(TimeOut) ->
+start(Name, Args, TimeOut)
+ when is_list(Name), is_list(Args), is_integer(TimeOut) ->
Parent = self(),
Ref = make_ref(),
Starter
@@ -119,7 +120,7 @@ start(Name, Args, TimeOut) when list(Name), list(Args), integer(TimeOut) ->
io:format("Trying to start loose node...~n"
" --> ~p~n", [Cmd]),
Res = case open_port({spawn, Cmd}, []) of
- P when port(P) ->
+ P when is_port(P) ->
receive
{loose_node_started,
Node,
@@ -150,14 +151,14 @@ start(Name, Args, TimeOut) when list(Name), list(Args), integer(TimeOut) ->
%% Exported functions for internal use.
%%
-loose_node_started([Name, Node, TimeOutSecs]) when list(Name),
- list(Node),
- list(TimeOutSecs) ->
+loose_node_started([Name, Node, TimeOutSecs]) when is_list(Name),
+ is_list(Node),
+ is_list(TimeOutSecs) ->
spawn_opt(fun () ->
process_flag(trap_exit, true),
Proc = {list_to_atom(Name), list_to_atom(Node)},
Timeout = case catch list_to_integer(TimeOutSecs) of
- I when integer(I), I >= 0 -> I*1000;
+ I when is_integer(I), I >= 0 -> I*1000;
_ -> infinity
end,
wait_until(fun () -> is_alive() end),
diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl
index 667f267079..1673b33010 100644
--- a/lib/kernel/test/os_SUITE.erl
+++ b/lib/kernel/test/os_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(os_SUITE).
@@ -32,7 +32,7 @@ space_in_cwd(doc) ->
"Test that executing a command in a current working directory "
"with space in its name works.";
space_in_cwd(suite) -> [];
-space_in_cwd(Config) when list(Config) ->
+space_in_cwd(Config) when is_list(Config) ->
?line PrivDir = ?config(priv_dir, Config),
?line Dirname = filename:join(PrivDir, "cwd with space"),
?line ok = file:make_dir(Dirname),
@@ -60,7 +60,7 @@ space_in_cwd(Config) when list(Config) ->
quoting(doc) -> "Test that various ways of quoting arguments work.";
quoting(suite) -> [];
-quoting(Config) when list(Config) ->
+quoting(Config) when is_list(Config) ->
?line DataDir = ?config(data_dir, Config),
?line Echo = filename:join(DataDir, "my_echo"),
@@ -78,7 +78,7 @@ quoting(Config) when list(Config) ->
space_in_name(doc) ->
"Test that program with a space in its name can be executed.";
space_in_name(suite) -> [];
-space_in_name(Config) when list(Config) ->
+space_in_name(Config) when is_list(Config) ->
?line PrivDir = ?config(priv_dir, Config),
?line DataDir = ?config(data_dir, Config),
?line Spacedir = filename:join(PrivDir, "program files"),
@@ -108,7 +108,7 @@ space_in_name(Config) when list(Config) ->
bad_command(doc) ->
"Check that a bad command doesn't crasch the server or the emulator (it used to).";
bad_command(suite) -> [];
-bad_command(Config) when list(Config) ->
+bad_command(Config) when is_list(Config) ->
?line catch os:cmd([a|b]),
?line catch os:cmd({bad, thing}),
@@ -120,7 +120,7 @@ bad_command(Config) when list(Config) ->
find_executable(suite) -> [];
find_executable(doc) -> [];
-find_executable(Config) when list(Config) ->
+find_executable(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
?line DataDir = filename:join(?config(data_dir, Config), "win32"),
@@ -159,7 +159,7 @@ find_exe(Where, Name, Ext, Path) ->
case os:find_executable(Name, Path) of
Expected ->
ok;
- Name when list(Name) ->
+ Name when is_list(Name) ->
case filename:absname(Name) of
Expected ->
ok;
@@ -176,7 +176,7 @@ find_exe(Where, Name, Ext, Path) ->
unix_comment_in_command(doc) ->
"OTP-1805: Test that os:cmd(\"ls #\") works correctly (used to hang).";
unix_comment_in_command(suite) -> [];
-unix_comment_in_command(Config) when list(Config) ->
+unix_comment_in_command(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(20)),
?line Priv = ?config(priv_dir, Config),
?line ok = file:set_cwd(Priv),
diff --git a/lib/kernel/test/pdict_SUITE.erl b/lib/kernel/test/pdict_SUITE.erl
index 6aa434b614..87ee951a0c 100644
--- a/lib/kernel/test/pdict_SUITE.erl
+++ b/lib/kernel/test/pdict_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(pdict_SUITE).
@@ -49,7 +49,7 @@ simple(doc) ->
["Tests simple functionality in process dictionary."];
simple(suite) ->
[];
-simple(Config) when list(Config) ->
+simple(Config) when is_list(Config) ->
XX = get(),
erase(),
L = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,
@@ -146,7 +146,7 @@ info(doc) ->
["Tests process_info(Pid, dictionary)"];
info(suite) ->
[];
-info(Config) when list(Config) ->
+info(Config) when is_list(Config) ->
L = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,
q,r,s,t,u,v,x,y,z,'A','B','C','D'],
process_flag(trap_exit,true),
diff --git a/lib/kernel/test/rpc_SUITE.erl b/lib/kernel/test/rpc_SUITE.erl
index 2b39e31a80..2b7de40797 100644
--- a/lib/kernel/test/rpc_SUITE.erl
+++ b/lib/kernel/test/rpc_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(rpc_SUITE).
@@ -333,7 +333,7 @@ suicide(exit, Reason) ->
suicide(erlang, exit, [Name, Reason]) when is_atom(Name) ->
case whereis(Name) of
- Pid when pid(Pid) -> suicide(erlang, exit, [Pid, Reason])
+ Pid when is_pid(Pid) -> suicide(erlang, exit, [Pid, Reason])
end;
suicide(Mod, Func, Args) ->
spawn_link(
@@ -448,7 +448,7 @@ call_benchmark(Config) when is_list(Config) ->
?t:timetrap_cancel(Timetrap),
ok.
-do_call_benchmark(Node, M) when integer(M), M > 0 ->
+do_call_benchmark(Node, M) when is_integer(M), M > 0 ->
do_call_benchmark(Node, erlang:now(), 0, M).
do_call_benchmark(Node, {A,B,C}, M, M) ->
diff --git a/lib/kernel/test/seq_trace_SUITE.erl b/lib/kernel/test/seq_trace_SUITE.erl
index f582b94c97..b557c7fb1e 100644
--- a/lib/kernel/test/seq_trace_SUITE.erl
+++ b/lib/kernel/test/seq_trace_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(seq_trace_SUITE).
@@ -381,7 +381,7 @@ port(Config) when is_list(Config) ->
get_port_message(Port) ->
receive
- {Port,{data,Bin}} when binary(Bin) ->
+ {Port,{data,Bin}} when is_binary(Bin) ->
binary_to_term(Bin);
Other ->
?t:fail({unexpected,Other})
@@ -678,7 +678,7 @@ transparent_tracer() ->
receive {started, Ref} -> ok end,
fun(pid) ->
Pid;
- ({stop, N}) when integer(N), N >= 0 ->
+ ({stop, N}) when is_integer(N), N >= 0 ->
Mref = erlang:monitor(process, Pid),
receive
{'DOWN', Mref, _, _, _} ->
@@ -717,7 +717,7 @@ simple_tracer(Data, DN) ->
From ! {tracerlog,lists:reverse(Data)}
end.
-stop_tracer(N) when integer(N) ->
+stop_tracer(N) when is_integer(N) ->
case catch (seq_trace_SUITE_tracer ! {stop,N,self()}) of
{'EXIT', _} ->
{error, not_started};
diff --git a/lib/kernel/test/wrap_log_reader_SUITE.erl b/lib/kernel/test/wrap_log_reader_SUITE.erl
index 1d1570fbd9..ceac593e44 100644
--- a/lib/kernel/test/wrap_log_reader_SUITE.erl
+++ b/lib/kernel/test/wrap_log_reader_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -48,7 +48,7 @@
all(suite) ->
[no_file, one, two, four, wrap, wrapping, external, error].
-init_per_testcase(Func, Config) when atom(Func), list(Config) ->
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:seconds(60)),
[{watchdog, Dog} | Config].
@@ -58,7 +58,7 @@ fin_per_testcase(_Func, _Config) ->
no_file(suite) -> [];
no_file(doc) -> ["No log file exists"];
-no_file(Conf) when list(Conf) ->
+no_file(Conf) when is_list(Conf) ->
?line code:add_path(?config(data_dir,Conf)),
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
@@ -81,7 +81,7 @@ one(doc) -> ["One index file"].
one_empty(suite) -> [];
one_empty(doc) -> ["One empty index file"];
-one_empty(Conf) when list(Conf) ->
+one_empty(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -107,7 +107,7 @@ one_empty(Conf) when list(Conf) ->
one_filled(suite) -> [];
one_filled(doc) -> ["One filled index file"];
-one_filled(Conf) when list(Conf) ->
+one_filled(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -144,7 +144,7 @@ two(doc) -> ["Two index files"].
two_filled(suite) -> [];
two_filled(doc) -> ["Two filled index files"];
-two_filled(Conf) when list(Conf) ->
+two_filled(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = list_to_atom(join(Dir, "sune.LOG")),
delete_files(File),
@@ -186,7 +186,7 @@ four(doc) -> ["Four index files"].
four_filled(suite) -> [];
four_filled(doc) -> ["Four filled index files"];
-four_filled(Conf) when list(Conf) ->
+four_filled(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -231,7 +231,7 @@ wrap(doc) -> ["Wrap index file, first wrapping"].
wrap_filled(suite) -> [];
wrap_filled(doc) -> ["First wrap, open, filled index file"];
-wrap_filled(Conf) when list(Conf) ->
+wrap_filled(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -274,7 +274,7 @@ test_wrap(File) ->
wrapping(suite) -> [];
wrapping(doc) -> ["Wrapping at the same time as reading"];
-wrapping(Conf) when list(Conf) ->
+wrapping(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -329,7 +329,7 @@ wrapping(Conf) when list(Conf) ->
external(suite) -> [];
external(doc) -> ["External format"];
-external(Conf) when list(Conf) ->
+external(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -349,7 +349,7 @@ external(Conf) when list(Conf) ->
error(suite) -> [];
error(doc) -> ["Error situations"];
-error(Conf) when list(Conf) ->
+error(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
diff --git a/lib/megaco/doc/src/Makefile b/lib/megaco/doc/src/Makefile
index 2c55e92914..537d34441d 100644
--- a/lib/megaco/doc/src/Makefile
+++ b/lib/megaco/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
include $(ERL_TOP)/make/target.mk
@@ -49,6 +49,9 @@ include files.mk
# ----------------------------------------------------
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
INTERNAL_HTML_FILES = $(TECHNICAL_DESCR_FILES:%.xml=$(HTMLDIR)/%.html)
HTML_APP_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html)
@@ -104,8 +107,10 @@ INDEX_SRC = $(INDEX_FILE).src
INDEX_TARGET = $(DOCDIR)/$(INDEX_FILE)
STANDARD_DIR = ../standard
-STANDARDS = $(STANDARD_DIR)/rfc3015.txt \
- $(STANDARD_DIR)/implementors_guide_v6.pdf
+ $(STANDARD_DIR)/rfc3525.txt \
+ $(STANDARD_DIR)/rfc4234.txt \
+ $(STANDARD_DIR)/rfc4566.txt \
+ $(STANDARD_DIR)/implementors_guide_v10-13.pdf
# ----------------------------------------------------
# FLAGS
diff --git a/lib/megaco/doc/src/megaco_codec_transform.xml b/lib/megaco/doc/src/megaco_codec_transform.xml
index 71f7fc689f..89ed3fd654 100644
--- a/lib/megaco/doc/src/megaco_codec_transform.xml
+++ b/lib/megaco/doc/src/megaco_codec_transform.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>megaco_codec_transform</title>
@@ -36,8 +36,8 @@
<description>
<p>This module implements a simple megaco message transformation utility.</p>
- <p><em>Note</em> that this module is <em>not</em> included in the runtime part of
- the application.</p>
+ <p><em>Note</em> that this module is <em>not</em> included in the
+ runtime part of the application.</p>
<marker id="export_messages"></marker>
</description>
@@ -51,15 +51,16 @@
<v>MessagePackage = atom()</v>
</type>
<desc>
- <p>Export the messages in the <c>MessagePackage</c> (default is <c>time_test</c>). </p>
- <p>The out produced by this function is a directory structure with the
- following structure: </p>
+ <p>Export the messages in the <c>MessagePackage</c> (default
+ is <c>time_test</c>). </p>
+ <p>The output produced by this function is a directory structure
+ with the following structure: </p>
<code type="none"><![CDATA[
-\011 <message package>/pretty/<message-files>
-\011 compact/<message-files>
-\011 per/<message-files>
-\011 ber/<message-files>
-\011 erlang/<message-files>
+<message package>/pretty/<message-files>
+ compact/<message-files>
+ per/<message-files>
+ ber/<message-files>
+ erlang/<message-files>
]]></code>
</desc>
</func>
diff --git a/lib/megaco/doc/src/megaco_debug.xml b/lib/megaco/doc/src/megaco_debug.xml
index 1b99985341..2523a3be86 100644
--- a/lib/megaco/doc/src/megaco_debug.xml
+++ b/lib/megaco/doc/src/megaco_debug.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Testing and tools</title>
@@ -159,12 +159,12 @@
<p>When run as above (this will take some time), the measurement
process is done as follows:</p>
<pre>
-\011 For each codec:
-\011 For each message:
-\011 Read the message from the file
-\011 Detect message version
-\011 Measure decode
- Measure encode
+For each codec:
+ For each message:
+ Read the message from the file
+ Detect message version
+ Measure decode
+ Measure encode
Write results, encode, decode and total, to file
</pre>
</item>
@@ -218,11 +218,11 @@ message() = binary()
with the following structure:
</p>
<code type="none"><![CDATA[
-\011 <message package>/pretty/<message-files>
-\011 compact/
-\011 per/
-\011 ber/<message-files>
-\011 erlang/
+<message package>/pretty/<message-files>
+ compact/
+ per/
+ ber/<message-files>
+ erlang/
]]></code>
<p>The file includes both version 1, 2 and version 3 messages.</p>
</section>
diff --git a/lib/megaco/doc/src/megaco_performance.xml b/lib/megaco/doc/src/megaco_performance.xml
index b34ee4f389..72b5c156ba 100644
--- a/lib/megaco/doc/src/megaco_performance.xml
+++ b/lib/megaco/doc/src/megaco_performance.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Performance comparison</title>
@@ -257,12 +257,12 @@ MEGACO/1 [124.124.124.222]
Transaction = 9998 {
Context = - {
ServiceChange = ROOT {
- \011Services {
- \011 Method = Restart,
- \011 ServiceChangeAddress = 55555,
- \011 Profile = ResGW/1,
- \011 Reason = "901 MG Cold Boot"
- \011}
+ Services {
+ Method = Restart,
+ ServiceChangeAddress = 55555,
+ Profile = ResGW/1,
+ Reason = "901 MG Cold Boot"
+ }
}
}
} </pre>
diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml
index bacb7275d7..61f3611029 100644
--- a/lib/megaco/doc/src/notes.xml
+++ b/lib/megaco/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Megaco Release Notes</title>
@@ -36,27 +36,27 @@
section is the version number of Megaco.</p>
<section>
- <title>Megaco 3.13.0.1</title>
+ <title>Megaco 3.13.0.2</title>
- <p>Version 3.13.0.1 supports code replacement in runtime from/to
+ <p>Version 3.13.0.2 supports code replacement in runtime from/to
version 3.13, 3.12 and 3.11.3.</p>
<section>
<title>Improvements and new features</title>
+<!--
<p>-</p>
+-->
-<!--
<list type="bulleted">
<item>
- <p>The documentation is now built with open source tools
- (<em>xsltproc</em> and <em>fop</em>) that exists on most
- platforms. One visible change is that the frames are removed.</p>
- <p>Own Id: OTP-8249</p>
+ <p>Added a help target in the test Makefile to explain
+ the most useful make targets, used when testing the
+ application using the test-server provided with megaco.</p>
+ <p>Own Id: OTP-8362</p>
</item>
</list>
--->
</section>
@@ -75,25 +75,7 @@
</section>
- <section>
- <title>Incompatibilities</title>
- <p>-</p>
-
-<!--
- <list type="bulleted">
- <item>
- <p>For those implementing their own codec's, the new megaco_encoder
- behaviour will require three more functions. See above for more
- info. </p>
- <p>Own Id: OTP-7168</p>
- <p>Aux Id: Seq 10867</p>
- </item>
-
- </list>
--->
-
- </section>
- </section> <!-- 3.13.0.1 -->
+ </section> <!-- 3.13.0.2 -->
<section>
diff --git a/lib/megaco/doc/standard/H.248.1-Corr1-200403.doc b/lib/megaco/doc/standard/H.248.1-Corr1-200403.doc
deleted file mode 100644
index 39ef6e4efa..0000000000
--- a/lib/megaco/doc/standard/H.248.1-Corr1-200403.doc
+++ /dev/null
Binary files differ
diff --git a/lib/megaco/doc/standard/rfc2327.txt b/lib/megaco/doc/standard/rfc2327.txt
deleted file mode 100644
index ce77de6128..0000000000
--- a/lib/megaco/doc/standard/rfc2327.txt
+++ /dev/null
@@ -1,2355 +0,0 @@
-
-
-
-
-
-
-Network Working Group M. Handley
-Request for Comments: 2327 V. Jacobson
-Category: Standards Track ISI/LBNL
- April 1998
-
-
- SDP: Session Description Protocol
-
-Status of this Memo
-
- This document specifies an Internet standards track protocol for the
- Internet community, and requests discussion and suggestions for
- improvements. Please refer to the current edition of the "Internet
- Official Protocol Standards" (STD 1) for the standardization state
- and status of this protocol. Distribution of this memo is unlimited.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (1998). All Rights Reserved.
-
-Abstract
-
- This document defines the Session Description Protocol, SDP. SDP is
- intended for describing multimedia sessions for the purposes of
- session announcement, session invitation, and other forms of
- multimedia session initiation.
-
- This document is a product of the Multiparty Multimedia Session
- Control (MMUSIC) working group of the Internet Engineering Task
- Force. Comments are solicited and should be addressed to the working
- group's mailing list at [email protected] and/or the authors.
-
-1. Introduction
-
- On the Internet multicast backbone (Mbone), a session directory tool
- is used to advertise multimedia conferences and communicate the
- conference addresses and conference tool-specific information
- necessary for participation. This document defines a session
- description protocol for this purpose, and for general real-time
- multimedia session description purposes. This memo does not describe
- multicast address allocation or the distribution of SDP messages in
- detail. These are described in accompanying memos. SDP is not
- intended for negotiation of media encodings.
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 1]
-
-RFC 2327 SDP April 1998
-
-
-2. Background
-
- The Mbone is the part of the internet that supports IP multicast, and
- thus permits efficient many-to-many communication. It is used
- extensively for multimedia conferencing. Such conferences usually
- have the property that tight coordination of conference membership is
- not necessary; to receive a conference, a user at an Mbone site only
- has to know the conference's multicast group address and the UDP
- ports for the conference data streams.
-
- Session directories assist the advertisement of conference sessions
- and communicate the relevant conference setup information to
- prospective participants. SDP is designed to convey such information
- to recipients. SDP is purely a format for session description - it
- does not incorporate a transport protocol, and is intended to use
- different transport protocols as appropriate including the Session
- Announcement Protocol [4], Session Initiation Protocol [11], Real-
- Time Streaming Protocol [12], electronic mail using the MIME
- extensions, and the Hypertext Transport Protocol.
-
- SDP is intended to be general purpose so that it can be used for a
- wider range of network environments and applications than just
- multicast session directories. However, it is not intended to
- support negotiation of session content or media encodings - this is
- viewed as outside the scope of session description.
-
-3. Glossary of Terms
-
- The following terms are used in this document, and have specific
- meaning within the context of this document.
-
- Conference
- A multimedia conference is a set of two or more communicating users
- along with the software they are using to communicate.
-
- Session
- A multimedia session is a set of multimedia senders and receivers
- and the data streams flowing from senders to receivers. A
- multimedia conference is an example of a multimedia session.
-
- Session Advertisement
- See session announcement.
-
- Session Announcement
- A session announcement is a mechanism by which a session
- description is conveyed to users in a proactive fashion, i.e., the
- session description was not explicitly requested by the user.
-
-
-
-
-Handley & Jacobson Standards Track [Page 2]
-
-RFC 2327 SDP April 1998
-
-
- Session Description
- A well defined format for conveying sufficient information to
- discover and participate in a multimedia session.
-
-3.1. Terminology
-
- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
- document are to be interpreted as described in RFC 2119.
-
-4. SDP Usage
-
-4.1. Multicast Announcements
-
- SDP is a session description protocol for multimedia sessions. A
- common mode of usage is for a client to announce a conference session
- by periodically multicasting an announcement packet to a well known
- multicast address and port using the Session Announcement Protocol
- (SAP).
-
- SAP packets are UDP packets with the following format:
-
- |--------------------|
- | SAP header |
- |--------------------|
- | text payload |
- |//////////
-
-
- The header is the Session Announcement Protocol header. SAP is
- described in more detail in a companion memo [4]
-
- The text payload is an SDP session description, as described in this
- memo. The text payload should be no greater than 1 Kbyte in length.
- If announced by SAP, only one session announcement is permitted in a
- single packet.
-
-4.2. Email and WWW Announcements
-
- Alternative means of conveying session descriptions include
- electronic mail and the World Wide Web. For both email and WWW
- distribution, the use of the MIME content type "application/sdp"
- should be used. This enables the automatic launching of applications
- for participation in the session from the WWW client or mail reader
- in a standard manner.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 3]
-
-RFC 2327 SDP April 1998
-
-
- Note that announcements of multicast sessions made only via email or
- the World Wide Web (WWW) do not have the property that the receiver
- of a session announcement can necessarily receive the session because
- the multicast sessions may be restricted in scope, and access to the
- WWW server or reception of email is possible outside this scope. SAP
- announcements do not suffer from this mismatch.
-
-5. Requirements and Recommendations
-
- The purpose of SDP is to convey information about media streams in
- multimedia sessions to allow the recipients of a session description
- to participate in the session. SDP is primarily intended for use in
- an internetwork, although it is sufficiently general that it can
- describe conferences in other network environments.
-
- A multimedia session, for these purposes, is defined as a set of
- media streams that exist for some duration of time. Media streams
- can be many-to-many. The times during which the session is active
- need not be continuous.
-
- Thus far, multicast based sessions on the Internet have differed from
- many other forms of conferencing in that anyone receiving the traffic
- can join the session (unless the session traffic is encrypted). In
- such an environment, SDP serves two primary purposes. It is a means
- to communicate the existence of a session, and is a means to convey
- sufficient information to enable joining and participating in the
- session. In a unicast environment, only the latter purpose is likely
- to be relevant.
-
- Thus SDP includes:
-
- o Session name and purpose
-
- o Time(s) the session is active
-
- o The media comprising the session
-
- o Information to receive those media (addresses, ports, formats and
- so on)
-
- As resources necessary to participate in a session may be limited,
- some additional information may also be desirable:
-
- o Information about the bandwidth to be used by the conference
-
- o Contact information for the person responsible for the session
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 4]
-
-RFC 2327 SDP April 1998
-
-
- In general, SDP must convey sufficient information to be able to join
- a session (with the possible exception of encryption keys) and to
- announce the resources to be used to non-participants that may need
- to know.
-
-5.1. Media Information
-
- SDP includes:
-
- o The type of media (video, audio, etc)
-
- o The transport protocol (RTP/UDP/IP, H.320, etc)
-
- o The format of the media (H.261 video, MPEG video, etc)
-
- For an IP multicast session, the following are also conveyed:
-
- o Multicast address for media
-
- o Transport Port for media
-
- This address and port are the destination address and destination
- port of the multicast stream, whether being sent, received, or both.
-
- For an IP unicast session, the following are conveyed:
-
- o Remote address for media
-
- o Transport port for contact address
-
- The semantics of this address and port depend on the media and
- transport protocol defined. By default, this is the remote address
- and remote port to which data is sent, and the remote address and
- local port on which to receive data. However, some media may define
- to use these to establish a control channel for the actual media
- flow.
-
-5.2. Timing Information
-
- Sessions may either be bounded or unbounded in time. Whether or not
- they are bounded, they may be only active at specific times.
-
- SDP can convey:
-
- o An arbitrary list of start and stop times bounding the session
-
- o For each bound, repeat times such as "every Wednesday at 10am for
- one hour"
-
-
-
-Handley & Jacobson Standards Track [Page 5]
-
-RFC 2327 SDP April 1998
-
-
- This timing information is globally consistent, irrespective of local
- time zone or daylight saving time.
-
-5.3. Private Sessions
-
- It is possible to create both public sessions and private sessions.
- Private sessions will typically be conveyed by encrypting the session
- description to distribute it. The details of how encryption is
- performed are dependent on the mechanism used to convey SDP - see [4]
- for how this is done for session announcements.
-
- If a session announcement is private it is possible to use that
- private announcement to convey encryption keys necessary to decode
- each of the media in a conference, including enough information to
- know which encryption scheme is used for each media.
-
-5.4. Obtaining Further Information about a Session
-
- A session description should convey enough information to decide
- whether or not to participate in a session. SDP may include
- additional pointers in the form of Universal Resources Identifiers
- (URIs) for more information about the session.
-
-5.5. Categorisation
-
- When many session descriptions are being distributed by SAP or any
- other advertisement mechanism, it may be desirable to filter
- announcements that are of interest from those that are not. SDP
- supports a categorisation mechanism for sessions that is capable of
- being automated.
-
-5.6. Internationalization
-
- The SDP specification recommends the use of the ISO 10646 character
- sets in the UTF-8 encoding (RFC 2044) to allow many different
- languages to be represented. However, to assist in compact
- representations, SDP also allows other character sets such as ISO
- 8859-1 to be used when desired. Internationalization only applies to
- free-text fields (session name and background information), and not
- to SDP as a whole.
-
-6. SDP Specification
-
- SDP session descriptions are entirely textual using the ISO 10646
- character set in UTF-8 encoding. SDP field names and attributes names
- use only the US-ASCII subset of UTF-8, but textual fields and
- attribute values may use the full ISO 10646 character set. The
- textual form, as opposed to a binary encoding such as ASN/1 or XDR,
-
-
-
-Handley & Jacobson Standards Track [Page 6]
-
-RFC 2327 SDP April 1998
-
-
- was chosen to enhance portability, to enable a variety of transports
- to be used (e.g, session description in a MIME email message) and to
- allow flexible, text-based toolkits (e.g., Tcl/Tk ) to be used to
- generate and to process session descriptions. However, since the
- total bandwidth allocated to all SAP announcements is strictly
- limited, the encoding is deliberately compact. Also, since
- announcements may be transported via very unreliable means (e.g.,
- email) or damaged by an intermediate caching server, the encoding was
- designed with strict order and formatting rules so that most errors
- would result in malformed announcements which could be detected
- easily and discarded. This also allows rapid discarding of encrypted
- announcements for which a receiver does not have the correct key.
-
- An SDP session description consists of a number of lines of text of
- the form <type>=<value> <type> is always exactly one character and is
- case-significant. <value> is a structured text string whose format
- depends on <type>. It also will be case-significant unless a
- specific field defines otherwise. Whitespace is not permitted either
- side of the `=' sign. In general <value> is either a number of fields
- delimited by a single space character or a free format string.
-
- A session description consists of a session-level description
- (details that apply to the whole session and all media streams) and
- optionally several media-level descriptions (details that apply onto
- to a single media stream).
-
- An announcement consists of a session-level section followed by zero
- or more media-level sections. The session-level part starts with a
- `v=' line and continues to the first media-level section. The media
- description starts with an `m=' line and continues to the next media
- description or end of the whole session description. In general,
- session-level values are the default for all media unless overridden
- by an equivalent media-level value.
-
- When SDP is conveyed by SAP, only one session description is allowed
- per packet. When SDP is conveyed by other means, many SDP session
- descriptions may be concatenated together (the `v=' line indicating
- the start of a session description terminates the previous
- description). Some lines in each description are required and some
- are optional but all must appear in exactly the order given here (the
- fixed order greatly enhances error detection and allows for a simple
- parser). Optional items are marked with a `*'.
-
-Session description
- v= (protocol version)
- o= (owner/creator and session identifier).
- s= (session name)
- i=* (session information)
-
-
-
-Handley & Jacobson Standards Track [Page 7]
-
-RFC 2327 SDP April 1998
-
-
- u=* (URI of description)
- e=* (email address)
- p=* (phone number)
- c=* (connection information - not required if included in all media)
- b=* (bandwidth information)
- One or more time descriptions (see below)
- z=* (time zone adjustments)
- k=* (encryption key)
- a=* (zero or more session attribute lines)
- Zero or more media descriptions (see below)
-
-Time description
- t= (time the session is active)
- r=* (zero or more repeat times)
-
-Media description
- m= (media name and transport address)
- i=* (media title)
- c=* (connection information - optional if included at session-level)
- b=* (bandwidth information)
- k=* (encryption key)
- a=* (zero or more media attribute lines)
-
- The set of `type' letters is deliberately small and not intended to
- be extensible -- SDP parsers must completely ignore any announcement
- that contains a `type' letter that it does not understand. The
- `attribute' mechanism ("a=" described below) is the primary means for
- extending SDP and tailoring it to particular applications or media.
- Some attributes (the ones listed in this document) have a defined
- meaning but others may be added on an application-, media- or
- session-specific basis. A session directory must ignore any
- attribute it doesn't understand.
-
- The connection (`c=') and attribute (`a=') information in the
- session-level section applies to all the media of that session unless
- overridden by connection information or an attribute of the same name
- in the media description. For instance, in the example below, each
- media behaves as if it were given a `recvonly' attribute.
-
- An example SDP description is:
-
- v=0
- o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
- s=SDP Seminar
- i=A Seminar on the session description protocol
- u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps
- [email protected] (Mark Handley)
- c=IN IP4 224.2.17.12/127
-
-
-
-Handley & Jacobson Standards Track [Page 8]
-
-RFC 2327 SDP April 1998
-
-
- t=2873397496 2873404696
- a=recvonly
- m=audio 49170 RTP/AVP 0
- m=video 51372 RTP/AVP 31
- m=application 32416 udp wb
- a=orient:portrait
-
- Text records such as the session name and information are bytes
- strings which may contain any byte with the exceptions of 0x00 (Nul),
- 0x0a (ASCII newline) and 0x0d (ASCII carriage return). The sequence
- CRLF (0x0d0a) is used to end a record, although parsers should be
- tolerant and also accept records terminated with a single newline
- character. By default these byte strings contain ISO-10646
- characters in UTF-8 encoding, but this default may be changed using
- the `charset' attribute.
-
- Protocol Version
-
- v=0
-
- The "v=" field gives the version of the Session Description Protocol.
- There is no minor version number.
-
- Origin
-
- o=<username> <session id> <version> <network type> <address type>
- <address>
-
- The "o=" field gives the originator of the session (their username
- and the address of the user's host) plus a session id and session
- version number.
-
- <username> is the user's login on the originating host, or it is "-"
- if the originating host does not support the concept of user ids.
- <username> must not contain spaces. <session id> is a numeric string
- such that the tuple of <username>, <session id>, <network type>,
- <address type> and <address> form a globally unique identifier for
- the session.
-
- The method of <session id> allocation is up to the creating tool, but
- it has been suggested that a Network Time Protocol (NTP) timestamp be
- used to ensure uniqueness [1].
-
- <version> is a version number for this announcement. It is needed
- for proxy announcements to detect which of several announcements for
- the same session is the most recent. Again its usage is up to the
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 9]
-
-RFC 2327 SDP April 1998
-
-
- creating tool, so long as <version> is increased when a modification
- is made to the session data. Again, it is recommended (but not
- mandatory) that an NTP timestamp is used.
-
- <network type> is a text string giving the type of network.
- Initially "IN" is defined to have the meaning "Internet". <address
- type> is a text string giving the type of the address that follows.
- Initially "IP4" and "IP6" are defined. <address> is the globally
- unique address of the machine from which the session was created.
- For an address type of IP4, this is either the fully-qualified domain
- name of the machine, or the dotted-decimal representation of the IP
- version 4 address of the machine. For an address type of IP6, this
- is either the fully-qualified domain name of the machine, or the
- compressed textual representation of the IP version 6 address of the
- machine. For both IP4 and IP6, the fully-qualified domain name is
- the form that SHOULD be given unless this is unavailable, in which
- case the globally unique address may be substituted. A local IP
- address MUST NOT be used in any context where the SDP description
- might leave the scope in which the address is meaningful.
-
- In general, the "o=" field serves as a globally unique identifier for
- this version of this session description, and the subfields excepting
- the version taken together identify the session irrespective of any
- modifications.
-
- Session Name
-
- s=<session name>
-
- The "s=" field is the session name. There must be one and only one
- "s=" field per session description, and it must contain ISO 10646
- characters (but see also the `charset' attribute below).
-
- Session and Media Information
-
- i=<session description>
-
- The "i=" field is information about the session. There may be at
- most one session-level "i=" field per session description, and at
- most one "i=" field per media. Although it may be omitted, this is
- discouraged for session announcements, and user interfaces for
- composing sessions should require text to be entered. If it is
- present it must contain ISO 10646 characters (but see also the
- `charset' attribute below).
-
- A single "i=" field can also be used for each media definition. In
- media definitions, "i=" fields are primarily intended for labeling
- media streams. As such, they are most likely to be useful when a
-
-
-
-Handley & Jacobson Standards Track [Page 10]
-
-RFC 2327 SDP April 1998
-
-
- single session has more than one distinct media stream of the same
- media type. An example would be two different whiteboards, one for
- slides and one for feedback and questions.
-
- URI
-
- u=<URI>
-
- o A URI is a Universal Resource Identifier as used by WWW clients
-
- o The URI should be a pointer to additional information about the
- conference
-
- o This field is optional, but if it is present it should be specified
- before the first media field
-
- o No more than one URI field is allowed per session description
-
-
- Email Address and Phone Number
-
- e=<email address>
- p=<phone number>
-
- o These specify contact information for the person responsible for
- the conference. This is not necessarily the same person that
- created the conference announcement.
-
- o Either an email field or a phone field must be specified.
- Additional email and phone fields are allowed.
-
- o If these are present, they should be specified before the first
- media field.
-
- o More than one email or phone field can be given for a session
- description.
-
- o Phone numbers should be given in the conventional international
-
- format - preceded by a "+ and the international country code.
- There must be a space or a hyphen ("-") between the country code
- and the rest of the phone number. Spaces and hyphens may be used
- to split up a phone field to aid readability if desired. For
- example:
-
- p=+44-171-380-7777 or p=+1 617 253 6011
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 11]
-
-RFC 2327 SDP April 1998
-
-
- o Both email addresses and phone numbers can have an optional free
- text string associated with them, normally giving the name of the
- person who may be contacted. This should be enclosed in
- parenthesis if it is present. For example:
-
- [email protected] (Mark Handley)
-
- The alternative RFC822 name quoting convention is also allowed for
- both email addresses and phone numbers. For example,
-
- e=Mark Handley <[email protected]>
-
- The free text string should be in the ISO-10646 character set with
- UTF-8 encoding, or alternatively in ISO-8859-1 or other encodings
- if the appropriate charset session-level attribute is set.
-
- Connection Data
-
- c=<network type> <address type> <connection address>
-
- The "c=" field contains connection data.
-
- A session announcement must contain one "c=" field in each media
- description (see below) or a "c=" field at the session-level. It may
- contain a session-level "c=" field and one additional "c=" field per
- media description, in which case the per-media values override the
- session-level settings for the relevant media.
-
- The first sub-field is the network type, which is a text string
- giving the type of network. Initially "IN" is defined to have the
- meaning "Internet".
-
- The second sub-field is the address type. This allows SDP to be used
- for sessions that are not IP based. Currently only IP4 is defined.
-
- The third sub-field is the connection address. Optional extra
- subfields may be added after the connection address depending on the
- value of the <address type> field.
-
- For IP4 addresses, the connection address is defined as follows:
-
- o Typically the connection address will be a class-D IP multicast
-
- group address. If the session is not multicast, then the
- connection address contains the fully-qualified domain name or the
- unicast IP address of the expected data source or data relay or
- data sink as determined by additional attribute fields. It is not
- expected that fully-qualified domain names or unicast addresses
-
-
-
-Handley & Jacobson Standards Track [Page 12]
-
-RFC 2327 SDP April 1998
-
-
- will be given in a session description that is communicated by a
- multicast announcement, though this is not prohibited. If a
- unicast data stream is to pass through a network address
- translator, the use of a fully-qualified domain name rather than an
- unicast IP address is RECOMMENDED. In other cases, the use of an
- IP address to specify a particular interface on a multi-homed host
- might be required. Thus this specification leaves the decision as
- to which to use up to the individual application, but all
- applications MUST be able to cope with receiving both formats.
-
- o Conferences using an IP multicast connection address must also have
- a time to live (TTL) value present in addition to the multicast
- address. The TTL and the address together define the scope with
- which multicast packets sent in this conference will be sent. TTL
- values must be in the range 0-255.
-
- The TTL for the session is appended to the address using a slash as
- a separator. An example is:
-
- c=IN IP4 224.2.1.1/127
-
- Hierarchical or layered encoding schemes are data streams where the
- encoding from a single media source is split into a number of
- layers. The receiver can choose the desired quality (and hence
- bandwidth) by only subscribing to a subset of these layers. Such
- layered encodings are normally transmitted in multiple multicast
- groups to allow multicast pruning. This technique keeps unwanted
- traffic from sites only requiring certain levels of the hierarchy.
- For applications requiring multiple multicast groups, we allow the
- following notation to be used for the connection address:
-
- <base multicast address>/<ttl>/<number of addresses>
-
- If the number of addresses is not given it is assumed to be one.
- Multicast addresses so assigned are contiguously allocated above
- the base address, so that, for example:
-
- c=IN IP4 224.2.1.1/127/3
-
- would state that addresses 224.2.1.1, 224.2.1.2 and 224.2.1.3 are
- to be used at a ttl of 127. This is semantically identical to
- including multiple "c=" lines in a media description:
-
- c=IN IP4 224.2.1.1/127
- c=IN IP4 224.2.1.2/127
- c=IN IP4 224.2.1.3/127
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 13]
-
-RFC 2327 SDP April 1998
-
-
- Multiple addresses or "c=" lines can only be specified on a per-
- media basis, and not for a session-level "c=" field.
-
- It is illegal for the slash notation described above to be used for
- IP unicast addresses.
-
- Bandwidth
-
- b=<modifier>:<bandwidth-value>
-
- o This specifies the proposed bandwidth to be used by the session or
- media, and is optional.
-
- o <bandwidth-value> is in kilobits per second
-
- o <modifier> is a single alphanumeric word giving the meaning of the
- bandwidth figure.
-
- o Two modifiers are initially defined:
-
- CT Conference Total: An implicit maximum bandwidth is associated with
- each TTL on the Mbone or within a particular multicast
- administrative scope region (the Mbone bandwidth vs. TTL limits are
- given in the MBone FAQ). If the bandwidth of a session or media in
- a session is different from the bandwidth implicit from the scope,
- a `b=CT:...' line should be supplied for the session giving the
- proposed upper limit to the bandwidth used. The primary purpose of
- this is to give an approximate idea as to whether two or more
- conferences can co-exist simultaneously.
-
- AS Application-Specific Maximum: The bandwidth is interpreted to be
- application-specific, i.e., will be the application's concept of
- maximum bandwidth. Normally this will coincide with what is set on
- the application's "maximum bandwidth" control if applicable.
-
- Note that CT gives a total bandwidth figure for all the media at
- all sites. AS gives a bandwidth figure for a single media at a
- single site, although there may be many sites sending
- simultaneously.
-
- o Extension Mechanism: Tool writers can define experimental bandwidth
- modifiers by prefixing their modifier with "X-". For example:
-
- b=X-YZ:128
-
- SDP parsers should ignore bandwidth fields with unknown modifiers.
- Modifiers should be alpha-numeric and, although no length limit is
- given, they are recommended to be short.
-
-
-
-Handley & Jacobson Standards Track [Page 14]
-
-RFC 2327 SDP April 1998
-
-
- Times, Repeat Times and Time Zones
-
- t=<start time> <stop time>
-
- o "t=" fields specify the start and stop times for a conference
- session. Multiple "t=" fields may be used if a session is active
- at multiple irregularly spaced times; each additional "t=" field
- specifies an additional period of time for which the session will
- be active. If the session is active at regular times, an "r="
- field (see below) should be used in addition to and following a
- "t=" field - in which case the "t=" field specifies the start and
- stop times of the repeat sequence.
-
- o The first and second sub-fields give the start and stop times for
- the conference respectively. These values are the decimal
- representation of Network Time Protocol (NTP) time values in
- seconds [1]. To convert these values to UNIX time, subtract
- decimal 2208988800.
-
- o If the stop-time is set to zero, then the session is not bounded,
- though it will not become active until after the start-time. If
- the start-time is also zero, the session is regarded as permanent.
-
- User interfaces should strongly discourage the creation of
- unbounded and permanent sessions as they give no information about
- when the session is actually going to terminate, and so make
- scheduling difficult.
-
- The general assumption may be made, when displaying unbounded
- sessions that have not timed out to the user, that an unbounded
- session will only be active until half an hour from the current
- time or the session start time, whichever is the later. If
- behaviour other than this is required, an end-time should be given
- and modified as appropriate when new information becomes available
- about when the session should really end.
-
- Permanent sessions may be shown to the user as never being active
- unless there are associated repeat times which state precisely when
- the session will be active. In general, permanent sessions should
- not be created for any session expected to have a duration of less
- than 2 months, and should be discouraged for sessions expected to
- have a duration of less than 6 months.
-
- r=<repeat interval> <active duration> <list of offsets from start-
- time>
-
- o "r=" fields specify repeat times for a session. For example, if
- a session is active at 10am on Monday and 11am on Tuesday for one
-
-
-
-Handley & Jacobson Standards Track [Page 15]
-
-RFC 2327 SDP April 1998
-
-
- hour each week for three months, then the <start time> in the
- corresponding "t=" field would be the NTP representation of 10am on
- the first Monday, the <repeat interval> would be 1 week, the
- <active duration> would be 1 hour, and the offsets would be zero
- and 25 hours. The corresponding "t=" field stop time would be the
- NTP representation of the end of the last session three months
- later. By default all fields are in seconds, so the "r=" and "t="
- fields might be:
-
- t=3034423619 3042462419
- r=604800 3600 0 90000
-
- To make announcements more compact, times may also be given in units
- of days, hours or minutes. The syntax for these is a number
- immediately followed by a single case-sensitive character.
- Fractional units are not allowed - a smaller unit should be used
- instead. The following unit specification characters are allowed:
-
- d - days (86400 seconds)
- h - minutes (3600 seconds)
- m - minutes (60 seconds)
- s - seconds (allowed for completeness but not recommended)
-
- Thus, the above announcement could also have been written:
-
- r=7d 1h 0 25h
-
- Monthly and yearly repeats cannot currently be directly specified
- with a single SDP repeat time - instead separate "t" fields should
- be used to explicitly list the session times.
-
- z=<adjustment time> <offset> <adjustment time> <offset> ....
-
- o To schedule a repeated session which spans a change from daylight-
- saving time to standard time or vice-versa, it is necessary to
- specify offsets from the base repeat times. This is required
- because different time zones change time at different times of day,
- different countries change to or from daylight time on different
- dates, and some countries do not have daylight saving time at all.
-
- Thus in order to schedule a session that is at the same time winter
- and summer, it must be possible to specify unambiguously by whose
- time zone a session is scheduled. To simplify this task for
- receivers, we allow the sender to specify the NTP time that a time
- zone adjustment happens and the offset from the time when the
- session was first scheduled. The "z" field allows the sender to
- specify a list of these adjustment times and offsets from the base
- time.
-
-
-
-Handley & Jacobson Standards Track [Page 16]
-
-RFC 2327 SDP April 1998
-
-
- An example might be:
-
- z=2882844526 -1h 2898848070 0
-
- This specifies that at time 2882844526 the time base by which the
- session's repeat times are calculated is shifted back by 1 hour,
- and that at time 2898848070 the session's original time base is
- restored. Adjustments are always relative to the specified start
- time - they are not cumulative.
-
- o If a session is likely to last several years, it is expected
- that
- the session announcement will be modified periodically rather than
- transmit several years worth of adjustments in one announcement.
-
- Encryption Keys
-
- k=<method>
- k=<method>:<encryption key>
-
- o The session description protocol may be used to convey encryption
- keys. A key field is permitted before the first media entry (in
- which case it applies to all media in the session), or for each
- media entry as required.
-
- o The format of keys and their usage is outside the scope of this
- document, but see [3].
-
- o The method indicates the mechanism to be used to obtain a usable
- key by external means, or from the encoded encryption key given.
-
- The following methods are defined:
-
- k=clear:<encryption key>
- The encryption key (as described in [3] for RTP media streams
- under the AV profile) is included untransformed in this key
- field.
-
- k=base64:<encoded encryption key>
- The encryption key (as described in [3] for RTP media streams
- under the AV profile) is included in this key field but has been
- base64 encoded because it includes characters that are
- prohibited in SDP.
-
- k=uri:<URI to obtain key>
- A Universal Resource Identifier as used by WWW clients is
- included in this key field. The URI refers to the data
- containing the key, and may require additional authentication
-
-
-
-Handley & Jacobson Standards Track [Page 17]
-
-RFC 2327 SDP April 1998
-
-
- before the key can be returned. When a request is made to the
- given URI, the MIME content-type of the reply specifies the
- encoding for the key in the reply. The key should not be
- obtained until the user wishes to join the session to reduce
- synchronisation of requests to the WWW server(s).
-
- k=prompt
- No key is included in this SDP description, but the session or
- media stream referred to by this key field is encrypted. The
- user should be prompted for the key when attempting to join the
- session, and this user-supplied key should then be used to
- decrypt the media streams.
-
- Attributes
-
- a=<attribute>
- a=<attribute>:<value>
-
- Attributes are the primary means for extending SDP. Attributes may
- be defined to be used as "session-level" attributes, "media-level"
- attributes, or both.
-
- A media description may have any number of attributes ("a=" fields)
- which are media specific. These are referred to as "media-level"
- attributes and add information about the media stream. Attribute
- fields can also be added before the first media field; these
- "session-level" attributes convey additional information that applies
- to the conference as a whole rather than to individual media; an
- example might be the conference's floor control policy.
-
- Attribute fields may be of two forms:
-
- o property attributes. A property attribute is simply of the form
- "a=<flag>". These are binary attributes, and the presence of the
- attribute conveys that the attribute is a property of the session.
- An example might be "a=recvonly".
-
- o value attributes. A value attribute is of the form
- "a=<attribute>:<value>". An example might be that a whiteboard
- could have the value attribute "a=orient:landscape"
-
- Attribute interpretation depends on the media tool being invoked.
- Thus receivers of session descriptions should be configurable in
- their interpretation of announcements in general and of attributes in
- particular.
-
- Attribute names must be in the US-ASCII subset of ISO-10646/UTF-8.
-
-
-
-
-Handley & Jacobson Standards Track [Page 18]
-
-RFC 2327 SDP April 1998
-
-
- Attribute values are byte strings, and MAY use any byte value except
- 0x00 (Nul), 0x0A (LF), and 0x0D (CR). By default, attribute values
- are to be interpreted as in ISO-10646 character set with UTF-8
- encoding. Unlike other text fields, attribute values are NOT
- normally affected by the `charset' attribute as this would make
- comparisons against known values problematic. However, when an
- attribute is defined, it can be defined to be charset-dependent, in
- which case it's value should be interpreted in the session charset
- rather than in ISO-10646.
-
- Attributes that will be commonly used can be registered with IANA
- (see Appendix B). Unregistered attributes should begin with "X-" to
- prevent inadvertent collision with registered attributes. In either
- case, if an attribute is received that is not understood, it should
- simply be ignored by the receiver.
-
- Media Announcements
-
- m=<media> <port> <transport> <fmt list>
-
- A session description may contain a number of media descriptions.
- Each media description starts with an "m=" field, and is terminated
- by either the next "m=" field or by the end of the session
- description. A media field also has several sub-fields:
-
- o The first sub-field is the media type. Currently defined media are
- "audio", "video", "application", "data" and "control", though this
- list may be extended as new communication modalities emerge (e.g.,
- telepresense). The difference between "application" and "data" is
- that the former is a media flow such as whiteboard information, and
- the latter is bulk-data transfer such as multicasting of program
- executables which will not typically be displayed to the user.
- "control" is used to specify an additional conference control
- channel for the session.
-
- o The second sub-field is the transport port to which the media
- stream will be sent. The meaning of the transport port depends on
- the network being used as specified in the relevant "c" field and
- on the transport protocol defined in the third sub-field. Other
- ports used by the media application (such as the RTCP port, see
- [2]) should be derived algorithmically from the base media port.
-
- Note: For transports based on UDP, the value should be in the range
- 1024 to 65535 inclusive. For RTP compliance it should be an even
- number.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 19]
-
-RFC 2327 SDP April 1998
-
-
- For applications where hierarchically encoded streams are being
- sent to a unicast address, it may be necessary to specify multiple
- transport ports. This is done using a similar notation to that
- used for IP multicast addresses in the "c=" field:
-
- m=<media> <port>/<number of ports> <transport> <fmt list>
-
- In such a case, the ports used depend on the transport protocol.
- For RTP, only the even ports are used for data and the
- corresponding one-higher odd port is used for RTCP. For example:
-
- m=video 49170/2 RTP/AVP 31
-
- would specify that ports 49170 and 49171 form one RTP/RTCP pair and
- 49172 and 49173 form the second RTP/RTCP pair. RTP/AVP is the
- transport protocol and 31 is the format (see below).
-
- It is illegal for both multiple addresses to be specified in the
- "c=" field and for multiple ports to be specified in the "m=" field
- in the same session description.
-
- o The third sub-field is the transport protocol. The transport
- protocol values are dependent on the address-type field in the "c="
- fields. Thus a "c=" field of IP4 defines that the transport
- protocol runs over IP4. For IP4, it is normally expected that most
- media traffic will be carried as RTP over UDP. The following
- transport protocols are preliminarily defined, but may be extended
- through registration of new protocols with IANA:
-
- - RTP/AVP - the IETF's Realtime Transport Protocol using the
- Audio/Video profile carried over UDP.
-
- - udp - User Datagram Protocol
-
- If an application uses a single combined proprietary media format
- and transport protocol over UDP, then simply specifying the
- transport protocol as udp and using the format field to distinguish
- the combined protocol is recommended. If a transport protocol is
- used over UDP to carry several distinct media types that need to be
- distinguished by a session directory, then specifying the transport
- protocol and media format separately is necessary. RTP is an
- example of a transport-protocol that carries multiple payload
- formats that must be distinguished by the session directory for it
- to know how to start appropriate tools, relays, mixers or
- recorders.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 20]
-
-RFC 2327 SDP April 1998
-
-
- The main reason to specify the transport-protocol in addition to
- the media format is that the same standard media formats may be
- carried over different transport protocols even when the network
- protocol is the same - a historical example is vat PCM audio and
- RTP PCM audio. In addition, relays and monitoring tools that are
- transport-protocol-specific but format-independent are possible.
-
- For RTP media streams operating under the RTP Audio/Video Profile
- [3], the protocol field is "RTP/AVP". Should other RTP profiles be
- defined in the future, their profiles will be specified in the same
- way. For example, the protocol field "RTP/XYZ" would specify RTP
- operating under a profile whose short name is "XYZ".
-
- o The fourth and subsequent sub-fields are media formats. For audio
- and video, these will normally be a media payload type as defined
- in the RTP Audio/Video Profile.
-
- When a list of payload formats is given, this implies that all of
- these formats may be used in the session, but the first of these
- formats is the default format for the session.
-
- For media whose transport protocol is not RTP or UDP the format
- field is protocol specific. Such formats should be defined in an
- additional specification document.
-
- For media whose transport protocol is RTP, SDP can be used to
- provide a dynamic binding of media encoding to RTP payload type.
- The encoding names in the RTP AV Profile do not specify unique
- audio encodings (in terms of clock rate and number of audio
- channels), and so they are not used directly in SDP format fields.
- Instead, the payload type number should be used to specify the
- format for static payload types and the payload type number along
- with additional encoding information should be used for dynamically
- allocated payload types.
-
- An example of a static payload type is u-law PCM coded single
- channel audio sampled at 8KHz. This is completely defined in the
- RTP Audio/Video profile as payload type 0, so the media field for
- such a stream sent to UDP port 49232 is:
-
- m=video 49232 RTP/AVP 0
-
- An example of a dynamic payload type is 16 bit linear encoded
- stereo audio sampled at 16KHz. If we wish to use dynamic RTP/AVP
- payload type 98 for such a stream, additional information is
- required to decode it:
-
- m=video 49232 RTP/AVP 98
-
-
-
-Handley & Jacobson Standards Track [Page 21]
-
-RFC 2327 SDP April 1998
-
-
- a=rtpmap:98 L16/16000/2
-
- The general form of an rtpmap attribute is:
-
- a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding
- parameters>]
-
- For audio streams, <encoding parameters> may specify the number of
- audio channels. This parameter may be omitted if the number of
- channels is one provided no additional parameters are needed. For
- video streams, no encoding parameters are currently specified.
-
- Additional parameters may be defined in the future, but
- codecspecific parameters should not be added. Parameters added to
- an rtpmap attribute should only be those required for a session
- directory to make the choice of appropriate media too to
- participate in a session. Codec-specific parameters should be
- added in other attributes.
-
- Up to one rtpmap attribute can be defined for each media format
- specified. Thus we might have:
-
- m=audio 49230 RTP/AVP 96 97 98
- a=rtpmap:96 L8/8000
- a=rtpmap:97 L16/8000
- a=rtpmap:98 L16/11025/2
-
- RTP profiles that specify the use of dynamic payload types must
- define the set of valid encoding names and/or a means to register
- encoding names if that profile is to be used with SDP.
-
- Experimental encoding formats can also be specified using rtpmap.
- RTP formats that are not registered as standard format names must
- be preceded by "X-". Thus a new experimental redundant audio
- stream called GSMLPC using dynamic payload type 99 could be
- specified as:
-
- m=video 49232 RTP/AVP 99
- a=rtpmap:99 X-GSMLPC/8000
-
- Such an experimental encoding requires that any site wishing to
- receive the media stream has relevant configured state in its
- session directory to know which tools are appropriate.
-
- Note that RTP audio formats typically do not include information
- about the number of samples per packet. If a non-default (as
- defined in the RTP Audio/Video Profile) packetisation is required,
- the "ptime" attribute is used as given below.
-
-
-
-Handley & Jacobson Standards Track [Page 22]
-
-RFC 2327 SDP April 1998
-
-
- For more details on RTP audio and video formats, see [3].
-
- o Formats for non-RTP media should be registered as MIME content
- types as described in Appendix B. For example, the LBL whiteboard
- application might be registered as MIME content-type application/wb
- with encoding considerations specifying that it operates over UDP,
- with no appropriate file format. In SDP this would then be
- expressed using a combination of the "media" field and the "fmt"
- field, as follows:
-
- m=application 32416 udp wb
-
- Suggested Attributes
-
- The following attributes are suggested. Since application writers
- may add new attributes as they are required, this list is not
- exhaustive.
-
- a=cat:<category>
- This attribute gives the dot-separated hierarchical category of
- the session. This is to enable a receiver to filter unwanted
- sessions by category. It would probably have been a compulsory
- separate field, except for its experimental nature at this time.
- It is a session-level attribute, and is not dependent on charset.
-
- a=keywds:<keywords>
- Like the cat attribute, this is to assist identifying wanted
- sessions at the receiver. This allows a receiver to select
- interesting session based on keywords describing the purpose of
- the session. It is a session-level attribute. It is a charset
- dependent attribute, meaning that its value should be interpreted
- in the charset specified for the session description if one is
- specified, or by default in ISO 10646/UTF-8.
-
- a=tool:<name and version of tool>
- This gives the name and version number of the tool used to create
- the session description. It is a session-level attribute, and is
- not dependent on charset.
-
- a=ptime:<packet time>
- This gives the length of time in milliseconds represented by the
- media in a packet. This is probably only meaningful for audio
- data. It should not be necessary to know ptime to decode RTP or
- vat audio, and it is intended as a recommendation for the
- encoding/packetisation of audio. It is a media attribute, and is
- not dependent on charset.
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 23]
-
-RFC 2327 SDP April 1998
-
-
- a=recvonly
- This specifies that the tools should be started in receive-only
- mode where applicable. It can be either a session or media
- attribute, and is not dependent on charset.
-
- a=sendrecv
- This specifies that the tools should be started in send and
- receive mode. This is necessary for interactive conferences with
- tools such as wb which defaults to receive only mode. It can be
- either a session or media attribute, and is not dependent on
- charset.
-
- a=sendonly
- This specifies that the tools should be started in send-only
- mode. An example may be where a different unicast address is to
- be used for a traffic destination than for a traffic source. In
- such a case, two media descriptions may be use, one sendonly and
- one recvonly. It can be either a session or media attribute, but
- would normally only be used as a media attribute, and is not
- dependent on charset.
-
- a=orient:<whiteboard orientation>
- Normally this is only used in a whiteboard media specification.
- It specifies the orientation of a the whiteboard on the screen.
- It is a media attribute. Permitted values are `portrait',
- `landscape' and `seascape' (upside down landscape). It is not
- dependent on charset
-
- a=type:<conference type>
- This specifies the type of the conference. Suggested values are
- `broadcast', `meeting', `moderated', `test' and `H332'.
- `recvonly' should be the default for `type:broadcast' sessions,
- `type:meeting' should imply `sendrecv' and `type:moderated'
- should indicate the use of a floor control tool and that the
- media tools are started so as to "mute" new sites joining the
- conference.
-
- Specifying the attribute type:H332 indicates that this loosely
- coupled session is part of a H.332 session as defined in the ITU
- H.332 specification [10]. Media tools should be started
- `recvonly'.
-
- Specifying the attribute type:test is suggested as a hint that,
- unless explicitly requested otherwise, receivers can safely avoid
- displaying this session description to users.
-
- The type attribute is a session-level attribute, and is not
- dependent on charset.
-
-
-
-Handley & Jacobson Standards Track [Page 24]
-
-RFC 2327 SDP April 1998
-
-
- a=charset:<character set>
- This specifies the character set to be used to display the
- session name and information data. By default, the ISO-10646
- character set in UTF-8 encoding is used. If a more compact
- representation is required, other character sets may be used such
- as ISO-8859-1 for Northern European languages. In particular,
- the ISO 8859-1 is specified with the following SDP attribute:
-
- a=charset:ISO-8859-1
-
- This is a session-level attribute; if this attribute is present,
- it must be before the first media field. The charset specified
- MUST be one of those registered with IANA, such as ISO-8859-1.
- The character set identifier is a US-ASCII string and MUST be
- compared against the IANA identifiers using a case-insensitive
- comparison. If the identifier is not recognised or not
- supported, all strings that are affected by it SHOULD be regarded
- as byte strings.
-
- Note that a character set specified MUST still prohibit the use
- of bytes 0x00 (Nul), 0x0A (LF) and 0x0d (CR). Character sets
- requiring the use of these characters MUST define a quoting
- mechanism that prevents these bytes appearing within text fields.
-
- a=sdplang:<language tag>
- This can be a session level attribute or a media level attribute.
- As a session level attribute, it specifies the language for the
- session description. As a media level attribute, it specifies
- the language for any media-level SDP information field associated
- with that media. Multiple sdplang attributes can be provided
- either at session or media level if multiple languages in the
- session description or media use multiple languages, in which
- case the order of the attributes indicates the order of
- importance of the various languages in the session or media from
- most important to least important.
-
- In general, sending session descriptions consisting of multiple
- languages should be discouraged. Instead, multiple descriptions
- should be sent describing the session, one in each language.
- However this is not possible with all transport mechanisms, and
- so multiple sdplang attributes are allowed although not
- recommended.
-
- The sdplang attribute value must be a single RFC 1766 language
- tag in US-ASCII. It is not dependent on the charset attribute.
- An sdplang attribute SHOULD be specified when a session is of
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 25]
-
-RFC 2327 SDP April 1998
-
-
- sufficient scope to cross geographic boundaries where the
- language of recipients cannot be assumed, or where the session is
- in a different language from the locally assumed norm.
-
- a=lang:<language tag>
- This can be a session level attribute or a media level attribute.
- As a session level attribute, it specifies the default language
- for the session being described. As a media level attribute, it
- specifies the language for that media, overriding any session-
- level language specified. Multiple lang attributes can be
- provided either at session or media level if multiple languages
- if the session description or media use multiple languages, in
- which case the order of the attributes indicates the order of
- importance of the various languages in the session or media from
- most important to least important.
-
- The lang attribute value must be a single RFC 1766 language tag
- in US-ASCII. It is not dependent on the charset attribute. A
- lang attribute SHOULD be specified when a session is of
- sufficient scope to cross geographic boundaries where the
- language of recipients cannot be assumed, or where the session is
- in a different language from the locally assumed norm.
-
- a=framerate:<frame rate>
- This gives the maximum video frame rate in frames/sec. It is
- intended as a recommendation for the encoding of video data.
- Decimal representations of fractional values using the notation
- "<integer>.<fraction>" are allowed. It is a media attribute, is
- only defined for video media, and is not dependent on charset.
-
- a=quality:<quality>
- This gives a suggestion for the quality of the encoding as an
- integer value.
-
- The intention of the quality attribute for video is to specify a
- non-default trade-off between frame-rate and still-image quality.
- For video, the value in the range 0 to 10, with the following
- suggested meaning:
-
- 10 - the best still-image quality the compression scheme can
- give.
-
- 5 - the default behaviour given no quality suggestion.
-
- 0 - the worst still-image quality the codec designer thinks is
- still usable.
-
- It is a media attribute, and is not dependent on charset.
-
-
-
-Handley & Jacobson Standards Track [Page 26]
-
-RFC 2327 SDP April 1998
-
-
- a=fmtp:<format> <format specific parameters>
- This attribute allows parameters that are specific to a
- particular format to be conveyed in a way that SDP doesn't have
- to understand them. The format must be one of the formats
- specified for the media. Format-specific parameters may be any
- set of parameters required to be conveyed by SDP and given
- unchanged to the media tool that will use this format.
-
- It is a media attribute, and is not dependent on charset.
-
-6.1. Communicating Conference Control Policy
-
- There is some debate over the way conference control policy should be
- communicated. In general, the authors believe that an implicit
- declarative style of specifying conference control is desirable where
- possible.
-
- A simple declarative style uses a single conference attribute field
- before the first media field, possibly supplemented by properties
- such as `recvonly' for some of the media tools. This conference
- attribute conveys the conference control policy. An example might be:
-
- a=type:moderated
-
- In some cases, however, it is possible that this may be insufficient
- to communicate the details of an unusual conference control policy.
- If this is the case, then a conference attribute specifying external
- control might be set, and then one or more "media" fields might be
- used to specify the conference control tools and configuration data
- for those tools. An example is an ITU H.332 session:
-
- c=IN IP4 224.5.6.7
- a=type:H332
- m=audio 49230 RTP/AVP 0
- m=video 49232 RTP/AVP 31
- m=application 12349 udp wb
- m=control 49234 H323 mc
- c=IN IP4 134.134.157.81
-
- In this example, a general conference attribute (type:H332) is
- specified stating that conference control will be provided by an
- external H.332 tool, and a contact addresses for the H.323 session
- multipoint controller is given.
-
- In this document, only the declarative style of conference control
- declaration is specified. Other forms of conference control should
- specify an appropriate type attribute, and should define the
- implications this has for control media.
-
-
-
-Handley & Jacobson Standards Track [Page 27]
-
-RFC 2327 SDP April 1998
-
-
-7. Security Considerations
-
- SDP is a session description format that describes multimedia
- sessions. A session description should not be trusted unless it has
- been obtained by an authenticated transport protocol from a trusted
- source. Many different transport protocols may be used to distribute
- session description, and the nature of the authentication will differ
- from transport to transport.
-
- One transport that will frequently be used to distribute session
- descriptions is the Session Announcement Protocol (SAP). SAP
- provides both encryption and authentication mechanisms but due to the
- nature of session announcements it is likely that there are many
- occasions where the originator of a session announcement cannot be
- authenticated because they are previously unknown to the receiver of
- the announcement and because no common public key infrastructure is
- available.
-
- On receiving a session description over an unauthenticated transport
- mechanism or from an untrusted party, software parsing the session
- should take a few precautions. Session description contain
- information required to start software on the receivers system.
- Software that parses a session description MUST not be able to start
- other software except that which is specifically configured as
- appropriate software to participate in multimedia sessions. It is
- normally considered INAPPROPRIATE for software parsing a session
- description to start, on a user's system, software that is
- appropriate to participate in multimedia sessions, without the user
- first being informed that such software will be started and giving
- their consent. Thus a session description arriving by session
- announcement, email, session invitation, or WWW page SHOULD not
- deliver the user into an {it interactive} multimedia session without
- the user being aware that this will happen. As it is not always
- simple to tell whether a session is interactive or not, applications
- that are unsure should assume sessions are interactive.
-
- In this specification, there are no attributes which would allow the
- recipient of a session description to be informed to start multimedia
- tools in a mode where they default to transmitting. Under some
- circumstances it might be appropriate to define such attributes. If
- this is done an application parsing a session description containing
- such attributes SHOULD either ignore them, or inform the user that
- joining this session will result in the automatic transmission of
- multimedia data. The default behaviour for an unknown attribute is
- to ignore it.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 28]
-
-RFC 2327 SDP April 1998
-
-
- Session descriptions may be parsed at intermediate systems such as
- firewalls for the purposes of opening a hole in the firewall to allow
- the participation in multimedia sessions. It is considered
- INAPPROPRIATE for a firewall to open such holes for unicast data
- streams unless the session description comes in a request from inside
- the firewall.
-
- For multicast sessions, it is likely that local administrators will
- apply their own policies, but the exclusive use of "local" or "site-
- local" administrative scope within the firewall and the refusal of
- the firewall to open a hole for such scopes will provide separation
- of global multicast sessions from local ones.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 29]
-
-RFC 2327 SDP April 1998
-
-
-Appendix A: SDP Grammar
-
- This appendix provides an Augmented BNF grammar for SDP. ABNF is
- defined in RFC 2234.
-
-
- announcement = proto-version
- origin-field
- session-name-field
- information-field
- uri-field
- email-fields
- phone-fields
- connection-field
- bandwidth-fields
- time-fields
- key-field
- attribute-fields
- media-descriptions
-
- proto-version = "v=" 1*DIGIT CRLF
- ;this memo describes version 0
-
- origin-field = "o=" username space
- sess-id space sess-version space
- nettype space addrtype space
- addr CRLF
-
- session-name-field = "s=" text CRLF
-
- information-field = ["i=" text CRLF]
-
- uri-field = ["u=" uri CRLF]
-
- email-fields = *("e=" email-address CRLF)
-
- phone-fields = *("p=" phone-number CRLF)
-
-
- connection-field = ["c=" nettype space addrtype space
- connection-address CRLF]
- ;a connection field must be present
- ;in every media description or at the
- ;session-level
-
-
- bandwidth-fields = *("b=" bwtype ":" bandwidth CRLF)
-
-
-
-
-Handley & Jacobson Standards Track [Page 30]
-
-RFC 2327 SDP April 1998
-
-
- time-fields = 1*( "t=" start-time space stop-time
- *(CRLF repeat-fields) CRLF)
- [zone-adjustments CRLF]
-
-
- repeat-fields = "r=" repeat-interval space typed-time
- 1*(space typed-time)
-
-
- zone-adjustments = time space ["-"] typed-time
- *(space time space ["-"] typed-time)
-
-
- key-field = ["k=" key-type CRLF]
-
-
- key-type = "prompt" |
- "clear:" key-data |
- "base64:" key-data |
- "uri:" uri
-
-
- key-data = email-safe | "~" | "
-
-
- attribute-fields = *("a=" attribute CRLF)
-
-
- media-descriptions = *( media-field
- information-field
- *(connection-field)
- bandwidth-fields
- key-field
- attribute-fields )
-
-
- media-field = "m=" media space port ["/" integer]
- space proto 1*(space fmt) CRLF
-
-
- media = 1*(alpha-numeric)
- ;typically "audio", "video", "application"
- ;or "data"
-
- fmt = 1*(alpha-numeric)
- ;typically an RTP payload type for audio
- ;and video media
-
-
-
-
-Handley & Jacobson Standards Track [Page 31]
-
-RFC 2327 SDP April 1998
-
-
- proto = 1*(alpha-numeric)
- ;typically "RTP/AVP" or "udp" for IP4
-
-
- port = 1*(DIGIT)
- ;should in the range "1024" to "65535" inclusive
- ;for UDP based media
-
-
- attribute = (att-field ":" att-value) | att-field
-
-
- att-field = 1*(alpha-numeric)
-
-
- att-value = byte-string
-
-
- sess-id = 1*(DIGIT)
- ;should be unique for this originating username/host
-
-
- sess-version = 1*(DIGIT)
- ;0 is a new session
-
-
- connection-address = multicast-address
- | addr
-
-
- multicast-address = 3*(decimal-uchar ".") decimal-uchar "/" ttl
- [ "/" integer ]
- ;multicast addresses may be in the range
- ;224.0.0.0 to 239.255.255.255
-
- ttl = decimal-uchar
-
- start-time = time | "0"
-
- stop-time = time | "0"
-
- time = POS-DIGIT 9*(DIGIT)
- ;sufficient for 2 more centuries
-
-
- repeat-interval = typed-time
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 32]
-
-RFC 2327 SDP April 1998
-
-
- typed-time = 1*(DIGIT) [fixed-len-time-unit]
-
-
- fixed-len-time-unit = "d" | "h" | "m" | "s"
-
-
- bwtype = 1*(alpha-numeric)
-
- bandwidth = 1*(DIGIT)
-
-
- username = safe
- ;pretty wide definition, but doesn't include space
-
-
- email-address = email | email "(" email-safe ")" |
- email-safe "<" email ">"
-
-
- email = ;defined in RFC822
-
-
- uri= ;defined in RFC1630
-
-
- phone-number = phone | phone "(" email-safe ")" |
- email-safe "<" phone ">"
-
-
- phone = "+" POS-DIGIT 1*(space | "-" | DIGIT)
- ;there must be a space or hyphen between the
- ;international code and the rest of the number.
-
-
- nettype = "IN"
- ;list to be extended
-
-
- addrtype = "IP4" | "IP6"
- ;list to be extended
-
-
- addr = FQDN | unicast-address
-
-
- FQDN = 4*(alpha-numeric|"-"|".")
- ;fully qualified domain name as specified in RFC1035
-
-
-
-
-Handley & Jacobson Standards Track [Page 33]
-
-RFC 2327 SDP April 1998
-
-
- unicast-address = IP4-address | IP6-address
-
-
- IP4-address = b1 "." decimal-uchar "." decimal-uchar "." b4
- b1 = decimal-uchar
- ;less than "224"; not "0" or "127"
- b4 = decimal-uchar
- ;not "0"
-
- IP6-address = ;to be defined
-
-
- text = byte-string
- ;default is to interpret this as IS0-10646 UTF8
- ;ISO 8859-1 requires a "a=charset:ISO-8859-1"
- ;session-level attribute to be used
-
-
- byte-string = 1*(0x01..0x09|0x0b|0x0c|0x0e..0xff)
- ;any byte except NUL, CR or LF
-
-
- decimal-uchar = DIGIT
- | POS-DIGIT DIGIT
- | ("1" 2*(DIGIT))
- | ("2" ("0"|"1"|"2"|"3"|"4") DIGIT)
- | ("2" "5" ("0"|"1"|"2"|"3"|"4"|"5"))
-
-
- integer = POS-DIGIT *(DIGIT)
-
-
- alpha-numeric = ALPHA | DIGIT
-
-
- DIGIT = "0" | POS-DIGIT
-
-
- POS-DIGIT = "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
-
-
- ALPHA = "a"|"b"|"c"|"d"|"e"|"f"|"g"|"h"|"i"|"j"|"k"|
- "l"|"m"|"n"|"o "|"p"|"q"|"r"|"s"|"t"|"u"|"v"|
- "w"|"x"|"y"|"z"|"A"|"B"|"C "|"D"|"E"|"F"|"G"|
- "H"|"I"|"J"|"K"|"L"|"M"|"N"|"O"|"P"|" Q"|"R"|
- "S"|"T"|"U"|"V"|"W"|"X"|"Y"|"Z"
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 34]
-
-RFC 2327 SDP April 1998
-
-
- email-safe = safe | space | tab
-
-
- safe = alpha-numeric |
- "'" | "'" | "-" | "." | "/" | ":" | "?" | """ |
- "#" | "$" | "&" | "*" | ";" | "=" | "@" | "[" |
- "]" | "^" | "_" | "`" | "{" | "|" | "}" | "+" |
- "~" | "
-
-
- space = %d32
- tab = %d9
- CRLF = %d13.10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 35]
-
-RFC 2327 SDP April 1998
-
-
-Appendix B: Guidelines for registering SDP names with IANA
-
- There are seven field names that may be registered with IANA. Using
- the terminology in the SDP specification BNF, they are "media",
- "proto", "fmt", "att-field", "bwtype", "nettype" and "addrtype".
-
- "media" (eg, audio, video, application, data).
-
- Packetized media types, such as those used by RTP, share the
- namespace used by media types registry [RFC 2048] (i.e. "MIME
- types"). The list of valid media names is the set of top-level
- MIME content types. The set of media is intended to be small and
- not to be extended except under rare circumstances. (The MIME
- subtype corresponds to the "fmt" parameter below).
-
- "proto"
-
- In general this should be an IETF standards-track transport
- protocol identifier such as RTP/AVP (rfc 1889 under the rfc 1890
- profile).
-
- However, people will want to invent their own proprietary
- transport protocols. Some of these should be registered as a
- "fmt" using "udp" as the protocol and some of which probably
- can't be.
-
- Where the protocol and the application are intimately linked,
- such as with the LBL whiteboard wb which used a proprietary and
- special purpose protocol over UDP, the protocol name should be
- "udp" and the format name that should be registered is "wb". The
- rules for formats (see below) apply to such registrations.
-
- Where the proprietary transport protocol really carries many
- different data formats, it is possible to register a new protocol
- name with IANA. In such a case, an RFC MUST be produced
- describing the protocol and referenced in the registration. Such
- an RFC MAY be informational, although it is preferable if it is
- standards-track.
-
- "fmt"
-
- The format namespace is dependent on the context of the "proto"
- field, so a format cannot be registered without specifying one or
- more transport protocols that it applies to.
-
- Formats cover all the possible encodings that might want to be
- transported in a multimedia session.
-
-
-
-
-Handley & Jacobson Standards Track [Page 36]
-
-RFC 2327 SDP April 1998
-
-
- For RTP formats that have been assigned static payload types, the
- payload type number is used. For RTP formats using a dynamic
- payload type number, the dynamic payload type number is given as
- the format and an additional "rtpmap" attribute specifies the
- format and parameters.
-
- For non-RTP formats, any unregistered format name may be
- registered through the MIME-type registration process [RFC 2048].
- The type given here is the MIME subtype only (the top-level MIME
- content type is specified by the media parameter). The MIME type
- registration SHOULD reference a standards-track RFC which
- describes the transport protocol for this media type. If there
- is an existing MIME type for this format, the MIME registration
- should be augmented to reference the transport specification for
- this media type. If there is not an existing MIME type for this
- format, and there exists no appropriate file format, this should
- be noted in the encoding considerations as "no appropriate file
- format".
-
- "att-field" (Attribute names)
-
- Attribute field names MAY be registered with IANA, although this
- is not compulsory, and unknown attributes are simply ignored.
-
- When an attribute is registered, it must be accompanied by a
- brief specification stating the following:
-
- o contact name, email address and telephone number
-
- o attribute-name (as it will appear in SDP)
-
- o long-form attribute name in English
-
- o type of attribute (session level, media level, or both)
-
- o whether the attribute value is subject to the charset
- attribute.
-
- o a one paragraph explanation of the purpose of the attribute.
-
- o a specification of appropriate attribute values for this
- attribute.
-
- IANA will not sanity check such attribute registrations except to
- ensure that they do not clash with existing registrations.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 37]
-
-RFC 2327 SDP April 1998
-
-
- Although the above is the minimum that IANA will accept, if the
- attribute is expected to see widespread use and interoperability
- is an issue, authors are encouraged to produce a standards-track
- RFC that specifies the attribute more precisely.
-
- Submitters of registrations should ensure that the specification
- is in the spirit of SDP attributes, most notably that the
- attribute is platform independent in the sense that it makes no
- implicit assumptions about operating systems and does not name
- specific pieces of software in a manner that might inhibit
- interoperability.
-
- "bwtype" (bandwidth specifiers)
-
- A proliferation of bandwidth specifiers is strongly discouraged.
-
- New bandwidth specifiers may be registered with IANA. The
- submission MUST reference a standards-track RFC specifying the
- semantics of the bandwidth specifier precisely, and indicating
- when it should be used, and why the existing registered bandwidth
- specifiers do not suffice.
-
- "nettype" (Network Type)
-
- New network types may be registered with IANA if SDP needs to be
- used in the context of non-internet environments. Whilst these
- are not normally the preserve of IANA, there may be circumstances
- when an Internet application needs to interoperate with a non-
- internet application, such as when gatewaying an internet
- telephony call into the PSTN. The number of network types should
- be small and should be rarely extended. A new network type
- cannot be registered without registering at least one address
- type to be used with that network type. A new network type
- registration MUST reference an RFC which gives details of the
- network type and address type and specifies how and when they
- would be used. Such an RFC MAY be Informational.
-
- "addrtype" (Address Type)
-
- New address types may be registered with IANA. An address type
- is only meaningful in the context of a network type, and any
- registration of an address type MUST specify a registered network
- type, or be submitted along with a network type registration. A
- new address type registration MUST reference an RFC giving
- details of the syntax of the address type. Such an RFC MAY be
- Informational. Address types are not expected to be registered
- frequently.
-
-
-
-
-Handley & Jacobson Standards Track [Page 38]
-
-RFC 2327 SDP April 1998
-
-
- Registration Procedure
-
- To register a name the above guidelines should be followed regarding
- the required level of documentation that is required. The
- registration itself should be sent to IANA. Attribute registrations
- should include the information given above. Other registrations
- should include the following additional information:
-
- o contact name, email address and telephone number
-
- o name being registered (as it will appear in SDP)
-
- o long-form name in English
-
- o type of name ("media", "proto", "fmt", "bwtype", "nettype", or
- "addrtype")
-
- o a one paragraph explanation of the purpose of the registered name.
-
- o a reference to the specification (eg RFC number) of the registered
- name.
-
- IANA may refer any registration to the IESG or to any appropriate
- IETF working group for review, and may request revisions to be made
- before a registration will be made.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 39]
-
-RFC 2327 SDP April 1998
-
-
-Appendix C: Authors' Addresses
-
- Mark Handley
- Information Sciences Institute
- c/o MIT Laboratory for Computer Science
- 545 Technology Square
- Cambridge, MA 02139
- United States
- electronic mail: [email protected]
-
- Van Jacobson
- MS 46a-1121
- Lawrence Berkeley Laboratory
- Berkeley, CA 94720
- United States
- electronic mail: [email protected]
-
-Acknowledgments
-
- Many people in the IETF MMUSIC working group have made comments and
- suggestions contributing to this document. In particular, we would
- like to thank Eve Schooler, Steve Casner, Bill Fenner, Allison
- Mankin, Ross Finlayson, Peter Parnes, Joerg Ott, Carsten Bormann, Rob
- Lanphier and Steve Hanna.
-
-References
-
- [1] Mills, D., "Network Time Protocol (version 3) specification and
- implementation", RFC 1305, March 1992.
-
- [2] Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson, "RTP:
- A Transport Protocol for Real-Time Applications", RFC 1889, January
- 1996.
-
- [3] Schulzrinne, H., "RTP Profile for Audio and Video Conferences
- with Minimal Control", RFC 1890, January 1996
-
- [4] Handley, M., "SAP - Session Announcement Protocol", Work in
- Progress.
-
- [5] V. Jacobson, S. McCanne, "vat - X11-based audio teleconferencing
- tool" vat manual page, Lawrence Berkeley Laboratory, 1994.
-
- [6] The Unicode Consortium, "The Unicode Standard -- Version 2.0",
- Addison-Wesley, 1996.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 40]
-
-RFC 2327 SDP April 1998
-
-
- [7] ISO/IEC 10646-1:1993. International Standard -- Information
- technol- ogy -- Universal Multiple-Octet Coded Character Set (UCS) --
- Part 1: Architecture and Basic Multilingual Plane. Five amendments
- and a techn- ical corrigendum have been published up to now. UTF-8
- is described in Annex R, published as Amendment 2.
-
- [8] Goldsmith, D., and M. Davis, "Using Unicode with MIME", RFC 1641,
- July 1994.
-
- [9] Yergeau, F., "UTF-8, a transformation format of Unicode and ISO
- 10646", RFC 2044, October 1996.
-
- [10] ITU-T Recommendation H.332 (1998): "Multimedia Terminal for
- Receiving Internet-based H.323 Conferences", ITU, Geneva.
-
- [11] Handley, M., Schooler, E., and H. Schulzrinne, "Session
- Initiation Protocol (SIP)", Work in Progress.
-
- [12] Schulzrinne, H., Rao, A., and R. Lanphier, "Real Time Streaming
- Protocol (RTSP)", RFC 2326, April 1998.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 41]
-
-RFC 2327 SDP April 1998
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (1998). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 42]
-
diff --git a/lib/megaco/doc/standard/rfc3266.txt b/lib/megaco/doc/standard/rfc3266.txt
deleted file mode 100644
index f047f12a1f..0000000000
--- a/lib/megaco/doc/standard/rfc3266.txt
+++ /dev/null
@@ -1,283 +0,0 @@
-
-
-
-
-
-
-Network Working Group S. Olson
-Request for Comments: 3266 Microsoft
-Updates: 2327 G. Camarillo
-Category: Standards Track Ericsson
- A. B. Roach
- dynamicsoft
- June 2002
-
-
- Support for IPv6 in Session Description Protocol (SDP)
-
-Status of this Memo
-
- This document specifies an Internet standards track protocol for the
- Internet community, and requests discussion and suggestions for
- improvements. Please refer to the current edition of the "Internet
- Official Protocol Standards" (STD 1) for the standardization state
- and status of this protocol. Distribution of this memo is unlimited.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- This document describes the use of Internet Protocol Version 6 (IPv6)
- addresses in conjunction with the Session Description Protocol (SDP).
- Specifically, this document clarifies existing text in SDP with
- regards to the syntax of IPv6 addresses.
-
-1. Introduction
-
- SDP is intended for describing multimedia sessions for the purposes
- of session announcement, session invitation, and other forms of
- multimedia session initiation. It is a text format description that
- provides many details of a multimedia session including: the
- originator of the session, a URL related to the session, the
- connection address for the session media(s), and optional attributes
- for the session media(s). Each of these pieces of information may
- involve one or more IPv6 addresses. The ABNF for IP addresses in SDP
- currently leaves the syntax for IPv6 addresses undefined. This
- document attempts to complete the ABNF to include IPv6 addresses.
-
- Accordingly, the address type "IP6" indicating an IPv6 address,
- should be allowed in the connection field, "c=", of the SDP. The
- ABNF already reflects this, though the "Connection Data" text under
- section 6 of RFC 2328 currently only defines the "IP4" address type.
-
-
-
-
-Olson, et. al. Standards Track [Page 1]
-
-RFC 3266 Support for IPv6 in Session Description Protocol June 2002
-
-
-2. Terminology
-
- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
- document are to be interpreted as described in RFC 2119 [5].
-
-3. Syntax
-
- RFC 2373 [1] gives an ABNF for the text representation of IPv6
- addresses in Appendix B. RFC 2732 [3] covers the text representation
- of IPv6 addresses when used within a URL. Using the ABNF described
- in these documents, the following updated ABNF for SDP is proposed.
-
- uri = ; defined in RFC1630 and RFC2732
-
- multicast-address = IP4-multicast / IP6-multicast
-
- IP4-multicast = m1 3*( "." decimal-uchar )
- "/" ttl [ "/" integer ]
- ; IPv4 multicast addresses may be in the
- ; range 224.0.0.0 to 239.255.255.255
-
- m1 = ("22" ("4"/"5"/"6"/"7"/"8"/"9")) /
- ("23" DIGIT ))
-
- IP6-multicast = hexpart
- ; IPv6 address starting with FF
-
- addr = FQDN / unicast-address
-
- FQDN = 4*(alpha-numeric/"-"/".")
- ; fully qualified domain name as specified
- ; in RFC1035
- unicast-address = IP4-address / IP6-address
-
- IP4-address = b1 3*("." decimal-uchar) / "0.0.0.0"
-
- b1 = decimal-uchar
- ; less than "224"; not "0" or "127"
-
- ; The following is from RFC2373 Appendix B. It is a direct copy.
- IP6-address = hexpart [ ":" IP4-address ]
-
- hexpart = hexseq / hexseq "::" [ hexseq ] /
- "::" [ hexseq ]
-
-
-
-
-
-
-Olson, et. al. Standards Track [Page 2]
-
-RFC 3266 Support for IPv6 in Session Description Protocol June 2002
-
-
- hexseq = hex4 *( ":" hex4)
-
- hex4 = 1*4HEXDIG
-
-4. Example SDP description with IPv6 addresses
-
- The following is an example SDP description using the above ABNF for
- IPv6 addresses. In particular, the origin and connection fields
- contain IPv6 addresses.
-
- v=0
- o=nasa1 971731711378798081 0 IN IP6 2201:056D::112E:144A:1E24
- s=(Almost) live video feed from Mars-II satellite
- p=+1 713 555 1234
- c=IN IP6 FF1E:03AD::7F2E:172A:1E24
- t=3338481189 3370017201
- m=audio 6000 RTP/AVP 2
- a=rtpmap:2 G726-32/8000
- m=video 6024 RTP/AVP 107
- a=rtpmap:107 H263-1998/90000
-
-5. Note for implementors
-
- An implementation may receive an SDP session description with an IPv6
- address whose format [1] is internally that of an IPv4 mapped
- address. Note that such an address is actually the address of an
- IPv4-only node, and implementors are warned to interpret IPv4 mapped
- addresses as equivalent to IP4.
-
-6. IANA Considerations
-
- This document updates the definition of the IP6 addrtype parameter
- found in RFC 2327.
-
-7. Security Considerations
-
- No additional considerations above what is stated in section 7 of RFC
- 2327.
-
-8. References
-
- [1] Hinden, R. and S. Deering, "IP Version 6 Addressing
- Architecture", RFC 2373, July 1998.
-
- [2] Handley, M. and V. Jacobson, "SDP: Session Description
- Protocol", RFC 2327, April 1998.
-
-
-
-
-
-Olson, et. al. Standards Track [Page 3]
-
-RFC 3266 Support for IPv6 in Session Description Protocol June 2002
-
-
- [3] Hinden, R., Carpenter, B. and L. Masinter, "Format for Literal
- IPv6 Addresses in URL's", RFC 2732, December 1999.
-
- [4] Crocker, D. and P. Overell, "Augmented BNF for Syntax
- Specifications: ABNF", RFC 2234, November 1997.
-
- [5] Bradner, S., "Key words for Use in RFCs to Indicate Requirement
- Levels", BCP 14, RFC 2119, March 1997.
-
-9. Authors' Addresses
-
- Sean Olson
- Microsoft
- One Microsoft Way
- Redmond, WA 98052
- USA
-
-
-
- Gonzalo Camarillo
- Ericsson
- Advanced Signalling Research Lab.
- FIN-02420 Jorvas
- Finland
-
- Phone: +358 9 299 3371
- Fax: +358 9 299 3118
-
-
- Adam Roach
- dynamicsoft
- 5100 Tennyson Parkway
- Suite 1200
- Plano, TX 75024
- USA
-
- Voice: <sip:[email protected]>
-
-
-
-
-
-
-
-
-
-
-
-Olson, et. al. Standards Track [Page 4]
-
-RFC 3266 Support for IPv6 in Session Description Protocol June 2002
-
-
-10. Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Olson, et. al. Standards Track [Page 5]
-
diff --git a/lib/megaco/examples/meas/meas.sh.skel b/lib/megaco/examples/meas/meas.sh.skel
index 4bbc6a5f7e..76745ed8f4 100644
--- a/lib/megaco/examples/meas/meas.sh.skel
+++ b/lib/megaco/examples/meas/meas.sh.skel
@@ -1,20 +1,20 @@
#!/bin/sh
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2007-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2007-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -27,7 +27,7 @@ MEAS_HOME=$MEGACO_HOME/examples/meas
PATH=$ERL_HOME/bin:$PATH
# MEAS_TIME_TEST="-s megaco_codec_meas start time_test"
-MEAS_DEFAULT="-s megaco_codec_meas t"
+MEAS_DEFAULT="-s megaco_codec_meas start"
STOP="-s init stop"
ERL="erl \
diff --git a/lib/megaco/include/megaco.hrl b/lib/megaco/include/megaco.hrl
index 4045fa9461..87e830323f 100644
--- a/lib/megaco/include/megaco.hrl
+++ b/lib/megaco/include/megaco.hrl
@@ -1,19 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
+%% retrieved online at http://www.erlang.org/.
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
-%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-%% AB. All Rights Reserved.''
-%%
-%% $Id$
+%%
+%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% Purpose: Define common data structures and error codes
diff --git a/lib/megaco/src/engine/megaco_config.erl b/lib/megaco/src/engine/megaco_config.erl
index 2058c53973..1c7a141be7 100644
--- a/lib/megaco/src/engine/megaco_config.erl
+++ b/lib/megaco/src/engine/megaco_config.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -1432,7 +1432,7 @@ verify_val(Item, Val) ->
segment_send_timer -> verify_timer(Val);
max_pdu_size -> verify_int(Val) andalso (Val > 0);
request_keep_alive_timeout ->
- (verify_int(Val) andalso (Val >= 0)) orelse (Val =:= plain);
+ (verify_uint(Val) orelse (Val =:= plain));
_ -> false
end.
diff --git a/lib/megaco/test/Makefile b/lib/megaco/test/Makefile
index a6f50f87c4..e521194419 100644
--- a/lib/megaco/test/Makefile
+++ b/lib/megaco/test/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
include $(ERL_TOP)/make/target.mk
@@ -141,6 +141,125 @@ info:
@echo "ERL = $(ERL)"
@echo "MERL = $(MERL)"
@echo ""
+ @echo "ARGS = $(ARGS)"
+ @echo ""
+ @echo "HRL_FILES = $(HRL_FILES)"
+ @echo "ERL_FILES = $(ERL_FILES)"
+ @echo "TARGET_FILES = $(TARGET_FILES)"
+ @echo ""
+
+help:
+ @echo ""
+ @echo "This Makefile controls the test of the $(APPLICATION) application. "
+ @echo ""
+ @echo "There are two separate ways to perform the test of $(APPLICATION)."
+ @echo ""
+ @echo " a) Run the official OTP test-server (which we do not describe here)"
+ @echo ""
+ @echo " b) Run the test-server provided with this application. "
+ @echo " There are a number of targets to run the entire or parts"
+ @echo " of this applications ($(APPLICATION)) test-suite"
+ @echo ""
+ @echo "Targets:"
+ @echo ""
+ @echo " help"
+ @echo " Print this info"
+ @echo ""
+ @echo " info"
+ @echo " Prints various environment variables. "
+ @echo " May be useful when debugging the Makefile. "
+ @echo ""
+ @echo " tests | debug | opt "
+ @echo " Compile all test-code. "
+ @echo ""
+ @echo " clean "
+ @echo " Remove all targets. "
+ @echo ""
+ @echo " test"
+ @echo " Run the entire $(APPLICATION) test-suite. "
+ @echo ""
+ @echo " app"
+ @echo " Run the $(APPLICATION) application sub-test-suite. "
+ @echo ""
+ @echo " appup"
+ @echo " Run the $(APPLICATION) application upgrade (appup) sub-test-suite. "
+ @echo ""
+ @echo " conf"
+ @echo " Run the $(APPLICATION) config sub-test-suite. "
+ @echo " Checks various aspects of the megaco configuration. "
+ @echo ""
+ @echo " codec"
+ @echo " Run the $(APPLICATION) codec sub-test-suite(s). "
+ @echo ""
+ @echo " flex"
+ @echo " Run the $(APPLICATION) flex-scanner sub-test-suite. "
+ @echo " This sub-test-suite does not test the function of the scanner itself"
+ @echo " (that is done by the codec sub-test-suite(s)), instead, this"
+ @echo " sub-test-suite tests the *handling* of the flex-scanner linked-in driver."
+ @echo ""
+ @echo " dm"
+ @echo " Run the $(APPLICATION) digit-map sub-test-suite. "
+ @echo ""
+ @echo " tid"
+ @echo " Run the $(APPLICATION) binary term-id sub-test-suite. "
+ @echo ""
+ @echo " sdp"
+ @echo " Run the $(APPLICATION) SDP sub-test-suite. "
+ @echo ""
+ @echo " action"
+ @echo " Run the $(APPLICATION) actions sub-test-suite. "
+ @echo " Actions are building blocks of a $(APPLICATION) message. "
+ @echo " This sub-test-suite attempts to perform tests related to this, "
+ @echo " using all the supported codecs. "
+ @echo ""
+ @echo " mess"
+ @echo " Run the $(APPLICATION) message sub-test-suite"
+ @echo " This is basic message processing test-cases"
+ @echo ""
+ @echo " trans"
+ @echo " Run the $(APPLICATION) transaction sender sub-test-suite"
+ @echo " This is basic message processing for a megaco application "
+ @echo " configured to be using the transaction sender. "
+ @echo ""
+ @echo " mib"
+ @echo " Run the $(APPLICATION) $(APPLICATION)-mib sub-test-suite"
+ @echo " Tests related to the basic support for the $(APPLICATION) mib"
+ @echo " primarily counters"
+ @echo ""
+ @echo " mreq"
+ @echo " Run the $(APPLICATION) mreq sub-test-suite"
+ @echo " This is yet another sub-test-suite with message processing "
+ @echo " test-cases. "
+ @echo ""
+ @echo " pending"
+ @echo " Run the $(APPLICATION) pending-limit sub-test-suite"
+ @echo ""
+ @echo " udp"
+ @echo " Run the $(APPLICATION) UDP transport component sub-test-suite"
+ @echo ""
+ @echo " tcp"
+ @echo " Run the $(APPLICATION) TCP transport component sub-test-suite"
+ @echo ""
+ @echo " load"
+ @echo " Run the $(APPLICATION) load sub-test-suite"
+ @echo " This sub-test-suite performs load test test-cases using "
+ @echo " \"high\" message traffic. "
+ @echo ""
+ @echo " segment"
+ @echo " Run the $(APPLICATION) message segmentation sub-test-suite"
+ @echo " If using the UDP transport protocol, it is possible to send "
+ @echo " and receive segmented megaco replies (in version 3 of the protocol) "
+ @echo " This sub-test-suite tests this feature. "
+ @echo ""
+ @echo " timer"
+ @echo " Run the $(APPLICATION) timer sub-test-suite"
+ @echo " Basic test-suite for the megaco-timers"
+ @echo ""
+ @echo " ex"
+ @echo " Run the $(APPLICATION) example sub-test-suite"
+ @echo " The $(APPLICATION) application contains one example,"
+ @echo " this is a sub-test-suite based on the code,"
+ @echo ""
# ----------------------------------------------------
diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk
index 1c637fe8aa..9e4ae4d242 100644
--- a/lib/megaco/vsn.mk
+++ b/lib/megaco/vsn.mk
@@ -1,27 +1,30 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
-MEGACO_VSN = 3.13.0.1
-PRE_VSN =
-APP_VSN = "megaco-$(MEGACO_VSN)$(PRE_VSN)"
+APPLICATION = megaco
+MEGACO_VSN = 3.13.1
+PRE_VSN =-p01
+APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)"
-TICKETS = OTP-8205 OTP-8239 OTP-8249
+TICKETS = OTP-8317 OTP-8362
+
+TICKETS_3_13 = OTP-8205 OTP-8239 OTP-8249
TICKETS_3_12 = OTP-8183 OTP-8212
diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml
index 33387a88f4..07f9fce8c7 100644
--- a/lib/mnesia/doc/src/mnesia.xml
+++ b/lib/mnesia/doc/src/mnesia.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>mnesia</title>
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index c9599a1911..fb29007780 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl
index 5657f6e299..3de329503e 100644
--- a/lib/mnesia/src/mnesia_loader.erl
+++ b/lib/mnesia/src/mnesia_loader.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl
index b39ee92fa8..ab1500d439 100644
--- a/lib/mnesia/src/mnesia_monitor.erl
+++ b/lib/mnesia/src/mnesia_monitor.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
diff --git a/lib/odbc/doc/src/Makefile b/lib/odbc/doc/src/Makefile
index 136ddfb980..e2f09733d0 100644
--- a/lib/odbc/doc/src/Makefile
+++ b/lib/odbc/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -63,6 +63,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES = \
book.gif \
odbc.gif \
diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml
index 1185b7658f..816ec77d61 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Orber Release Notes</title>
@@ -36,6 +36,18 @@
<title>Orber 3.6.15</title>
<section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Removed obsolete SSL dependency.</p>
+ <p>
+ Own Id: OTP-8374 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
<title>Fixed Bugs and Malfunctions</title>
<list type="bulleted">
<item>
diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk
index ccba631fb5..8bfa13eb03 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -2,7 +2,8 @@
ORBER_VSN = 3.6.15
TICKETS = OTP-8353 \
- OTP-8354
+ OTP-8354 \
+ OTP-8374
TICKETS_3.6.14 = OTP-8201
diff --git a/lib/parsetools/test/Makefile b/lib/parsetools/test/Makefile
new file mode 100644
index 0000000000..19354b87b2
--- /dev/null
+++ b/lib/parsetools/test/Makefile
@@ -0,0 +1,78 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2005-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+MODULES = \
+ leex_SUITE \
+ yecc_SUITE
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+INSTALL_PROGS= $(TARGET_FILES)
+
+EMAKEFILE=Emakefile
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/parsetools_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+.PHONY: make_emakefile
+
+make_emakefile:
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\
+ > $(EMAKEFILE)
+
+tests debug opt: make_emakefile
+ erl $(ERL_MAKE_FLAGS) -make
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: make_emakefile
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) parsetools.spec $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ # @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl
new file mode 100644
index 0000000000..069f780b5e
--- /dev/null
+++ b/lib/parsetools/test/leex_SUITE.erl
@@ -0,0 +1,909 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(leex_SUITE).
+
+%-define(debug, true).
+
+-include_lib("stdlib/include/erl_compile.hrl").
+-include_lib("kernel/include/file.hrl").
+
+-ifdef(debug).
+-define(line, put(line, ?LINE), ).
+-define(config(X,Y), foo).
+-define(datadir, "leex_SUITE_data").
+-define(privdir, "leex_SUITE_priv").
+-define(t, test_server).
+-else.
+-include("test_server.hrl").
+-define(datadir, ?config(data_dir, Config)).
+-define(privdir, ?config(priv_dir, Config)).
+-endif.
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+
+-export([checks/1,
+ file/1, compile/1, syntax/1,
+ examples/1,
+ pt/1, man/1, ex/1, ex2/1, not_yet/1]).
+
+% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(suite) -> [checks, examples].
+
+checks(suite) ->
+ [file, compile, syntax].
+
+file(doc) ->
+ "Bad files and options.";
+file(suite) -> [];
+file(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, false}],
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file("not_a_file", Ret),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file("not_a_file", [{return,true}]),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file("not_a_file", [{report,false},return_errors]),
+ ?line error = leex:file("not_a_file"),
+ ?line error = leex:file("not_a_file", [{return,false},report]),
+ ?line error = leex:file("not_a_file", [return_warnings,{report,false}]),
+
+ Filename = filename:join(Dir, "file.xrl"),
+ file:delete(Filename),
+
+ ?line {'EXIT', {badarg, _}} = (catch leex:file({foo})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch leex:file(Filename, {parserfile,{foo}})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch leex:file(Filename, {includefile,{foo}})),
+
+ ?line {'EXIT', {badarg, _}} = (catch leex:file(Filename, no_option)),
+ ?line {'EXIT', {badarg, _}} =
+ (catch leex:file(Filename, [return | report])),
+ ?line {'EXIT', {badarg, _}} =
+ (catch leex:file(Filename, {return,foo})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch leex:file(Filename, includefile)),
+
+ Mini = <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : {token,{word,TokenLine,TokenChars}}.\n"
+ "Erlang code.\n">>,
+ ?line ok = file:write_file(Filename, Mini),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file(Filename, [{scannerfile,"//"} | Ret]),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file(Filename, [{includefile,"//"} | Ret]),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file(Filename, [{includefile,"/ /"} | Ret]),
+
+ LeexPre = filename:join(Dir, "leexinc.hrl"),
+ ?line ok = file:write_file(LeexPre, <<"syntax error.\n">>),
+ PreErrors = run_test(Config, Mini, LeexPre),
+ ?line {errors,
+ [{1,_,["syntax error before: ","error"]},
+ {3,_,undefined_module}],
+ []} =
+ extract(LeexPre, PreErrors),
+ file:delete(LeexPre),
+
+ Ret2 = [return, report_errors, report_warnings, verbose],
+ Scannerfile = filename:join(Dir, "file.erl"),
+ ?line ok = file:write_file(Scannerfile, <<"nothing">>),
+ ?line unwritable(Scannerfile),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file(Filename, Ret2),
+ ?line writable(Scannerfile),
+ file:delete(Scannerfile),
+
+ Dotfile = filename:join(Dir, "file.dot"),
+ ?line ok = file:write_file(Dotfile, <<"nothing">>),
+ ?line unwritable(Dotfile),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file(Filename, [dfa_graph | Ret2]),
+ ?line writable(Dotfile),
+ file:delete(Dotfile),
+
+ file:delete(Filename),
+ ok.
+
+compile(doc) ->
+ "Check of compile/3.";
+compile(suite) -> [];
+compile(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.xrl"),
+ Scannerfile = filename:join(Dir, "file.erl"),
+ Mini = <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : {token,{word,TokenLine,TokenChars}}.\n"
+ "Erlang code.\n">>,
+ ?line ok = file:write_file(Filename, Mini),
+ ?line error = leex:compile(Filename, "//", #options{}),
+ ?line ok = leex:compile(Filename, Scannerfile, #options{}),
+ file:delete(Scannerfile),
+ file:delete(Filename),
+ ok.
+
+syntax(doc) ->
+ "Syntax checks.";
+syntax(suite) -> [];
+syntax(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.xrl"),
+ Ret = [return, {report, true}],
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "%% comment\n"
+ "Rules.\n"
+ "{L}+ : {token,{word,TokenLine,TokenChars}}.\n
+ ">>),
+ ?line {error,[{_,[{7,leex,missing_code}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : \n">>),
+ ?line {error,[{_,[{5,leex,missing_code}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "[] :">>),
+ ?line {error,[{_,[{4,leex,{regexp,_}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : .\n"
+ "[] : ">>),
+ ?line {error,[{_,[{5,leex,{regexp,_}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "[] : .\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,_}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ ">>),
+ ?line {error,[{_,[{5,leex,bad_rule}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ ; ">>),
+ ?line {error,[{_,[{4,leex,bad_rule}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "[] : '99\n">>),
+ ?line {error,[{_,[{4,erl_scan,_}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n">>),
+ ?line {error,[{_,[{3,leex,empty_rules}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "Erlang code.\n">>),
+ ?line {error,[{_,[{4,leex,empty_rules}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n">>),
+ ?line {error,[{_,[{2,leex,missing_rules}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Erlang code.\n">>),
+ ?line {error,[{_,[{3,leex,missing_rules}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"">>),
+ %% This is a weird line:
+ ?line {error,[{_,[{0,leex,missing_defs}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Rules.\n">>),
+ ?line {error,[{_,[{1,leex,missing_defs}]}],[]} = leex:file(Filename, Ret),
+
+ %% Check that correct line number is used in messages.
+ ErlFile = filename:join(Dir, "file.erl"),
+ Ret1 = [{scannerfile,ErlFile}|Ret],
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : {token,\n"
+ " {word,TokenLine,TokenChars,\n"
+ " DDDD}}.\n" % unbound
+ "Erlang code.\n"
+ "an error.\n">>), % syntax error
+ ?line {ok, _, []} = leex:file(Filename, Ret1),
+ ?line {error,
+ [{_,[{8,_,["syntax error before: ","error"]}]},
+ {_,[{6,_,{unbound_var,'DDDD'}}]}],
+ []} =
+ compile:file(ErlFile, [basic_validation, return]),
+
+ %% Ignored characters
+ ?line ok = file:write_file(Filename,
+ <<"Definitions. D = [0-9]\n"
+ "Rules. [a-z] : .\n"
+ "1 : skip_token.\n"
+ "Erlang code. f() -> a.\n">>),
+ ?line {ok,_,[{_,
+ [{1,leex,ignored_characters},
+ {2,leex,ignored_characters},
+ {4,leex,ignored_characters}]}]} =
+ leex:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+\\ : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{unterminated,"\\"}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+\\x : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{illegal_char,"\\x"}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+\\x{ : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{unterminated,"\\x{"}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "[^ab : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{unterminated,"["}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "(a : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{unterminated,"("}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "[b-a] : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{char_class,"b-a"}}}]}],[]} =
+ leex:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "\\x{333333333333333333333333} : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,
+ {illegal_char,
+ "\\x{333333333333333333333333}"}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ok.
+
+examples(suite) ->
+ [pt,man,ex,ex2,not_yet].
+
+pt(doc) ->
+ "Pushing back characters.";
+pt(suite) -> [];
+pt(Config) when is_list(Config) ->
+ %% Needs more testing...
+ Ts = [{pt_1,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "L = [a-z]\n"
+
+ "Rules.\n"
+ "{L}+ : {token,{word,TokenLine,TokenChars}}.\n"
+ "abc{D}+ : {skip_token,\"sture\" ++ string:substr(TokenChars, 4)}.\n"
+ "{D}+ : {token,{integer,TokenLine,list_to_integer(TokenChars)}}.\n"
+ "\\s : .\n"
+ "\\r\\n : {end_token,{crlf,TokenLine}}.\n"
+
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->
+ {ok,[{word,1,\"sture\"},{integer,1,123}],1} =
+ string(\"abc123\"), ok. ">>,
+ default,
+ ok}],
+
+ ?line run(Config, Ts),
+ ok.
+
+man(doc) ->
+ "Examples from the manpage.";
+man(suite) -> [];
+man(Config) when is_list(Config) ->
+ Ts = [{man_1,
+ <<"Definitions.\n"
+ "Rules.\n"
+ "[a-z][0-9a-zA-Z_]* :\n"
+ " {token,{atom,TokenLine,list_to_atom(TokenChars)}}.\n"
+ "[A-Z_][0-9a-zA-Z_]* :\n"
+ " {token,{var,TokenLine,list_to_atom(TokenChars)}}.\n"
+ "(\\+|-)?[0-9]+\\.[0-9]+((E|e)(\\+|-)?[0-9]+)? : \n"
+ " {token,{float,TokenLine,list_to_float(TokenChars)}}.\n"
+ "\\s : skip_token.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{float,1,3.14},{atom,1,atom},{var,1,'V314'}],1} =\n"
+ " string(\"3.14atom V314\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {man_2,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{D}+ :\n"
+ " {token,{integer,TokenLine,list_to_integer(TokenChars)}}.\n"
+ "{D}+\\.{D}+((E|e)(\\+|\\-)?{D}+)? :\n"
+ " {token,{float,TokenLine,list_to_float(TokenChars)}}.\n"
+ "\\s : skip_token.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{float,1,3.14},{integer,1,314}],1} = \n"
+ " string(\"3.14 314\"),\n"
+ " ok.\n">>,
+ default,
+ ok}],
+
+ ?line run(Config, Ts),
+ ok.
+
+ex(doc) ->
+ "Examples.";
+ex(suite) -> [];
+ex(Config) when is_list(Config) ->
+ Ts = [{ex_1,
+ <<"Definitions.\n"
+ "D = [0-543-705-982]\n"
+ "Rules.\n"
+ "{D}+ :\n"
+ " {token,{integer,TokenLine,list_to_integer(TokenChars)}}.\n"
+ "[^235]+ :\n"
+ " {token,{list_to_atom(TokenChars),TokenLine}}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{integer,1,12},{' c\\na',1},{integer,2,34},{b789a,2}],2} =\n"
+ " string(\"12 c\\na34b789a\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {ex_2,
+ <<"Definitions.\n"
+ "L = [a-z]\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : {token,chars}.\n"
+ "zyx{D}+ : {token,zyx}.\n"
+ "\\s : skip_token.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[chars,zyx],1} = string(\"abcdef zyx123\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {ex_3,
+ <<"Definitions.\n"
+ "NL = [\\n]\n"
+ "Rules.\n"
+ "{NL}* : {token,newlines}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[],1} = string(\"\"), ok.\n">>, % string("a") would loop...
+ default,
+ ok},
+
+ {ex_4,
+ <<"Definitions.\n"
+ "SP1 = [\\n-\\s]\n"
+ "SP0 = [\\000-\\n]\n"
+ "Rules.\n"
+ "{SP0}+ : {token,{small,TokenChars}}.\n"
+ "{SP1}+ : {token,{big,TokenChars}}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " string(\"\\x00\\n\\s\\n\\n\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {ex_5,
+ <<"Definitions.\n"
+ "L = [a-z]\n"
+ "W = [\\s\\b\\n\\r\\t\\e\\v\\d\\f]\n"
+ "Rules.\n"
+ "\\[{L}+(,{L}+)*\\] : {token,{list,TokenChars}}.\n"
+ "\"{L}+\" : {token,{string,TokenChars}}.\n"
+ "\\$. : {token,{char,TokenChars}}.\n"
+ "{W}+ : {token,{white,TokenChars}}.\n"
+ "ff\\f+ : {token,{form,TokenChars}}.\n"
+ "\\$\\^+\\\\+ : {token,{other,TokenChars}}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{white,\"\\b\\f\"}],1} = string(\"\\b\\f\"),\n"
+ " {ok,[{form,\"ff\\f\"}],1} = string(\"ff\\f\"),\n"
+ " {ok,[{string,\"\\\"foo\\\"\"}],1} = string(\"\\\"foo\\\"\"),\n"
+ " {ok,[{char,\"$.\"}],1} = string(\"$\\.\"),\n"
+ " {ok,[{list,\"[a,b,c]\"}],1} = string(\"[a,b,c]\"),\n"
+ " {ok,[{other,\"$^\\\\\"}],1} = string(\"$^\\\\\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {ex_6,
+ <<"Definitions.\n"
+ "L = [a-z]\n"
+ "Rules.\n"
+ "L}+ : {token,{TokenChars,#r.f}}.\n"
+ "Erlang code.\n"
+ "-record(r, {f}).\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " string(\"abc\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {ex_7, %% Assumes regexp can handle \x
+ <<"Definitions.\n"
+ "H1 = \\x11\\x{ab}\n"
+ "H2 = [\\x{30}\\x{ac}]\n"
+ "Rules.\n"
+ "{H1}{H2}+ : {token,{hex,TokenChars}}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{hex,[17,171,48,172]}],1} =\n"
+ " string(\"\\x{11}\\xab0\\xac\"),\n"
+ " ok.\n">>,
+ default,
+ ok}],
+
+ ?line run(Config, Ts),
+ ok.
+
+ex2(doc) ->
+ "More examples.";
+ex2(suite) -> [];
+ex2(Config) when is_list(Config) ->
+ Xrl =
+ <<"
+%%% File : erlang_scan.xrl
+%%% Author : Robert Virding
+%%% Purpose : Tkoen definitions for Erlang.
+
+Definitions.
+O = [0-7]
+D = [0-9]
+H = [0-9a-fA-F]
+U = [A-Z]
+L = [a-z]
+A = ({U}|{L}|{D}|_|@)
+WS = ([\\000-\\s]|%.*)
+
+Rules.
+{D}+\\.{D}+((E|e)(\\+|\\-)?{D}+)? :
+ {token,{float,TokenLine,list_to_float(TokenChars)}}.
+{D}+#{H}+ : base(TokenLine, TokenChars).
+{D}+ : {token,{integer,TokenLine,list_to_integer(TokenChars)}}.
+{L}{A}* : Atom = list_to_atom(TokenChars),
+ {token,case reserved_word(Atom) of
+ true -> {Atom,TokenLine};
+ false -> {atom,TokenLine,Atom}
+ end}.
+'(\\\\\\^.|\\\\.|[^'])*' :
+ %% Strip quotes.
+ S = lists:sublist(TokenChars, 2, TokenLen - 2),
+ case catch list_to_atom(string_gen(S)) of
+ {'EXIT',_} -> {error,\"illegal atom \" ++ TokenChars};
+ Atom -> {token,{atom,TokenLine,Atom}}
+ end.
+({U}|_){A}* : {token,{var,TokenLine,list_to_atom(TokenChars)}}.
+\"(\\\\\\^.|\\\\.|[^\"])*\" :
+ %% Strip quotes.
+ S = lists:sublist(TokenChars, 2, TokenLen - 2),
+ {token,{string,TokenLine,string_gen(S)}}.
+\\$(\\\\{O}{O}{O}|\\\\\\^.|\\\\.|.) :
+ {token,{char,TokenLine,cc_convert(TokenChars)}}.
+-> : {token,{'->',TokenLine}}.
+:- : {token,{':-',TokenLine}}.
+\\|\\| : {token,{'||',TokenLine}}.
+<- : {token,{'<-',TokenLine}}.
+\\+\\+ : {token,{'++',TokenLine}}.
+-- : {token,{'--',TokenLine}}.
+=/= : {token,{'=/=',TokenLine}}.
+== : {token,{'==',TokenLine}}.
+=:= : {token,{'=:=',TokenLine}}.
+/= : {token,{'/=',TokenLine}}.
+>= : {token,{'>=',TokenLine}}.
+=< : {token,{'=<',TokenLine}}.
+<= : {token,{'<=',TokenLine}}.
+<< : {token,{'<<',TokenLine}}.
+>> : {token,{'>>',TokenLine}}.
+:: : {token,{'::',TokenLine}}.
+[]()[}{|!?/;:,.*+#<>=-] :
+ {token,{list_to_atom(TokenChars),TokenLine}}.
+\\.{WS} : {end_token,{dot,TokenLine}}.
+{WS}+ : skip_token.
+
+Erlang code.
+
+-export([reserved_word/1]).
+
+%% reserved_word(Atom) -> Bool
+%% return 'true' if Atom is an Erlang reserved word, else 'false'.
+
+reserved_word('after') -> true;
+reserved_word('begin') -> true;
+reserved_word('case') -> true;
+reserved_word('try') -> true;
+reserved_word('cond') -> true;
+reserved_word('catch') -> true;
+reserved_word('andalso') -> true;
+reserved_word('orelse') -> true;
+reserved_word('end') -> true;
+reserved_word('fun') -> true;
+reserved_word('if') -> true;
+reserved_word('let') -> true;
+reserved_word('of') -> true;
+reserved_word('query') -> true;
+reserved_word('receive') -> true;
+reserved_word('when') -> true;
+reserved_word('bnot') -> true;
+reserved_word('not') -> true;
+reserved_word('div') -> true;
+reserved_word('rem') -> true;
+reserved_word('band') -> true;
+reserved_word('and') -> true;
+reserved_word('bor') -> true;
+reserved_word('bxor') -> true;
+reserved_word('bsl') -> true;
+reserved_word('bsr') -> true;
+reserved_word('or') -> true;
+reserved_word('xor') -> true;
+reserved_word('spec') -> true;
+reserved_word(_) -> false.
+
+base(L, Cs) ->
+ H = string:chr(Cs, $#),
+ case list_to_integer(string:substr(Cs, 1, H-1)) of
+ B when B > 16 -> {error,\"illegal base\"};
+ B ->
+ case base(string:substr(Cs, H+1), B, 0) of
+ error -> {error,\"illegal based number\"};
+ N -> {token,{integer,L,N}}
+ end
+ end.
+
+base([C|Cs], Base, SoFar) when C >= $0, C =< $9, C < Base + $0 ->
+ Next = SoFar * Base + (C - $0),
+ base(Cs, Base, Next);
+base([C|Cs], Base, SoFar) when C >= $a, C =< $f, C < Base + $a - 10 ->
+ Next = SoFar * Base + (C - $a + 10),
+ base(Cs, Base, Next);
+base([C|Cs], Base, SoFar) when C >= $A, C =< $F, C < Base + $A - 10 ->
+ Next = SoFar * Base + (C - $A + 10),
+ base(Cs, Base, Next);
+base([_|_], _, _) -> error; %Unknown character
+base([], _, N) -> N.
+
+cc_convert([$$,$\\\\|Cs]) ->
+ hd(string_escape(Cs));
+cc_convert([$$,C]) -> C.
+
+string_gen([$\\\\|Cs]) ->
+ string_escape(Cs);
+string_gen([C|Cs]) ->
+ [C|string_gen(Cs)];
+string_gen([]) -> [].
+
+string_escape([O1,O2,O3|S]) when
+ O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 ->
+ [(O1*8 + O2)*8 + O3 - 73*$0|string_gen(S)];
+string_escape([$^,C|Cs]) ->
+ [C band 31|string_gen(Cs)];
+string_escape([C|Cs]) when C >= $\\000, C =< $\\s ->
+ string_gen(Cs);
+string_escape([C|Cs]) ->
+ [escape_char(C)|string_gen(Cs)].
+
+escape_char($n) -> $\\n; %\\n = LF
+escape_char($r) -> $\\r; %\\r = CR
+escape_char($t) -> $\\t; %\\t = TAB
+escape_char($v) -> $\\v; %\\v = VT
+escape_char($b) -> $\\b; %\\b = BS
+escape_char($f) -> $\\f; %\\f = FF
+escape_char($e) -> $\\e; %\\e = ESC
+escape_char($s) -> $\\s; %\\s = SPC
+escape_char($d) -> $\\d; %\\d = DEL
+escape_char(C) -> C.
+ ">>,
+ Dir = ?privdir,
+ XrlFile = filename:join(Dir, "erlang_scan.xrl"),
+ ?line ok = file:write_file(XrlFile, Xrl),
+ ErlFile = filename:join(Dir, "erlang_scan.erl"),
+ ?line {ok, _} = leex:file(XrlFile, []),
+ ?line {ok, _} = compile:file(ErlFile, [{outdir,Dir}]),
+ code:purge(erlang_scan),
+ AbsFile = filename:rootname(ErlFile, ".erl"),
+ code:load_abs(AbsFile, erlang_scan),
+
+ F = fun(Cont, Chars, Location) ->
+ erlang_scan:tokens(Cont, Chars, Location)
+ end,
+ F1 = fun(Cont, Chars, Location) ->
+ erlang_scan:token(Cont, Chars, Location)
+ end,
+ fun() ->
+ S = "ab cd. ",
+ {ok, Ts, 1} = scan_tokens_1(S, F, 1),
+ {ok, Ts, 1} = scan_token_1(S, F1, 1),
+ {ok, Ts, 1} = scan_tokens(S, F, 1),
+ {ok, Ts, 1} = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "'ab\n cd'. ",
+ {ok, Ts, 2} = scan_tokens_1(S, F, 1),
+ {ok, Ts, 2} = scan_token_1(S, F1, 1),
+ {ok, Ts, 2} = scan_tokens(S, F, 1),
+ {ok, Ts, 2} = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "99. ",
+ {ok, Ts, 1} = scan_tokens_1(S, F, 1),
+ {ok, Ts, 1} = scan_token_1(S, F1, 1),
+ {ok, Ts, 1} = scan_tokens(S, F, 1),
+ {ok, Ts, 1} = erlang_scan:string(S, 1)
+ end(),
+ {ok,[{integer,1,99},{dot,1}],1} = erlang_scan:string("99. "),
+ fun() ->
+ Atom = "'" ++ lists:duplicate(1000,$a) ++ "'",
+ S = Atom ++ ". ",
+ Reason = "illegal atom " ++ Atom,
+ Err = {error,{1,erlang_scan,{user,Reason}},1},
+ {done,Err,[]} = scan_tokens_1(S, F, 1),
+ {done,Err,[]} = scan_token_1(S, F1, 1),
+ {done,Err,[]} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "\x{aaa}. ",
+ Err = {error,{1,erlang_scan,{illegal,[2730]}},1},
+ {done,Err,[]} = scan_tokens_1(S, F, 1),
+ {done,Err,[_]} = scan_token_1(S, F1, 1), % Note: Rest non-empty
+ {done,Err,[]} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "\x{aaa} + 1. 34",
+ Err = {error,{1,erlang_scan,{illegal,[2730]}},1},
+ {done,Err,[]} = scan_tokens_1(S, F, 1),
+ {done,Err,[_]} = scan_token_1(S, F1, 1), % Note: Rest non-empty
+ {done,Err,"34"} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "\x{aaa} \x{bbb}. 34",
+ Err = {error,{1,erlang_scan,{illegal,[2730]}},1},
+ {done,Err,[]} = scan_tokens_1(S, F, 1),
+ {done,Err,[_]} = scan_token_1(S, F1, 1), % Note: Rest non-empty
+ {done,Err,"34"} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "\x{aaa} 18#34. 34",
+ Err = {error,{1,erlang_scan,{illegal,[2730]}},1},
+ {done,Err,[]} = scan_tokens_1(S, F, 1),
+ {done,Err,[_]} = scan_token_1(S, F1, 1), % Note: Rest non-empty
+ {done,Err,"34"} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "\x{aaa}"++eof,
+ Err = {error,{1,erlang_scan,{illegal,[2730]}},1},
+ {done,Err,eof} = scan_tokens_1(S, F, 1),
+ {done,Err,[_]} = scan_token_1(S, F1, 1), % Note: Rest non-empty
+ {done,Err,eof} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ ok.
+
+scan_tokens(String, Fun, Location) ->
+ scan_tokens(String, Fun, Location, []).
+
+scan_tokens(String, Fun, Location, Rs) ->
+ case Fun([], String, Location) of
+ {done, {error,_,_}, _} = Error ->
+ Error;
+ {done, {ok,Ts,End}, ""} ->
+ {ok, lists:append(lists:reverse([Ts|Rs])), End};
+ {done, {ok,Ts,End}, Rest} ->
+ scan_tokens(Rest, Fun, End, [Ts|Rs])
+ end.
+
+scan_tokens_1(String, Fun, Location) ->
+ scan_tokens_1({more, []}, String, Fun, Location, []).
+
+scan_tokens_1({done, {error, _, _}, _}=Error, _Cs, _Fun, _Location, _Rs) ->
+ Error;
+scan_tokens_1({done, {ok,Ts,End}, ""}, "", _Fun, _Location, Rs) ->
+ {ok,lists:append(lists:reverse([Ts|Rs])),End};
+scan_tokens_1({done, {ok,Ts,End}, Rest}, Cs, Fun, _Location, Rs) ->
+ scan_tokens_1({more,[]}, Rest++Cs, Fun, End, [Ts|Rs]);
+scan_tokens_1({more, Cont}, [C | Cs], Fun, Loc, Rs) ->
+ R = Fun(Cont, [C], Loc),
+ scan_tokens_1(R, Cs, Fun, Loc, Rs);
+scan_tokens_1({more, Cont}, eof, Fun, Loc, Rs) ->
+ R = Fun(Cont, eof, Loc),
+ scan_tokens_1(R, eof, Fun, Loc, Rs).
+
+scan_token_1(String, Fun, Location) ->
+ scan_token_1({more, []}, String, Fun, Location, []).
+
+scan_token_1({done, {error, _, _}, _}=Error, _Cs, _Fun, _Location, _Rs) ->
+ Error;
+scan_token_1({done, {ok,Ts,End}, ""}, "", _Fun, _Location, Rs) ->
+ {ok,lists:reverse([Ts|Rs]),End};
+scan_token_1({done, {ok,Ts,End}, Rest}, Cs, Fun, _Location, Rs) ->
+ scan_token_1({more,[]}, Rest++Cs, Fun, End, [Ts|Rs]);
+scan_token_1({more, Cont}, [C | Cs], Fun, Loc, Rs) ->
+ R = Fun(Cont, [C], Loc),
+ scan_token_1(R, Cs, Fun, Loc, Rs).
+
+%% End of ex2
+
+not_yet(doc) ->
+ "Not yet implemented.";
+not_yet(suite) -> [];
+not_yet(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.xrl"),
+ Ret = [return, {report, true}],
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "Rules.\n"
+ "$ : .\n"
+ "Erlang code.\n">>),
+ ?line {error,[{_,[{3,leex,{regexp,_}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "Rules.\n"
+ "^ : .\n"
+ "Erlang code.\n">>),
+ ?line {error,[{_,[{3,leex,{regexp,_}}]}],[]} =
+ leex:file(Filename, Ret),
+
+ ok.
+
+unwritable(Fname) ->
+ {ok, Info} = file:read_file_info(Fname),
+ Mode = Info#file_info.mode - 8#00200,
+ ok = file:write_file_info(Fname, Info#file_info{mode = Mode}).
+
+writable(Fname) ->
+ {ok, Info} = file:read_file_info(Fname),
+ Mode = Info#file_info.mode bor 8#00200,
+ ok = file:write_file_info(Fname, Info#file_info{mode = Mode}).
+
+run(Config, Tests) ->
+ F = fun({N,P,Pre,E}) ->
+ case catch run_test(Config, P, Pre) of
+ E ->
+ ok;
+ Bad ->
+ ?t:format("~nTest ~p failed. Expected~n ~p~n"
+ "but got~n ~p~n", [N, E, Bad]),
+ fail()
+ end
+ end,
+ lists:foreach(F, Tests).
+
+run_test(Config, Def, Pre) ->
+ %% io:format("testing ~s~n", [binary_to_list(Def)]),
+ DefFile = 'leex_test.xrl',
+ Filename = 'leex_test.erl',
+ DataDir = ?privdir,
+ XrlFile = filename:join(DataDir, DefFile),
+ ErlFile = filename:join(DataDir, Filename),
+ Opts = [return, warn_unused_vars,{outdir,DataDir}],
+ ok = file:write_file(XrlFile, Def),
+ LOpts = [return, {report, false} |
+ case Pre of
+ default ->
+ [];
+ _ ->
+ [{includefile,Pre}]
+ end],
+ XOpts = [verbose, dfa_graph], % just to get some code coverage...
+ LRet = leex:file(XrlFile, XOpts ++ LOpts),
+ case LRet of
+ {ok, _Outfile, _LWs} ->
+ CRet = compile:file(ErlFile, Opts),
+ case CRet of
+ {ok, _M, _Ws} ->
+ AbsFile = filename:rootname(ErlFile, ".erl"),
+ Mod = leex_test,
+ code:purge(Mod),
+ code:load_abs(AbsFile, Mod),
+ Mod:t();
+ %% warnings(ErlFile, Ws);
+ {error, [{ErlFile,Es}], []} -> {error, Es, []};
+ {error, [{ErlFile,Es}], [{ErlFile,Ws}]} -> {error, Es, Ws};
+ Error -> Error
+ end;
+ {error, [{XrlFile,LEs}], []} -> {error, LEs, []};
+ {error, [{XrlFile,LEs}], [{XrlFile,LWs}]} -> {error, LEs, LWs};
+ LError -> LError
+ end.
+
+extract(File, {error, Es, Ws}) ->
+ {errors, extract(File, Es), extract(File, Ws)};
+extract(File, Ts) ->
+ lists:append([T || {F, T} <- Ts, F =:= File]).
+
+fail() ->
+ ?t:fail().
diff --git a/lib/parsetools/test/parsetools.spec b/lib/parsetools/test/parsetools.spec
new file mode 100644
index 0000000000..5b34633378
--- /dev/null
+++ b/lib/parsetools/test/parsetools.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../parsetools_test"}}.
diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl
new file mode 100644
index 0000000000..b5da414f7b
--- /dev/null
+++ b/lib/parsetools/test/yecc_SUITE.erl
@@ -0,0 +1,1795 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(yecc_SUITE).
+
+%-define(debug, true).
+
+-include_lib("stdlib/include/erl_compile.hrl").
+
+-ifdef(debug).
+-define(line, put(line, ?LINE), ).
+-define(config(X,Y), foo).
+-define(datadir, "yecc_SUITE_data").
+-define(privdir, "yecc_SUITE_priv").
+-define(t, test_server).
+-else.
+-include("test_server.hrl").
+-define(datadir, ?config(data_dir, Config)).
+-define(privdir, ?config(priv_dir, Config)).
+-endif.
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+
+-export([app_test/1,
+ checks/1,
+ file/1, syntax/1, compile/1, rules/1, expect/1,
+ conflicts/1,
+ examples/1,
+ empty/1, prec/1, yeccpre/1, lalr/1, old_yecc/1,
+ other_examples/1,
+ bugs/1,
+ otp_5369/1, otp_6362/1, otp_7945/1,
+ improvements/1,
+ otp_7292/1, otp_7969/1]).
+
+% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(suite) -> [app_test, checks, examples, bugs, improvements].
+
+app_test(doc) ->
+ ["Tests the applications consistency."];
+app_test(suite) ->
+ [];
+app_test(Config) when is_list(Config) ->
+ ?line ok=?t:app_test(parsetools),
+ ok.
+
+checks(suite) ->
+ [file, syntax, compile, rules, expect, conflicts].
+
+file(doc) ->
+ "Bad files and options.";
+file(suite) -> [];
+file(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, false}],
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file("not_a_file", Ret),
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file("not_a_file", [{return,true}]),
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file("not_a_file", [{report,false},return_errors]),
+ ?line error = yecc:file("not_a_file"),
+ ?line error = yecc:file("not_a_file", [{return,false},report]),
+ ?line error = yecc:file("not_a_file", [return_warnings,{report,false}]),
+ Filename = filename:join(Dir, "file.yrl"),
+ file:delete(Filename),
+
+ ?line {'EXIT', {badarg, _}} = (catch yecc:file({foo})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch yecc:file(Filename, {parserfile,{foo}})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch yecc:file(Filename, {includefile,{foo}})),
+
+ ?line {'EXIT', {badarg, _}} = (catch yecc:file(Filename, no_option)),
+ ?line {'EXIT', {badarg, _}} =
+ (catch yecc:file(Filename, [return | report])),
+ ?line {'EXIT', {badarg, _}} =
+ (catch yecc:file(Filename, {return,foo})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch yecc:file(Filename, includefile)),
+
+ Mini = <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t.">>,
+ ?line ok = file:write_file(Filename, Mini),
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file(Filename, [{parserfile,"//"} | Ret]),
+
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file(Filename, [{includefile,"//"} | Ret]),
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file(Filename, [{includefile,"/ /"} | Ret]),
+
+ YeccPre = filename:join(Dir, "yeccpre.hrl"),
+ ?line ok = file:write_file(YeccPre, <<"syntax error. ">>),
+ PreErrors1 = run_test(Config, Mini, YeccPre),
+ ?line {errors,[_],[]} = extract(YeccPre, PreErrors1),
+ ?line ok = file:write_file(YeccPre, my_yeccpre()),
+ ?line {'EXIT', {undef,_}} = (catch run_test(Config, Mini, YeccPre)),
+
+ MiniCode = <<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t.
+ Erlang code.
+ ">>,
+ ?line {'EXIT', {undef,_}} = (catch run_test(Config, MiniCode, YeccPre)),
+
+ file:delete(YeccPre),
+ file:delete(Filename),
+
+ ok.
+
+syntax(doc) ->
+ "Syntax checks.";
+syntax(suite) -> [];
+syntax(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ %% Report errors. Very simple test of format_error/1.
+ Ret = [return, {report, true}],
+ Filename = filename:join(Dir, "file.yrl"),
+ Parserfile1 = filename:join(Dir, "a file"),
+
+ ?line ok = file:write_file(Filename, <<"">>),
+ ?line {error,[{_,[{none,yecc,no_grammar_rules},
+ {none,yecc,nonterminals_missing},
+ {none,yecc,rootsymbol_missing},
+ {none,yecc,terminals_missing}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"Nonterminals">>),
+ ?line {error,[{_,[{_,yecc,{error,yeccparser,_}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"Nonterminals nt.">>),
+ ?line {error,[{_,[{none,yecc,no_grammar_rules},
+ {none,yecc,rootsymbol_missing},
+ {none,yecc,terminals_missing}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"Nonterminals nt. Terminals t.">>),
+ ?line {error,[{_,[{none,yecc,no_grammar_rules},
+ {none,yecc,rootsymbol_missing}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Nonterminals and terminals not disjoint.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt 't t'. Terminals t 't t'. Rootsymbol nt.">>),
+ ?line {error,[{_,[{1,yecc,{symbol_terminal_and_nonterminal,'t t'}},
+ {none,yecc,no_grammar_rules}]}],
+ []} = yecc:file(Filename, Ret),
+
+ %% Rootsymbol is not a nonterminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t.
+ Rootsymbol t. nt -> t.">>),
+ ?line {error,[{_,[{2,yecc,{bad_rootsymbol,t}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Rootsymbol is not a nonterminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t.
+ Rootsymbol t. nt -> t.">>),
+ ?line {error,[{_,[{2,yecc,{bad_rootsymbol,t}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Endsymbol is a nonterminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt.
+ Endsymbol nt.
+ nt -> t.">>),
+ ?line {error,[{_,[{2,yecc,{endsymbol_is_nonterminal,nt}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Endsymbol is a terminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt.
+ Endsymbol t.
+ nt -> t.">>),
+ ?line {error,[{_,[{2,yecc,{endsymbol_is_terminal,t}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% No grammar rules.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e.">>),
+ ?line {error,[{_,[{none,yecc,no_grammar_rules}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Bad declaration.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e.
+ nt -> t. e e.">>),
+ ?line {ok,_,[{_,[{2,yecc,bad_declaration}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Bad declaration.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t.
+ Rootsymbol nt nt. Rootsymbol nt. Endsymbol e.
+ nt -> t.">>),
+ ?line {ok,_,[{_,[{2,yecc,bad_declaration}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Syntax error found by yeccparser.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e.
+ a - a.">>),
+ ?line {error,[{_,[{2,yecc,{error,_yeccparser,_}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Syntax error: unknown nonterminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e.
+ 'unknown ' -> t.">>),
+ ?line {error,[{_,[{2,yecc,{undefined_nonterminal,'unknown '}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Undefined rhs symbols. Note quotes in output.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals Nonterminals nt.
+ Terminals t Terminals.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> Nonterminals.
+ Nonterminals -> Terminals receive foo 45
+ '17' 'a b'.">>),
+ ?line {error,[{_,[{6,yecc,{undefined_symbol,45}},
+ {6,yecc,{undefined_symbol,foo}},
+ {6,yecc,{undefined_symbol,'receive'}},
+ {7,yecc,{undefined_symbol,'17'}},
+ {7,yecc,{undefined_symbol,'a b'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% '$empty' used early, before Terminals. OK.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ nt -> '$empty'.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.">>),
+ ?line {ok,_,[{_,[{3,yecc,{unused_terminal,t}}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Illegal use of '$empty'.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt nt2.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t.
+ nt2 -> t '$empty'.">>),
+ ?line {error,[{_,[{6,yecc,illegal_empty}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ParserFile3 = [{parserfile, Parserfile1}],
+
+ %% Bad Erlang expression in action. Changed in OTP-7224.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t : a bad code.">>),
+ ?line {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Ret),
+
+ SzYeccPre = yeccpre_size(),
+ %% Note: checking the line numbers. Changes when yeccpre.hrl changes.
+ fun() ->
+ ?line {error,[{_,[{5,_,["syntax error before: ","bad"]}]},
+ {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}},
+ {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
+ []} = compile:file(Parserfile1, [basic_validation,return]),
+ ?line L1 = 24 + SzYeccPre,
+ ?line L2 = 31 + SzYeccPre
+ end(),
+
+ %% Bad macro in action. OTP-7224.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t : ?F(3).">>),
+ ?line {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Ret),
+ %% Note: checking the line numbers. Changes when yeccpre.hrl changes.
+ fun() ->
+ ?line {error,[{_,[{5,_,{undefined,'F',1}}]},
+ {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}},
+ {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
+ []} = compile:file(Parserfile1, [basic_validation,return]),
+ ?line L1 = 24 + SzYeccPre,
+ ?line L2 = 31 + SzYeccPre
+ end(),
+
+ %% Check line numbers. OTP-7224.
+ ?line ok = file:write_file(Filename,
+ <<"Terminals t.
+ Nonterminals nt.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t : ?F(3).
+ Erlang code.
+ -define(F(X), X).
+ t() ->
+ bad().">>),
+ ?line {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Ret),
+ ?line {error,[{_,[{9,_,{undefined_function,{bad,0}}}]}],
+ [{_,[{8,_,{unused_function,{t,0}}}]}]}
+ = compile:file(Parserfile1, [basic_validation, return]),
+
+ %% Terminals defined before nonterminals. (One of many checks...)
+ %% Used to give an error message, but now allowed.
+ ?line ok = file:write_file(Filename,
+ <<"Terminals t.
+ Nonterminals nt.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t.
+ Erlang code.">>),
+ ?line {ok, _, []} = yecc:file(Filename, Ret),
+
+ %% Precedence with swapped arguments. Bad declaration.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t.
+ Right t.
+ Left nt 100.">>),
+ ?line {ok,_,[{_,[{6,yecc,bad_declaration},{7,yecc,bad_declaration}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Precedence with unknown operator.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t.
+ Unary 100 '-'.">>),
+ ?line {error,[{_,[{6,yecc,{precedence_op_is_unknown,'-'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Precedence with endsymbol operator.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t.
+ Unary 100 e.">>),
+ ?line {error,[{_,[{6,yecc,{precedence_op_is_endsymbol,e}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Duplicated precedence.
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals nt.
+ Terminals t '+'.
+ Rootsymbol nt.
+ nt -> t '+' nt.
+ Left 100 '+'.
+ Right 200 t.
+ Left 200 '+'.
+ Left 200 '+'.
+ Right 200 t.">>),
+ ?line {error,[{_,[{8,yecc,{duplicate_precedence,'+'}},
+ {9,yecc,{duplicate_precedence,'+'}},
+ {10,yecc,{duplicate_precedence,t}}]}],
+ []} = yecc:file(Filename, Ret),
+
+ %% Duplicated nonterminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals 'n t' 'n t'. Terminals t.
+ Rootsymbol 'n t'. 'n t' -> t.">>),
+ ?line {ok, _, [{_,[{1,yecc,{duplicate_nonterminal,'n t'}}]}]} =
+ yecc:file(Filename, Ret),
+ ?line {ok, _, [{_,[{1,yecc,{duplicate_nonterminal,'n t'}}]}]} =
+ yecc:file(Filename, [return_warnings, {report, false}]),
+ ?line {ok, _} = yecc:file(Filename),
+ ?line {ok, _} =
+ yecc:file(Filename, [{report,false}, {return_warnings,false}]),
+
+ %% Duplicated terminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals 't t' 't t'.
+ Rootsymbol nt. nt -> 't t'.">>),
+ ?line {ok, _, [{_,[{1,yecc,{duplicate_terminal,'t t'}}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Two Nonterminals declarations.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t.
+ Nonterminals nt2.
+ Rootsymbol nt2. nt -> t. nt2 -> nt.">>),
+ ?line {error,[{_,[{2,yecc,{duplicate_declaration,'Nonterminals'}}]}],
+ []} = yecc:file(Filename, Ret),
+
+ %% Three Terminals declarations.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t.
+ Terminals t1.
+ Terminals t1.
+ Rootsymbol nt. nt -> t t1.">>),
+ ?line {error,[{_,[{2,yecc,{duplicate_declaration,'Terminals'}},
+ {3,yecc,{duplicate_declaration,'Terminals'}}]}],
+ []} = yecc:file(Filename, Ret),
+
+ %% Two root symbols.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol t.
+ Rootsymbol nt. nt -> t.">>),
+ ?line {error,[{_,[{2,yecc,{duplicate_declaration,'Rootsymbol'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Two end symbols.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol t.
+ Endsymbol e.
+ Endsymbol e. nt -> t.">>),
+ ?line {error,[{_,[{3,yecc,{duplicate_declaration,'Endsymbol'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Two end symbols.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol t.
+ Expect 1.
+ Expect 0.
+ Endsymbol e. nt -> t.">>),
+ ?line {error,[{_,[{3,yecc,{duplicate_declaration,'Expect'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Some words should not be used.
+ ?line ok = file:write_file(Filename, <<"
+ Terminals '$empty' '$end'.
+ Nonterminals '$undefined'.
+ Rootsymbol '$undefined'.
+ Endsymbol '$end'.
+ '$undefined' -> '$empty'.
+ ">>),
+ ?line {error,[{_,[{2,yecc,{reserved,'$empty'}},
+ {2,yecc,{reserved,'$end'}},
+ {3,yecc,{reserved,'$undefined'}},
+ {5,yecc,{endsymbol_is_terminal,'$end'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Undefined pseudo variable.
+ ?line ok = file:write_file(Filename,<<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t : '$2'.
+ ">>),
+ ?line {error,[{_,[{5,yecc,{undefined_pseudo_variable,'$2'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Space in module name.
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals list.
+ Terminals element.
+ Rootsymbol list.
+
+ list -> element : {single, '$1'}.
+ list -> list element : {pair, '$1', '$2'}.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ L = [{element, 1}, {element, 2}, {element, 3}],
+ {ok,_} = parse(L),
+ ok.
+ ">>),
+
+ Parserfile2 = filename:join(Dir, "a \"file\""),
+ %% The parser (yeccgramm.yrl) allows many symbol names...
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals Nonterminals Rootsymbol ':' '->'.
+ Terminals Terminals.
+ Rootsymbol Rootsymbol.
+ Endsymbol e.
+ Rootsymbol -> Nonterminals ':' '->'.
+ Nonterminals -> Terminals.
+ ':' -> '->'.
+ '->' -> Terminals.
+ ">>),
+ ?line {ok, _} = yecc:file(Filename, [{parserfile, Parserfile1}]),
+ ?line {ok, _} = yecc:file(Filename, [{parserfile, Parserfile1},time]),
+ ?line {ok,[]} = compile:file(Parserfile1, [basic_validation]),
+
+ Quotes = <<"
+ Nonterminals
+ tail try 17 42 Unused ' unused ' '42' 'fnutt\\'' receive.
+
+ Terminals
+ ']' '|' ',' '\"hi\"' 'there\\'' 'you\\'' ACCEPT.
+
+ Rootsymbol 17.
+
+ Endsymbol '$end'.
+
+ 17 -> try : '$1':more([\"hi \\\" there\", '.', 3.14, % $3 , % '$1' is a module
+ -104, ' ', ' a', '->', $a, $\t]), '$1'.
+
+ try -> tail 'you\\'' 'fnutt\\''.
+
+ 'fnutt\\'' -> 'you\\'' ACCEPT.
+
+ '42' -> tail.
+
+ tail -> ']' :
+ (fun(Strange) -> foo end)(apa).
+ tail -> '|' try ']' :
+ (fun(Strange) -> foo;
+ (_) -> 'when' % warning
+ end)('ap a', foo),
+ %% This line intentionally left blank.
+ R = #rec{},
+ A = R#rec.a,
+ <<\"hi\">> = <<\"hi\">>,
+ there.
+ tail -> ',' try tail : {cons,line('$2'),'$2','$3'}.
+
+
+ Erlang code.
+
+ -export([t/0]).
+
+ -record(rec, {a}).
+
+ just(Some, Code) ->
+ true.
+
+ more(Code) ->
+ io:format(\"~p~n\", [Code]), true.
+
+ line(_) ->
+ 17.
+
+ t() ->
+ ok. % compiled successfully...
+
+ ">>,
+
+ ?line ok = file:write_file(Filename, Quotes),
+ ?line {ok,_,[{_,
+ [{3,yecc,{unused_nonterminal,42}},
+ {3,yecc,{unused_nonterminal,' unused '}},
+ {3,yecc,{unused_nonterminal,'42'}},
+ {3,yecc,{unused_nonterminal,'Unused'}},
+ {3,yecc,{unused_nonterminal,'receive'}},
+ {6,yecc,{unused_terminal,'"hi"'}},
+ {6,yecc,{unused_terminal,'there\''}}]}]} =
+ yecc:file(Filename, Ret),
+
+ Ts = [{quotes, Quotes, default, ok}],
+ ?line run(Config, Ts),
+
+ %% Non-terminal has no rules, but is unused.
+ ?line ok = file:write_file(Filename,<<"
+ Nonterminals nt bad.
+ Terminals t.
+ Rootsymbol nt.
+
+ nt -> t : something.
+ ">>),
+ ?line {ok,_,[{_,[{2,yecc,{unused_nonterminal,bad}}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Non-terminal has no rules and is used.
+ ?line ok = file:write_file(Filename,<<"
+ Nonterminals nt bad.
+ Terminals t.
+ Rootsymbol nt.
+
+ nt -> t bad : something.
+ ">>),
+ ?line {error,[{_,[{2,yecc,{missing_syntax_rule,bad}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Warning in Erlang code. With and without file attributes.
+ ?line ok = file:write_file(Filename,<<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+
+ nt -> t : t(17).
+
+ Erlang code.
+
+ t(A) ->
+ b.
+ ">>),
+ ?line {ok, _, []} =
+ yecc:file(Filename, [file_attributes | Ret]),
+ Opts = [basic_validation, return],
+ Erlfile = filename:join(Dir, "file.erl"),
+ ?line {ok,[],[{_,[{10,_,_}]}]} = compile:file(Erlfile, Opts),
+ ?line {ok, _, []} =
+ yecc:file(Filename, [{file_attributes,false} | Ret]),
+ ?line {ok,[],[{_,[{4,_,_}]}]} = compile:file(Erlfile, Opts),
+
+ file:delete(Parserfile1 ++ ".erl"),
+ file:delete(Parserfile2 ++ ".erl"),
+ file:delete(Filename),
+
+ ok.
+
+compile(doc) ->
+ "Check of compile/3.";
+compile(suite) -> [];
+compile(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.yrl"),
+ Parserfile = filename:join(Dir, "file.erl"),
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t.">>),
+ ?line error = yecc:compile(Filename, "//", #options{}),
+ ?line ok = yecc:compile(Filename, Parserfile, #options{}),
+ file:delete(Parserfile),
+ file:delete(Filename),
+ ok.
+
+rules(doc) ->
+ "Check of rules.";
+rules(suite) -> [];
+rules(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, false}],
+ Filename = filename:join(Dir, "file.yrl"),
+
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt.
+ nt -> t. nt -> t.">>),
+ ?line {error,[{_,[{none,yecc,{conflict,_}}]}],
+ [{_,[{none,yecc,{conflicts,0,1}}]}]} =
+ yecc:file(Filename, [return, report]),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals A B E.
+ Terminals c d f x y.
+ Rootsymbol A.
+
+ A -> B c d.
+ A -> E c f.
+ B -> x y.
+ E -> x y.
+ ">>),
+ ?line {error,[{_,[{none,yecc,{conflict,_}}]}],
+ [{_,[{none,yecc,{conflicts,0,1}}]}]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename,<<"
+ Terminals t.
+ Nonterminals nt.
+ Rootsymbol nt.
+ nt -> '$empty' : '$1'.
+ nt -> t.
+ ">>),
+ ?line {error,[{_,[{5,yecc,{undefined_pseudo_variable,'$1'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename,<<"
+ Terminals t.
+ Nonterminals nt.
+ Rootsymbol nt.
+ nt -> '$empty' : '$0'.
+ nt -> t.
+ ">>),
+ ?line {error,[{_,[{5,yecc,{undefined_pseudo_variable,'$0'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ file:delete(Filename),
+
+ %% No precedences.
+ Ts = [{rules_1,<<"
+ Nonterminals exp.
+ Terminals number '*' '+' '(' ')'.
+ Rootsymbol exp.
+
+ exp -> exp '+' exp : {plus,'$1','$3'}.
+ exp -> exp '*' exp : {times,'$1','$3'}.
+ exp -> number : element(2, '$1').
+ exp -> '(' exp ')' : '$2'.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok, {times, 1, {plus, 3, 5}}} =
+ parse([{number,1}, {'*',2}, {number,3},
+ {'+',4}, {number,5}]),
+ ok.
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+examples(suite) ->
+ [empty, prec, yeccpre, lalr, old_yecc, other_examples].
+
+expect(doc) ->
+ "Check of expect.";
+expect(suite) -> [];
+expect(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, true}],
+ Filename = filename:join(Dir, "file.yrl"),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals e.
+ Terminals i t else.
+ Rootsymbol e.
+ Expect a.
+
+ e -> i e t e.
+ e -> i e t e else e.
+ ">>),
+ ?line {error,[{_,[{5,yecc,{bad_expect,a}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals e.
+ Terminals i t else.
+ Rootsymbol e.
+ Expect 1.
+
+ e -> i e t e.
+ e -> i e t e else e.
+ ">>),
+ ?line {ok, _, []} = yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals e.
+ Terminals i t else.
+ Rootsymbol e.
+ Expect 2.
+
+ e -> i e t e.
+ e -> i e t e else e.
+ ">>),
+ ?line {ok, _, [{_,[{none,yecc,{conflicts,1,0}}]}]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals e.
+ Terminals i t else.
+ Rootsymbol e.
+ Expect -2.
+
+ e -> i e t e.
+ e -> i e t e else e.
+ ">>),
+ ?line {error,[{_,[{5,yecc,{error,_yeccparser,_}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% States N. An undocumented declaration used for testing.
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ States 100.
+ nt -> t.">>),
+ ?line {ok,_,[{_, [{none,yecc,{n_states,100,3}}]}]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ States bad.
+ nt -> t.">>),
+ ?line {error,[{_,[{5,yecc,{bad_states,bad}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ file:delete(Filename),
+ ok.
+
+conflicts(doc) ->
+ "Shift/reduce and reduce/reduce conflicts.";
+conflicts(suite) -> [];
+conflicts(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, true}],
+ Filename = filename:join(Dir, "file.yrl"),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals S List Tuple Elements Element.
+ Terminals '{' '}' '[' ']' ',' nil e.
+ Rootsymbol S.
+
+ S -> '$empty' : empty.
+ S -> List : '$1'.
+
+ List -> '$empty' : [].
+ List -> nil : [].
+ List -> '[' Tuple ']' : {list, '$2'}.
+
+ Tuple -> '$empty' : {}.
+ Tuple -> '{' '}' : {}.
+ Tuple -> '{' Elements '}' : {tuple, '$2'}.
+
+ Elements -> '$empty' : none.
+ Elements -> Elements ',' Element : {elements, '$3', '$1'}.
+ Elements -> Element : '$1'.
+
+ Element -> List : '$1'.
+ Element -> Tuple : '$1'.
+ Element -> e : '$1'.
+ ">>),
+ ?line {error,[{_,_}],[{_,[{none,yecc,{conflicts,1,5}}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Can easily be resolved (but don't do it!).
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals S List Tuple Elements Element.
+ Terminals '{' '}' '[' ']' ',' nil e.
+ Rootsymbol S.
+
+ Right 100 List.
+
+ S -> '$empty' : empty.
+ S -> List : '$1'.
+
+ List -> '$empty' : [].
+ List -> nil : [].
+ List -> '[' Tuple ']' : {list, '$2'}.
+
+ Tuple -> '$empty' : {}.
+ Tuple -> '{' '}' : {}.
+ Tuple -> '{' Elements '}' : {tuple, '$2'}.
+
+ Elements -> '$empty' : none.
+ Elements -> Elements ',' Element : {elements, '$3', '$1'}.
+ Elements -> Element : '$1'.
+
+ Element -> List : '$1'.
+ Element -> Tuple : '$1'.
+ Element -> e : '$1'.
+ ">>),
+ ?line {ok, _, []} =
+ yecc:file(Filename, Ret),
+
+ file:delete(Filename),
+ ok.
+
+empty(doc) ->
+ "'$empty'.";
+empty(suite) -> [];
+empty(Config) when is_list(Config) ->
+ Ts = [{empty_1, <<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> '$empty': nothing.
+ nt -> t : something.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok, nothing} = parse([{e,2}]),
+ {ok, something} = parse([{t,1},{e,2}]),
+ ok.">>,
+ default,
+ ok},
+ {empty_2, <<"
+ %% There used to be a bug when it came to the left
+ %% corners. In this example rule 2 is a prefix of rule 1
+ %% such that the rule 2 generates $empty but rule 1 does
+ %% not. The old buggy code seemingly worked well too.
+ Nonterminals top A B C D.
+ Terminals t.
+ Rootsymbol top.
+
+ top -> A B C D : {'$1','$2','$3','$4'}.
+ top -> A B C : {'$1','$2','$3'}.
+
+ A -> '$empty' : e.
+ B -> '$empty' : e.
+ C -> '$empty' : e.
+
+ D -> t : t.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok,{e,e,e,t}} = parse([{t, 1}]),
+ {ok,{e,e,e}} = parse([]),
+ ok.
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+prec(doc) ->
+ "Precedence.";
+prec(suite) -> [];
+prec(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, false}],
+ Filename = filename:join(Dir, "file.yrl"),
+
+ %% Don't know what 'Unary' actually means, but this is how it has
+ %% always worked...
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals E.
+ Terminals '*' '+' '=' integer.
+ Rootsymbol E.
+
+ E -> E '=' E : {op, '=', '$1', '$3'}.
+ E -> E '*' E : {op, '*', '$1', '$3'}.
+ E -> E '+' E : {op, '+', '$1', '$3'}.
+ E -> integer : '$1'.
+
+ Unary 100 '='.
+ Left 200 '+'.
+ Left 400 '*'.
+ ">>),
+ ?line {error,[{_,[{none,yecc,{conflict,_}}]}],
+ [{_,[{none,yecc,{conflicts,1,0}}]}]} =
+ yecc:file(Filename, Ret),
+
+ Ts = [{prec_1, <<"
+ Nonterminals E Expr Uminus.
+ Terminals '=' '+' '*' '-' '(' ')' integer var dot.
+ Rootsymbol Expr.
+
+ Expr -> E dot : '$1'.
+ E -> var '=' E : {match, line_of('$1'), '$1', '$3'}.
+ E -> E '+' E : {op, line_of('$1'), '+', '$1', '$3'}.
+ E -> E '-' E : {op, line_of('$1'), '-', '$1', '$3'}.
+ E -> E '*' E : {op, line_of('$1'), '*', '$1', '$3'}.
+ E -> Uminus : '$1'.
+ E -> '(' E ')' : '$2'.
+ E -> integer : '$1'.
+
+ Uminus -> '-' E : {op, line_of('$1'), '-', '$2'}.
+
+ Right 200 '='.
+ Left 300 '+'.
+ Left 300 '-'.
+ Left 400 '*'.
+ Unary 500 Uminus.
+
+ Erlang code.
+
+ -export([t/0, t/1]).
+
+ line_of(Token) ->
+ element(2, Token).
+
+ t() ->
+ {ok, -56} = t(\"A = (4 + 3) * - 8. \"),
+ {ok, 28} = t(\"A = 4 + B=3 * 8. \"),
+ {ok, 28} = t(\"4 - 3 * - 8. \"),
+ {ok, -20} = t(\"4 - 3 * 8. \"),
+ {ok, 2} = t(\"1 - - 1.\"),
+ ok.
+
+ t(S) ->
+ case erl_scan:string(S) of
+ {ok, Tokens, _Line} ->
+ case parse(Tokens) of
+ {ok, Expr} ->
+ case catch erl_eval:expr(Expr, []) of
+ {value, Value, _Bs} ->
+ {ok, Value};
+ {'EXIT', Reason} ->
+ {error, Reason}
+ end;
+ Error ->
+ Error
+ end;
+ Error ->
+ Error
+ end.
+ ">>,
+ default,
+ ok},
+
+ {prec_2, <<"
+ Nonterminals E uminus.
+ Terminals '*' '-' integer.
+ Rootsymbol E.
+
+ E -> E '-' E : {op, '-', '$1', '$3'}.
+ E -> E '*' E : {op, '*', '$1', '$3'}.
+ E -> uminus: '$1'.
+ E -> integer : '$1'.
+
+ uminus -> '-' E : {op, '-', '$2'}.
+
+ Left 200 '-'.
+ Left 400 '*'.
+ Unary 500 uminus.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ %% This used to be parsed -(4 * 3), but that has been corrected:
+ {ok,{op,'*',{op,'-',{integer,1,4}},{integer,3,12}}} =
+ parse([{'-',0},{integer,1,4},{'*',2},{integer,3,12}]),
+
+ {ok,{op,'-',{op,'-',{integer,1,4}},{integer,3,12}}} =
+ parse([{'-',0},{integer,1,4},{'-',2},{integer,3,12}]),
+ {ok,{op,'*',{op,'-',{op,'-',{integer,2,4}}},{integer,4,12}}} =
+ parse([{'-',0},{'-',1},{integer,2,4},{'*',3},{integer,4,12}]),
+ {ok,{op,'-',{integer,1,4},{op,'-',{integer,4,12}}}} =
+ parse([{integer,1,4},{'-',2},{'-',3},{integer,4,12}]),
+ ok.
+ ">>,
+ default,
+ ok},
+ {prec_3, <<"
+ Nonterminals nt.
+ Terminals '(' ')' t op.
+ Rootsymbol nt.
+
+ Nonassoc 100 op.
+
+ nt -> nt op nt : {'$2', '$1', '$3'}.
+ nt -> '(' nt ')' : '$2'.
+ nt -> t : '$1'.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {error,{4,yecc_test,[\"syntax error before: \",\"op\"]}} =
+ parse([{t,1},{op,2},{t,3},{op,4},{t,5}]),
+ {ok,{{op,2},{t,1},{{op,5},{t,4},{t,6}}}} =
+ parse([{t,1},{op,2},{'(',3},{t,4},{op,5},{t,6},{')',7}]),
+ ok.
+ ">>,
+ default,
+ ok},
+
+ {prec_4, <<"
+ Nonterminals E.
+ Terminals '-' '+' '=' id.
+ Rootsymbol E.
+
+ E -> E '=' E : {op, '=', '$1', '$3'}.
+ E -> E '+' E : {op, '+', '$1', '$3'}.
+ E -> '-' E : {op, '-', '$2'}.
+ E -> id : '$1'.
+
+ Nonassoc 100 '='.
+ Right 200 '+' '-'.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok,{op,'=',{id,1},{op,'-',{op,'+',{id,4},{id,6}}}}} =
+ parse([{id,1},{'=',2},{'-',3},{id,4},{'+',5},{id,6}]),
+ ok.
+
+ ">>,
+ default,
+ ok}],
+
+ ?line run(Config, Ts),
+ ok.
+
+yeccpre(doc) ->
+ "Errors etc. in actions, handled by yeccpre. parse_and_scan.";
+yeccpre(suite) -> [];
+yeccpre(Config) when is_list(Config) ->
+ Ts = [{error_1, <<"
+ Nonterminals list.
+ Terminals element e.
+ Rootsymbol list.
+
+ list -> element : {single, '$1'}.
+ list -> list element : throw(error).
+ list -> e : return_error(element(2, '$1'), bad_element).
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ error = (catch parse([{element,1},{element,2}])),
+ {error, {2, _, Mess}} = parse([{element,1},{e,2}]),
+ ok.
+ ">>,
+ default,
+ ok},
+
+ {error_2, <<"
+ Nonterminals list.
+ Terminals element.
+ Rootsymbol list.
+
+ list -> element.
+
+ Erlang code.
+
+ -export([t/0, scan/1]).
+
+ scan(How) ->
+ case How of
+ thrown -> throw(thrown);
+ error -> erlang:error(error);
+ exit -> exit(exit)
+ end.
+
+ t() ->
+ try parse_and_scan({yecc_test, scan, [thrown]})
+ catch throw: thrown ->
+ ok
+ end,
+ try parse_and_scan({yecc_test, scan, [error]})
+ catch error: error ->
+ ok
+ end,
+ try parse_and_scan({{yecc_test, scan}, [exit]})
+ catch exit: exit ->
+ ok
+ end,
+ try parse_and_scan({fun scan/1, [thrown]})
+ catch throw: thrown ->
+ ok
+ end,
+ ok.
+ ">>,
+ default,
+ ok}],
+
+ ?line run(Config, Ts),
+ ok.
+
+lalr(doc) ->
+ "Examples of grammars that are LALR(1) but not SLR(1).";
+lalr(suite) -> [];
+lalr(Config) when is_list(Config) ->
+ Ts = [{lalr_1, <<"
+ %% http://inst.cs.berkeley.edu/~cs164/lectures/slide14a.pdf
+ %% http://pages.cpsc.ucalgary.ca/~robin/class/411/LR.1.html
+ %% b d . c. Shift or reduce?
+ Nonterminals S A.
+ Terminals a b c d.
+ Rootsymbol S.
+ S -> A a : {r1,'$1','$2'}.
+ S -> b A c : {r2,'$1','$2','$3'}.
+ S -> d c : {r3,'$1','$2'}.
+ S -> b d a : {r4,'$1','$2','$3'}.
+
+ A -> d : {r5,'$1'}.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ %% Reduce!
+ {ok,{r2,{b,1},{r5,{d,2}},{c,3}}} = parse([{b,1},{d,2},{c,3}]),
+ ok.
+ ">>,
+ default,
+ ok},
+ {lalr_2, <<"
+ %% http://www.cs.pitt.edu/~mock/cs2210/lectures/lecture5.pdf
+ Nonterminals S L R.
+ Terminals '*' id '='.
+ Rootsymbol S.
+ S -> L '=' R : {r1,'$1','$3'}.
+ S -> R : {r2,'$1'}.
+
+ L -> '*' R : {r3,'$2'}.
+ L -> id : {r4,'$1'}.
+
+ R -> L : {r5,'$1'}.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok,{r1,{r3,{r5,{r4,{id,1}}}},{r5,{r4,{id,3}}}}} =
+ parse([{'*',0},{id,1},{'=',2},{id,3}]),
+ ok.
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+old_yecc(doc) ->
+ "The old interface yecc:yecc/2,3,4.";
+old_yecc(suite) -> [];
+old_yecc(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.yrl"),
+ Parserfile = filename:join(Dir, "file.erl"),
+ Mini = <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t.">>,
+ ?line ok = file:write_file(Filename, Mini),
+ ?line {_, _} = yecc:yecc(Filename, Parserfile),
+ ?line {_, _} = yecc:yecc(Filename, Parserfile, true),
+ ?line {_, _} = yecc:yecc(Filename, Parserfile, true),
+ TE = process_flag(trap_exit, true),
+ ?line {'EXIT', error} =
+ (catch yecc:yecc(Filename, Parserfile, false, Parserfile)),
+ _ = process_flag(trap_exit, TE),
+ ok.
+
+other_examples(doc) ->
+ "Misc examples.";
+other_examples(suite) -> [];
+other_examples(Config) when is_list(Config) ->
+ Ts = [{empty, <<"
+ %% G1 from the 1974 article.
+
+ Nonterminals LIST ELEMENT.
+ Terminals ',' a b.
+ Rootsymbol LIST.
+
+ LIST -> LIST ',' ELEMENT : {'$1', '$3'}.
+ LIST -> ELEMENT : '$1'.
+
+ ELEMENT -> a : '$1'.
+ ELEMENT -> b : '$1'.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ L = [{a, 1}, {',', 2}, {b, 3}],
+ {ok,{{a,1},{b,3}}} = parse(L),
+ ok.
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+bugs(suite) ->
+ [otp_5369, otp_6362, otp_7945].
+
+otp_5369(doc) ->
+ "OTP-5369. A bug in parse_and_scan reported on erlang questions.";
+otp_5369(suite) -> [];
+otp_5369(Config) when is_list(Config) ->
+ Ts = [{otp_5369,<<"
+ Nonterminals list.
+ Terminals element.
+ Rootsymbol list.
+
+ list -> element : {single, '$1'}.
+ list -> list element : {pair, '$1', '$2'}.
+
+ Erlang code.
+
+ -export([t/0, scan/1]).
+
+ scan(Lexer) ->
+ Lexer ! {scan, self()},
+ receive
+ {ok, Lexer, [Token], Position} ->
+ {ok, [Token], Position};
+ {eof, Lexer, Position} ->
+ {eof, Position}
+ end.
+
+ make_scanner(L) ->
+ spawn_link(fun() ->
+ loop(L)
+ end).
+
+ loop([]) ->
+ receive
+ {scan, Pid} ->
+ Pid ! {eof, self(), 1000}
+ end;
+ loop([Token = {_, P}|T]) ->
+ receive
+ {scan, Pid} ->
+ Pid ! {ok, self(), [Token], P},
+ loop(T)
+ end.
+
+ t(L) ->
+ case parse_and_scan({yecc_test, scan, [make_scanner(L)]}) of
+ {ok, _Result} ->
+ ok;
+ {error, {_LineNumber, Module, Message}} ->
+ _M = apply(Module, format_error, [Message]),
+ not_ok
+ end.
+
+ t() ->
+ not_ok = t([]), %% This test has been added afterwards.
+ %% OTP-5369 did not fix this bug!
+ L = [{element, 1},
+ {element, 2},
+ {element, 3}],
+ t(L).
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+otp_6362(doc) ->
+ "OTP-6362. A precedence declaration bug reported on erlang questions.";
+otp_6362(suite) -> [];
+otp_6362(Config) when is_list(Config) ->
+ Ts = [{otp_6362_1,<<"
+ Nonterminals cmp compare expr.
+ Terminals 'string' '>' '='.
+ Rootsymbol compare.
+ Nonassoc 250 cmp.
+ compare -> expr cmp expr : {cmp, '$2', '$1', '$3'}.
+ compare -> expr : {cmp, '==', '$1', {string, \"TRUE\"}}.
+ cmp -> '>' '=' : '>='.
+ cmp -> '>' : '>'.
+ expr -> 'string' : '$1'.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok,{cmp,'>',{string,1},{string,3}}} =
+ parse([{string,1}, {'>', 2}, {string,3}]),
+ ok.
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+
+ Dir = ?privdir,
+ %% Report errors. Very simple test of format_error/1.
+ Ret = [return, {report, true}],
+ Filename = filename:join(Dir, "file.yrl"),
+
+ %% An error introduced due to this ticket. Terminals can be
+ %% assigned conflicting precedences, which cannot be resolved.
+ ?line ok = file:write_file(Filename,<<"
+ Nonterminals cmp compare expr fopp.
+ Terminals string '>' '='.
+ Rootsymbol compare.
+ Nonassoc 250 cmp.
+ Left 300 '>'.
+
+ compare -> expr cmp expr : {cmp, '$2', '$1', '$3'}.
+ compare -> expr fopp expr : {cmp, '$2', '$1', '$3'}.
+ compare -> expr '=' expr : '$1'.
+ compare -> expr : {cmp, '==', '$1', {string, foo}}.
+ cmp -> '>' '=' : '>='.
+ cmp -> '>' : '>'.
+ expr -> string : '$1'.
+
+ fopp -> '>' '=' : '>='.
+ fopp -> '>' : '>'.">>),
+
+ Ret = [return, {report, true}],
+ ?line {error,[{_,[{none,yecc,{conflict,_}}]}],[]} =
+ yecc:file(Filename, Ret),
+ file:delete(Filename),
+ ok.
+
+my_yeccpre() ->
+ %% Version 1.1.
+ <<"parse(Tokens) ->
+ yeccpars0(Tokens, false).
+
+ parse_and_scan({F, A}) -> % Fun or {M, F}
+ yeccpars0([], {F, A});
+ parse_and_scan({M, F, A}) ->
+ yeccpars0([], {{M, F}, A}).
+
+ format_error(Message) ->
+ case io_lib:deep_char_list(Message) of
+ true ->
+ Message;
+ _ ->
+ io_lib:write(Message)
+ end.
+
+ % To be used in grammar files to throw an error message to the parser
+ % toplevel. Doesn't have to be exported!
+ -compile({nowarn_unused_function,{return_error,2}}).
+ return_error(Line, Message) ->
+ throw({error, {Line, yecc_test, Message}}).
+
+ yeccpars0(Tokens, MFA) ->
+ try yeccpars1(Tokens, MFA, 0, [], [])
+ catch
+ throw: {error, {_Line, yecc_test, _M}} = Error ->
+ Error % probably from return_error/1
+ end.
+
+ % Don't change yeccpars1/6 too much, it is called recursively by yeccpars2/8!
+ yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) ->
+ yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens,
+ Tokenizer);
+ yeccpars1([], {F, A}, State, States, Vstack) ->
+ case apply(F, A) of
+ {ok, Tokens, _Endline} ->
+ yeccpars1(Tokens, {F, A}, State, States, Vstack);
+ {eof, _Endline} ->
+ yeccpars1([], false, State, States, Vstack);
+ {error, Descriptor, _Endline} ->
+ {error, Descriptor}
+ end;
+ yeccpars1([], false, State, States, Vstack) ->
+ yeccpars2(State, '$end', States, Vstack, {'$end', 999999}, [], false).
+
+ % For internal use only.
+ yeccerror(Token) ->
+ {error,
+ {element(2, Token), yecc_test,
+ [\"syntax error before: \", yecctoken2string(Token)]}}.
+
+ yecctoken2string({atom, _, A}) -> io_lib:write(A);
+ yecctoken2string({integer,_,N}) -> io_lib:write(N);
+ yecctoken2string({float,_,F}) -> io_lib:write(F);
+ yecctoken2string({char,_,C}) -> io_lib:write_char(C);
+ yecctoken2string({var,_,V}) -> io_lib:format('~s', [V]);
+ yecctoken2string({string,_,S}) -> io_lib:write_string(S);
+ yecctoken2string({reserved_symbol, _, A}) -> io_lib:format('~w', [A]);
+ yecctoken2string({_Cat, _, Val}) -> io_lib:format('~w', [Val]);
+ yecctoken2string({'dot', _}) -> io_lib:format('~w', ['.']);
+ yecctoken2string({'$end', _}) ->
+ [];
+ yecctoken2string({Other, _}) when is_atom(Other) ->
+ io_lib:format('~w', [Other]);
+ yecctoken2string(Other) ->
+ io_lib:write(Other).
+">>.
+
+otp_7945(doc) ->
+ "OTP-7945. A bug introduced in R13A.";
+otp_7945(suite) -> [];
+otp_7945(Config) when is_list(Config) ->
+ ?line {error,_} = erl_parse:parse([{atom,3,foo},{'.',2,9,9}]),
+ ok.
+
+improvements(suite) ->
+ [otp_7292, otp_7969].
+
+otp_7292(doc) ->
+ "OTP-7292. Header declarations for edoc.";
+otp_7292(suite) -> [];
+otp_7292(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.yrl"),
+ Parserfile1 = filename:join(Dir, "a file"),
+
+ Contents = <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t : a bad code.
+
+ Header \"%% copyright bla bla bla\"
+ \"%% @private\" \"%% foo\"
+ \"%% @author X.Y.\".
+
+ Erlang code.
+
+ %% @private
+ %% etc.
+
+ foo() ->
+ bar. ">>,
+
+ %% Check that correct line number is used in messages.
+ ?line ok = file:write_file(Filename, Contents),
+ ParserFile3 = [{parserfile, Parserfile1}],
+ Ret = [return, {report, true}],
+ ?line {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Ret),
+
+ %% Note: checking the line numbers. Changes when yeccpre.hrl changes.
+ fun() ->
+ SzYeccPre = yeccpre_size(),
+ ?line {error,
+ [{_,[{5,_,["syntax error before: ","bad"]}]},
+ {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}},
+ {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
+ [{_,[{16,_,{unused_function,{foo,0}}}]}]} =
+ compile:file(Parserfile1, [basic_validation, return]),
+ ?line L1 = 34 + SzYeccPre,
+ ?line L2 = 41 + SzYeccPre
+ end(),
+
+ YeccPre = filename:join(Dir, "yeccpre.hrl"),
+ ?line ok = file:write_file(YeccPre,
+ [<<"-export([parse/1, parse_and_scan/1, format_error/1]).\n">>,
+ yeccpre_v1_2()]),
+ Inc = [{includefile,YeccPre}],
+ ?line {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Inc ++ Ret),
+ fun() ->
+ SzYeccPre = yeccpre_size(YeccPre),
+ ?line {error,
+ [{_,[{5,_,["syntax error before: ","bad"]}]},
+ {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}},
+ {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
+ [{_,[{16,_,{unused_function,{foo,0}}}]}]} =
+ compile:file(Parserfile1, [basic_validation, return]),
+ ?line L1 = 33 + SzYeccPre,
+ ?line L2 = 40 + SzYeccPre
+ end(),
+
+ file:delete(YeccPre),
+ file:delete(Parserfile1 ++ ".erl"),
+ file:delete(Filename),
+
+ ok.
+
+yeccpre_v1_2() ->
+ <<"
+parse(Tokens) ->
+ yeccpars0(Tokens, false).
+
+parse_and_scan({F, A}) -> % Fun or {M, F}
+ yeccpars0([], {F, A});
+parse_and_scan({M, F, A}) ->
+ yeccpars0([], {{M, F}, A}).
+
+format_error(Message) ->
+ case io_lib:deep_char_list(Message) of
+ true ->
+ Message;
+ _ ->
+ io_lib:write(Message)
+ end.
+
+-define(CODE_VERSION, \"1.2\").
+
+yeccpars0(Tokens, MFA) ->
+ try yeccpars1(Tokens, MFA, 0, [], [])
+ catch
+ error: Error ->
+ Stacktrace = erlang:get_stacktrace(),
+ try yecc_error_type(Error, Stacktrace) of
+ {syntax_error, Token} ->
+ yeccerror(Token);
+ {missing_in_goto_table=Tag, State} ->
+ Desc = {State, Tag},
+ erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc},
+ Stacktrace);
+ {missing_in_goto_table=Tag, Symbol, State} ->
+ Desc = {Symbol, State, Tag},
+ erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc},
+ Stacktrace)
+ catch _:_ -> erlang:raise(error, Error, Stacktrace)
+ end;
+ throw: {error, {_Line, ?MODULE, _M}} = Error ->
+ Error % probably from return_error/2
+ end.
+
+yecc_error_type(function_clause, [{?MODULE,F,[_,_,_,_,Token,_,_]} | _]) ->
+ \"yeccpars2\" ++ _ = atom_to_list(F),
+ {syntax_error, Token};
+yecc_error_type({case_clause,{State}}, [{?MODULE,yeccpars2,_}|_]) ->
+ %% Inlined goto-function
+ {missing_in_goto_table, State};
+yecc_error_type(function_clause, [{?MODULE,F,[State]}|_]) ->
+ \"yeccgoto_\" ++ SymbolL = atom_to_list(F),
+ {ok,[{atom,_,Symbol}]} = erl_scan:string(SymbolL),
+ {missing_in_goto_table, Symbol, State}.
+
+yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) ->
+ yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens,
+ Tokenizer);
+yeccpars1([], {F, A}, State, States, Vstack) ->
+ case apply(F, A) of
+ {ok, Tokens, _Endline} ->
+ yeccpars1(Tokens, {F, A}, State, States, Vstack);
+ {eof, _Endline} ->
+ yeccpars1([], false, State, States, Vstack);
+ {error, Descriptor, _Endline} ->
+ {error, Descriptor}
+ end;
+yeccpars1([], false, State, States, Vstack) ->
+ yeccpars2(State, '$end', States, Vstack, {'$end', 999999}, [], false).
+
+yeccpars1(State1, State, States, Vstack, Stack1, [Token | Tokens],
+ Tokenizer) ->
+ yeccpars2(State, element(1, Token), [State1 | States],
+ [Stack1 | Vstack], Token, Tokens, Tokenizer);
+yeccpars1(State1, State, States, Vstack, Stack1, [], {F, A}) ->
+ case apply(F, A) of
+ {ok, Tokens, _Endline} ->
+ yeccpars1(State1, State, States, Vstack, Stack1, Tokens, {F, A});
+ {eof, _Endline} ->
+ yeccpars1(State1, State, States, Vstack, Stack1, [], false);
+ {error, Descriptor, _Endline} ->
+ {error, Descriptor}
+ end;
+yeccpars1(State1, State, States, Vstack, Stack1, [], false) ->
+ yeccpars2(State, '$end', [State1 | States], [Stack1 | Vstack],
+ {'$end', 999999}, [], false).
+
+yeccerror(Token) ->
+ {error,
+ {element(2, Token), ?MODULE,
+ [\"syntax error before: \", yecctoken2string(Token)]}}.
+
+yecctoken2string({atom, _, A}) -> io_lib:write(A);
+yecctoken2string({integer,_,N}) -> io_lib:write(N);
+yecctoken2string({float,_,F}) -> io_lib:write(F);
+yecctoken2string({char,_,C}) -> io_lib:write_char(C);
+yecctoken2string({var,_,V}) -> io_lib:format('~s', [V]);
+yecctoken2string({string,_,S}) -> io_lib:write_string(S);
+yecctoken2string({reserved_symbol, _, A}) -> io_lib:format('~w', [A]);
+yecctoken2string({_Cat, _, Val}) -> io_lib:format('~w', [Val]);
+yecctoken2string({'dot', _}) -> io_lib:format('~w', ['.']);
+yecctoken2string({'$end', _}) ->
+ [];
+yecctoken2string({Other, _}) when is_atom(Other) ->
+ io_lib:format('~w', [Other]);
+yecctoken2string(Other) ->
+ io_lib:write(Other).
+">>.
+
+run(Config, Tests) ->
+ F = fun({N,P,Pre,E}) ->
+ case catch run_test(Config, P, Pre) of
+ E ->
+ ok;
+ Bad ->
+ ?t:format("~nTest ~p failed. Expected~n ~p~n"
+ "but got~n ~p~n", [N, E, Bad]),
+ fail()
+ end
+ end,
+ lists:foreach(F, Tests).
+
+otp_7969(doc) ->
+ "OTP-7969. Interface to the I/O protocol..";
+otp_7969(suite) -> [];
+otp_7969(Config) when is_list(Config) ->
+ ?line {ok,Ts1,_} =
+ erl_scan:string("'foo\nbar'", {1,1}, [text]),
+ ?line {error,{2,_,["syntax error before: ",[]]}} = erl_parse:parse(Ts1),
+
+ ?line {ok,Ts1_1,_} = erl_scan:string("'foo\nbar'", 1, [text]),
+ ?line {error,{2,_,["syntax error before: ",[]]}} = erl_parse:parse(Ts1_1),
+
+ ?line {ok,Ts2,_EndLocation} =
+ erl_scan:string("'foo\nbar'", {1,1}, []),
+ %% Can't do better than report possibly wrong line:
+ ?line {error,{1,_,["syntax error before: ",[]]}} = erl_parse:parse(Ts2),
+
+ ?line {ok, Ts11, _}=R1 = erl_scan:string("f() -> a."),
+ ?line F1 = fun() -> {ok,Ts11 ++ [{'$end',2}],2} end,
+ ?line{ok,{function,1,f,0,[{clause,1,[],[],[{atom,1,a}]}]}} =
+ erl_parse:parse_and_scan({F1, []}),
+ ?line F2 = fun() -> erl_scan:string("f() -> ,") end,
+ ?line {error,{1,erl_parse,_}} = erl_parse:parse_and_scan({F2, []}),
+ ?line F3 = fun() -> case erase(foo) of
+ bar ->
+ {ok,[{'$end',2}],3};
+ undefined ->
+ put(foo,bar), R1
+ end
+ end,
+ ?line {ok,{function,1,f,0,[{clause,1,[],[],[{atom,1,a}]}]}} =
+ erl_parse:parse_and_scan({F3,[]}),
+ F4 = fun() -> {error, {1, ?MODULE, bad}, 2} end,
+ ?line {error, {1,?MODULE,bad}} = erl_parse:parse_and_scan({F4, []}),
+ F5 = fun() -> {eof, 3} end,
+ ?line {error,{3,erl_parse,_}} = erl_parse:parse_and_scan({F5, []}),
+ ?line {error,{999999,erl_parse,_}} = erl_parse:parse([]),
+ ?line {ok, Ts21, EL} = erl_scan:string("f() -> a; g() -> b. ", {1,1}),
+ ?line F6 = fun() -> {ok, Ts21, EL} end,
+ ?line {error,{{1,11},erl_parse,_}} = erl_parse:parse_and_scan({F6, []}),
+ ok.
+
+yeccpre_size() ->
+ yeccpre_size(default_yeccpre()).
+
+yeccpre_size(File) ->
+ n_lines(File).
+
+default_yeccpre() ->
+ filename:join([code:lib_dir(parsetools),"include","yeccpre.hrl"]).
+
+n_lines(File) ->
+ {ok, Bin} = file:read_file(File),
+ length([C || C=$\n <- binary_to_list(Bin)]).
+
+run_test(Config, Def, Pre) ->
+ %% io:format("testing ~s~n", [binary_to_list(Def)]),
+ DefFile = 'yecc_test.yrl',
+ Filename = 'yecc_test.erl',
+ DataDir = ?privdir,
+ YrlFile = filename:join(DataDir, DefFile),
+ ErlFile = filename:join(DataDir, Filename),
+ Opts = [return, warn_unused_vars,{outdir,DataDir}],
+ ok = file:write_file(YrlFile, Def),
+ YOpts = [return, {report, false} |
+ case Pre of
+ default ->
+ [];
+ _ ->
+ [{includefile,Pre}]
+ end],
+ P0 = pps(),
+ YRet = yecc:file(YrlFile, [verbose | YOpts]),
+ case {pps(), YRet} of
+ {P0, {ok, _Outfile, _YWs}} ->
+ case compile:file(ErlFile, Opts) of
+ {ok, _M, _Ws} ->
+ AbsFile = filename:rootname(ErlFile, ".erl"),
+ Mod = yecc_test,
+ code:purge(Mod),
+ code:load_abs(AbsFile, Mod),
+ Mod:t();
+ %% warnings(ErlFile, Ws);
+ {error, [{ErlFile,Es}], []} -> {error, Es, []};
+ {error, [{ErlFile,Es}], [{ErlFile,Ws}]} -> {error, Es, Ws};
+ Error -> Error
+ end;
+ {P0, {error, [{YrlFile,YEs}], []}} -> {error, YEs, []};
+ {P0, {error, [{YrlFile,YEs}], [{YrlFile,YWs}]}} -> {error, YEs, YWs};
+ {P0, YError} -> YError;
+ {P, _} ->
+ io:format("failure, got ~p~n, expected ~p\n", [P, P0]),
+ fail()
+ end.
+
+extract(File, {error, Es, Ws}) ->
+ {errors, extract(File, Es), extract(File, Ws)};
+extract(File, Ts) ->
+ lists:append([T || {F, T} <- Ts, F =:= File]).
+
+pps() ->
+ {port_list(), process_list()}.
+
+port_list() ->
+ [{P,safe_second_element(erlang:port_info(P, name))} || P <- erlang:ports()].
+
+process_list() ->
+ [{P,process_info(P, registered_name),
+ safe_second_element(process_info(P, initial_call))} ||
+ P <- processes(), is_process_alive(P)].
+
+safe_second_element({_,Info}) -> Info;
+safe_second_element(Other) -> Other.
+
+fail() ->
+ ?t:fail().
diff --git a/lib/percept/doc/src/Makefile b/lib/percept/doc/src/Makefile
index c841d17c01..f0d43c5a01 100644
--- a/lib/percept/doc/src/Makefile
+++ b/lib/percept/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2007-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2007-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -153,10 +153,10 @@ gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
xml: $(MODULE_XML_FILES)
$(PERCEPT_XML_FILES):
- docb_gen $(PERCEPT_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(PERCEPT_DIR)/$(@:%.xml=%.erl)
$(RUNTIME_TOOLS_XML_FILES):
- docb_gen $(RUNTIME_TOOLS_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(RUNTIME_TOOLS_DIR)/$(@:%.xml=%.erl)
info:
@echo "XML_PART_FILES: $(XML_PART_FILES)"
diff --git a/lib/public_key/doc/src/Makefile b/lib/public_key/doc/src/Makefile
index 08d1396cca..298c28a740 100644
--- a/lib/public_key/doc/src/Makefile
+++ b/lib/public_key/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2008-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2008-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -56,6 +56,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES = note.gif
# ----------------------------------------------------
diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl
index 36b7c47a9c..c7d4080adb 100644
--- a/lib/public_key/src/pubkey_cert_records.erl
+++ b/lib/public_key/src/pubkey_cert_records.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -23,7 +23,7 @@
-include("public_key.hrl").
--export([decode_cert/2, encode_cert/1, encode_tbs_cert/1]).
+-export([decode_cert/2, encode_cert/1, encode_tbs_cert/1, transform/2]).
-export([old_decode_cert/2, old_encode_cert/1]). %% Debugging and testing new code.
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index b0b0b7a832..52c695523f 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -30,7 +30,7 @@
sign/2, sign/3,
verify_signature/3, verify_signature/4, verify_signature/5,
pem_to_der/1, pem_to_der/2,
- pkix_decode_cert/2, pkix_encode_cert/1,
+ pkix_decode_cert/2, pkix_encode_cert/1, pkix_transform/2,
pkix_is_self_signed/1, pkix_is_fixed_dh_cert/1,
pkix_issuer_id/2,
pkix_is_issuer/2, pkix_normalize_general_name/1,
@@ -162,6 +162,20 @@ pkix_encode_cert(Cert) ->
pubkey_cert_records:encode_cert(Cert).
%%--------------------------------------------------------------------
+%% Function: pkix_transform(CertPart, Op) -> TransformedCertPart
+%%
+%% CertPart = pkix part data
+%% Op = encode | decode
+%%
+%% Description: Transform parts of a pkix certificate between 'plain' format
+%% and the internal 'otp' format, see pkix_decode_cert/2.
+%% Decode transforms from 'plain' to 'otp' and encode from 'otp' to 'plain'
+%% format.
+%%--------------------------------------------------------------------
+pkix_transform(CertPart, Op) ->
+ pubkey_cert_records:transform(CertPart, Op).
+
+%%--------------------------------------------------------------------
%% Function: pkix_path_validation(TrustedCert, CertChain, Options) ->
%% {ok, {{algorithm(), public_key(), public_key_params()} policy_tree()}} |
%% {error, Reason}
diff --git a/lib/public_key/test/Makefile b/lib/public_key/test/Makefile
index 2a4687677c..c7215020c7 100644
--- a/lib/public_key/test/Makefile
+++ b/lib/public_key/test/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2008-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2008-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -21,7 +21,7 @@ include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
-INCLUDES= -I. -I$(ERL_TOP)/lib/test_server/include/ -I ../include \
+INCLUDES= -I. -I ../include
# ----------------------------------------------------
# Target Specs
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 93ae6e6eda..8cc36e490d 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -23,8 +23,9 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
--include("test_server_line.hrl").
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("test_server/include/test_server_line.hrl").
+
-include("public_key.hrl").
-define(TIMEOUT, 120000). % 2 min
diff --git a/lib/reltool/test/Makefile b/lib/reltool/test/Makefile
new file mode 100644
index 0000000000..00d2add3e5
--- /dev/null
+++ b/lib/reltool/test/Makefile
@@ -0,0 +1,82 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES= \
+ rtt \
+ reltool_wx_SUITE \
+ reltool_server_SUITE \
+ reltool_test_lib
+
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+HRL_FILES= reltool_test_lib.hrl
+
+TARGET_FILES= \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INSTALL_PROGS= $(TARGET_FILES)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/reltool_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+#ERL_COMPILE_FLAGS +=
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) reltool.spec $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_PROGRAM) rtt $(INSTALL_PROGS) $(RELSYSDIR)
+# chmod -f -R u+w $(RELSYSDIR)
+# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
+
+
diff --git a/lib/reltool/test/README b/lib/reltool/test/README
new file mode 100644
index 0000000000..031bd2c961
--- /dev/null
+++ b/lib/reltool/test/README
@@ -0,0 +1,30 @@
+
+Testing and running reltool tests.
+
+Testing gui api/applications can be hard, but we can at least
+test that wxerlang behaves as we expected, i.e. that the api
+is consistent and that it don't crash.
+
+The tests are structured as they are because we want you to
+be able to run them in three different ways.
+ - direct via an erlang shell
+ - via common_test application
+ - via erlang/OTP inhouse ts tool.
+
+To run all the tests compile them and on unix
+run ./rtt to create an erlang terminal.
+
+Invoke rtt:t(). in the erlang shell to run all regression tests.
+If you want to specific tests invoke rtt:t(Module)
+or rtt:t(Module, TestCase).
+
+To run all tests including the ones that require manual intervention run.
+rtt:t(all, [{user,true}]).
+
+To see every test_case window use
+rtt:t(all, [{user,step}]).
+This requires that you manually close each window to step to the
+next test_case.
+
+If you want to run specific test_cases use:
+rtt:t({Module,TestCase}, [{user,step}]).
diff --git a/lib/reltool/test/reltool.spec b/lib/reltool/test/reltool.spec
new file mode 100644
index 0000000000..252232e09d
--- /dev/null
+++ b/lib/reltool/test/reltool.spec
@@ -0,0 +1,2 @@
+{topcase, {dir, "../reltool_test"}}.
+
diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl
new file mode 100644
index 0000000000..cf951191a0
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE.erl
@@ -0,0 +1,494 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-module(reltool_server_SUITE).
+
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("reltool_test_lib.hrl").
+
+-define(NODE_NAME, '__RELTOOL__TEMPORARY_TEST__NODE__').
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Initialization functions.
+
+init_per_suite(Config) ->
+ reltool_test_lib:init_per_suite(Config).
+
+end_per_suite(Config) ->
+ reltool_test_lib:end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ reltool_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ reltool_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ reltool_test_lib:end_per_testcase(Func,Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% SUITE specification
+
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ start_server,
+ set_config,
+ create_release,
+ create_script,
+ create_target,
+ create_embedded,
+ create_standalone,
+ create_old_target
+ ].
+
+%% The test cases
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Start a server process and check that it does not crash
+
+start_server(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+start_server(_Config) ->
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([])),
+ Libs = lists:sort(erl_libs()),
+ StrippedDefault =
+ case Libs of
+ [] -> {sys, []};
+ _ -> {sys, [{lib_dirs, Libs}]}
+ end,
+ ?m({ok, StrippedDefault}, reltool:get_config(Pid)),
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Start a server process and check that it does not crash
+
+set_config(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+set_config(_Config) ->
+ Libs = lists:sort(erl_libs()),
+ Default =
+ {sys,
+ [
+ {mod_cond, all},
+ {incl_cond, derived},
+ {root_dir, code:root_dir()},
+ {lib_dirs, Libs}
+ ]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Default}])),
+ StrippedDefault =
+ case Libs of
+ [] -> {sys, []};
+ _ -> {sys, [{lib_dirs, Libs}]}
+ end,
+ ?m({ok, StrippedDefault}, reltool:get_config(Pid)),
+
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate releases
+
+create_release(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_release(_Config) ->
+ %% Configure the server
+ RelName = "Just testing...",
+ RelVsn = "1.0",
+ Config =
+ {sys,
+ [
+ {lib_dirs, []},
+ {boot_rel, RelName},
+ {rel, RelName, RelVsn, [kernel, stdlib]}
+ ]},
+ %% Generate release
+ ErtsVsn = erlang:system_info(version),
+ Apps = application:loaded_applications(),
+ {value, {_, _, KernelVsn}} = lists:keysearch(kernel, 1, Apps),
+ {value, {_, _, StdlibVsn}} = lists:keysearch(stdlib, 1, Apps),
+ Rel = {release, {RelName, RelVsn},
+ {erts, ErtsVsn},
+ [{kernel, KernelVsn},
+ {stdlib, StdlibVsn}]},
+ ?m({ok, Rel}, reltool:get_rel([{config, Config}], RelName)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate boot scripts
+
+create_script(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_script(_Config) ->
+ %% Configure the server
+ RelName = "Just testing",
+ RelVsn = "1.0",
+ Config =
+ {sys,
+ [
+ {lib_dirs, []},
+ {boot_rel, RelName},
+ {rel, RelName, RelVsn, [stdlib, kernel]}
+ ]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Config}])),
+
+ %% Generate release file
+ ErtsVsn = erlang:system_info(version),
+ Apps = application:loaded_applications(),
+ {value, {_, _, KernelVsn}} = lists:keysearch(kernel, 1, Apps),
+ {value, {_, _, StdlibVsn}} = lists:keysearch(stdlib, 1, Apps),
+ Rel = {release,
+ {RelName, RelVsn},
+ {erts, ErtsVsn},
+ [{stdlib, StdlibVsn}, {kernel, KernelVsn}]},
+ ?m({ok, Rel}, reltool:get_rel(Pid, RelName)),
+ RelFile = RelName ++ ".rel",
+ ?m(ok, file:write_file(RelFile, io_lib:format("~p.\n", [Rel]))),
+
+ %% Generate script file
+ ?m(ok, systools:make_script(RelName, [])),
+ ScriptFile = RelName ++ ".script",
+ {ok, [OrigScript]} = ?msym({ok, [_]}, file:consult(ScriptFile)),
+ {ok, Script} = ?msym({ok, _}, reltool:get_script(Pid, RelName)),
+ %% OrigScript2 = sort_script(OrigScript),
+ %% Script2 = sort_script(Script),
+ %% ?m(OrigScript2, Script2),
+
+ ?m(equal, diff_script(OrigScript, Script)),
+
+ %% Stop server
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate target system
+
+create_target(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_target(_Config) ->
+ %% Configure the server
+ RelName1 = "Just testing",
+ RelName2 = "Just testing with SASL",
+ RelVsn = "1.0",
+ Config =
+ {sys,
+ [
+ {root_dir, code:root_dir()},
+ {lib_dirs, []},
+ {boot_rel, RelName2},
+ {rel, RelName1, RelVsn, [stdlib, kernel]},
+ {rel, RelName2, RelVsn, [sasl, stdlib, kernel]},
+ {app, sasl, [{incl_cond, include}]}
+ ]},
+
+ %% Generate target file
+ TargetDir = "reltool_target_dir_development",
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?m(ok, reltool:create_target([{config, Config}], TargetDir)),
+
+ Erl = filename:join([TargetDir, "bin", "erl"]),
+ {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)),
+ ?msym(ok, stop_node(Node)),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate embedded target system
+
+create_embedded(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_embedded(_Config) ->
+ %% Configure the server
+ RelName1 = "Just testing",
+ RelName2 = "Just testing with SASL",
+ RelVsn = "1.0",
+ Config =
+ {sys,
+ [
+ {lib_dirs, []},
+ {profile, embedded},
+ {boot_rel, RelName2},
+ {rel, RelName1, RelVsn, [stdlib, kernel]},
+ {rel, RelName2, RelVsn, [sasl, stdlib, kernel]},
+ {app, sasl, [{incl_cond, include}]}
+ ]},
+
+ %% Generate target file
+ TargetDir = "reltool_target_dir_embedded",
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?m(ok, reltool:create_target([{config, Config}], TargetDir)),
+
+ Erl = filename:join([TargetDir, "bin", "erl"]),
+ {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)),
+ ?msym(ok, stop_node(Node)),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate standalone system
+
+create_standalone(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_standalone(_Config) ->
+ %% Configure the server
+ ExDir = code:lib_dir(reltool, examples),
+ EscriptName = "display_args",
+ Escript = filename:join([ExDir, EscriptName]),
+ Config =
+ {sys,
+ [
+ {lib_dirs, []},
+ {escript, Escript, [{incl_cond, include}]},
+ {profile, standalone}
+ ]},
+
+ %% Generate target file
+ TargetDir = "reltool_target_dir_standalone",
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?m(ok, reltool:create_target([{config, Config}], TargetDir)),
+
+ BinDir = filename:join([TargetDir, "bin"]),
+ Erl = filename:join([BinDir, "erl"]),
+ {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)),
+ RootDir = ?ignore(rpc:call(Node, code, root_dir, [])),
+ ?msym(ok, stop_node(Node)),
+
+ Expected = iolist_to_binary(["Root dir: ", RootDir, "\n"
+ "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
+ "Smp: false\n",
+ "ExitCode:0"]),
+ io:format("Expected: ~s\n", [Expected]),
+ ?m(Expected, run(BinDir, EscriptName ++ " -arg1 arg2 arg3")),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate old type of target system
+
+create_old_target(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_old_target(_Config) ->
+ %% Configure the server
+ RelName1 = "Just testing",
+ RelName2 = "Just testing with SASL",
+ RelVsn = "1.0",
+ Config =
+ {sys,
+ [
+ {lib_dirs, []},
+ {boot_rel, RelName2},
+ {rel, RelName1, RelVsn, [stdlib, kernel]},
+ {rel, RelName2, RelVsn, [sasl, stdlib, kernel]},
+ {relocatable, false}, % Implies explicit old style installation
+ {app, sasl, [{incl_cond, include}]}
+ ]},
+
+ %% Generate target file
+ TargetDir = "reltool_target_dir_old",
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?m(ok, reltool:create_target([{config, Config}], TargetDir)),
+
+ %% io:format("Will fail on Windows (should patch erl.ini)\n", []),
+ ?m(ok, reltool:install(RelName2, TargetDir)),
+
+ Erl = filename:join([TargetDir, "bin", "erl"]),
+ {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)),
+ ?msym(ok, stop_node(Node)),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Library functions
+
+erl_libs() ->
+ case os:getenv("ERL_LIBS") of
+ false -> [];
+ LibStr -> string:tokens(LibStr, ":;")
+ end.
+
+diff_script(Script, Script) ->
+ equal;
+diff_script({script, Rel, Commands1}, {script, Rel, Commands2}) ->
+ diff_cmds(Commands1, Commands2);
+diff_script({script, Rel1, _}, {script, Rel2, _}) ->
+ {error, {Rel1, Rel2}}.
+
+diff_cmds([Cmd | Commands1], [Cmd | Commands2]) ->
+ diff_cmds(Commands1, Commands2);
+diff_cmds([Cmd1 | _Commands1], [Cmd2 | _Commands2]) ->
+ {diff, {expected, Cmd1}, {actual, Cmd2}};
+diff_cmds([], []) ->
+ equal.
+
+os_cmd(Cmd) when is_list(Cmd) ->
+ %% Call the plain os:cmd with an echo command appended to print command status
+ %% io:format("os:cmd(~p).\n", [Cmd]),
+ case os:cmd(Cmd++";echo \"#$?\"") of
+ %% There is (as far as I can tell) only one thing that will match this
+ %% and that is too silly to ever be used, but...
+ []->
+ {99, []};
+ Return->
+ %% Find the position of the status code wich is last in the string
+ %% prepended with #
+ case string:rchr(Return, $#) of
+
+ %% This happens only if the sh command pipe is somehow interrupted
+ 0->
+ {98, Return};
+
+ Position->
+ Result = string:left(Return,Position - 1),
+ Status = string:substr(Return,Position + 1, length(Return) - Position - 1),
+ {list_to_integer(Status), Result}
+ end
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Node handling
+
+start_node(Name, ErlPath) ->
+ FullName = full_node_name(Name),
+ CmdLine = mk_node_cmdline(Name, ErlPath),
+ io:format("Starting node ~p: ~s~n", [FullName, CmdLine]),
+ case open_port({spawn, CmdLine}, []) of
+ Port when is_port(Port) ->
+ unlink(Port),
+ erlang:port_close(Port),
+ case ping_node(FullName, 50) of
+ ok -> {ok, FullName};
+ Other -> exit({failed_to_start_node, FullName, Other})
+ end;
+ Error ->
+ exit({failed_to_start_node, FullName, Error})
+ end.
+
+stop_node(Node) ->
+ monitor_node(Node, true),
+ spawn(Node, fun () -> halt() end),
+ receive {nodedown, Node} -> ok end.
+
+mk_node_cmdline(Name) ->
+ Prog = case catch init:get_argument(progname) of
+ {ok,[[P]]} -> P;
+ _ -> exit(no_progname_argument_found)
+ end,
+ mk_node_cmdline(Name, Prog).
+
+mk_node_cmdline(Name, Prog) ->
+ Static = "-detached -noinput",
+ Pa = filename:dirname(code:which(?MODULE)),
+ NameSw = case net_kernel:longnames() of
+ false -> "-sname ";
+ true -> "-name ";
+ _ -> exit(not_distributed_node)
+ end,
+ {ok, Pwd} = file:get_cwd(),
+ NameStr = atom_to_list(Name),
+ Prog ++ " "
+ ++ Static ++ " "
+ ++ NameSw ++ " " ++ NameStr ++ " "
+ ++ "-pa " ++ Pa ++ " "
+ ++ "-env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ NameStr ++ " "
+ ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()).
+
+full_node_name(PreName) ->
+ HostSuffix = lists:dropwhile(fun ($@) -> false; (_) -> true end,
+ atom_to_list(node())),
+ list_to_atom(atom_to_list(PreName) ++ HostSuffix).
+
+ping_node(_Node, 0) ->
+ {error, net_adm};
+ping_node(Node, N) when is_integer(N), N > 0 ->
+ case catch net_adm:ping(Node) of
+ pong ->
+ wait_for_process(Node, code_server, 50);
+ _ ->
+ timer:sleep(1000),
+ ping_node(Node, N-1)
+ end.
+
+wait_for_process(_Node, Name, 0) ->
+ {error, Name};
+wait_for_process(Node, Name, N) when is_integer(N), N > 0 ->
+ case rpc:call(Node, erlang, whereis, [Name]) of
+ undefined ->
+ timer:sleep(1000),
+ wait_for_process(Node, Name, N-1);
+ {badrpc, _} = Reason ->
+ erlang:error({Reason, Node});
+ Pid when is_pid(Pid) ->
+ ok
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Run escript
+
+run(Dir, Cmd0) ->
+ Cmd = case os:type() of
+ {win32,_} -> filename:nativename(Dir) ++ "\\" ++ Cmd0;
+ _ -> Cmd0
+ end,
+ do_run(Dir, Cmd).
+
+run(Dir, Opts, Cmd0) ->
+ Cmd = case os:type() of
+ {win32,_} -> Opts ++ " " ++ filename:nativename(Dir) ++ "\\" ++ Cmd0;
+ _ -> Opts ++ " " ++ Dir ++ "/" ++ Cmd0
+ end,
+ do_run(Dir, Cmd).
+
+do_run(Dir, Cmd) ->
+ io:format("Run: ~p\n", [Cmd]),
+ Env = [{"PATH",Dir++":"++os:getenv("PATH")}],
+ Port = open_port({spawn,Cmd}, [exit_status,eof,in,{env,Env}]),
+ Res = get_data(Port, []),
+ receive
+ {Port,{exit_status,ExitCode}} ->
+ iolist_to_binary([Res,"ExitCode:"++integer_to_list(ExitCode)])
+ end.
+
+get_data(Port, SoFar) ->
+ receive
+ {Port,{data,Bytes}} ->
+ get_data(Port, [SoFar|Bytes]);
+ {Port,eof} ->
+ erlang:port_close(Port),
+ SoFar
+ end.
+
+expected_output([data_dir|T], Data) ->
+ Slash = case os:type() of
+ {win32,_} -> "\\";
+ _ -> "/"
+ end,
+ [filename:nativename(Data)++Slash|expected_output(T, Data)];
+expected_output([H|T], Data) ->
+ [H|expected_output(T, Data)];
+expected_output([], _) ->
+ [];
+expected_output(Bin, _) when is_binary(Bin) ->
+ Bin.
diff --git a/lib/reltool/test/reltool_test_lib.erl b/lib/reltool/test/reltool_test_lib.erl
new file mode 100644
index 0000000000..25978294ee
--- /dev/null
+++ b/lib/reltool/test/reltool_test_lib.erl
@@ -0,0 +1,329 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-module(reltool_test_lib).
+-compile(export_all).
+
+-include("reltool_test_lib.hrl").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_suite(Config) when is_list(Config)->
+ incr_timetrap(Config, 5).
+
+end_per_suite(Config) when is_list(Config)->
+ ok.
+
+incr_timetrap(Config, Times) ->
+ Key = tc_timeout,
+ KeyPos = 1,
+ NewTime =
+ case lists:keysearch(Key, KeyPos, Config) of
+ {value, {Key, OldTime}} ->
+ (timer:minutes(1) + OldTime) * Times;
+ false ->
+ timer:minutes(1) * Times
+ end,
+ lists:keystore(Key, KeyPos, Config, {Key, NewTime}).
+
+set_kill_timer(Config) ->
+ case init:get_argument(reltool_test_timeout) of
+ {ok, _} ->
+ Config;
+ _ ->
+ Time =
+ case lookup_config(tc_timeout, Config) of
+ [] ->
+ timer:minutes(5);
+ ConfigTime when is_integer(ConfigTime) ->
+ ConfigTime
+ end,
+ WatchDog = test_server:timetrap(Time),
+ [{kill_timer, WatchDog} | Config]
+ end.
+
+reset_kill_timer(Config) ->
+ DogKiller =
+ case get(reltool_test_server) of
+ true ->
+ fun(P) when is_pid(P) -> P ! stop;
+ (_) -> ok
+ end;
+ _ ->
+ fun(Ref) -> test_server:timetrap_cancel(Ref) end
+ end,
+ case lists:keysearch(kill_timer, 1, Config) of
+ {value, {kill_timer, WatchDog}} ->
+ DogKiller(WatchDog),
+ lists:keydelete(kill_timer, 1, Config);
+ _ ->
+ Config
+ end.
+
+lookup_config(Key,Config) ->
+ case lists:keysearch(Key, 1, Config) of
+ {value,{Key,Val}} ->
+ Val;
+ _ ->
+ []
+ end.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+wx_init_per_suite(Config) ->
+ {_Pid, Ref} =
+ spawn_monitor(fun() ->
+ %% Avoid test case crash if wx master process dies
+ process_flag(trap_exit, true),
+ try
+ case os:type() of
+ {unix,darwin} ->
+ exit({skipped, "Can not test on MacOSX"});
+ {unix, _} ->
+ io:format("DISPLAY ~s~n", [os:getenv("DISPLAY")]),
+ case proplists:get_value(xserver, Config, none) of
+ none -> ignore;
+ Server -> os:putenv("DISPLAY", Server)
+ end;
+ _ ->
+ ignore
+ end,
+ wx:new(),
+ wx:destroy()
+ catch
+ error:undef ->
+ exit({skipped, "No wx compiled for this platform"});
+ _:Reason ->
+ exit({skipped, lists:flatten(io_lib:format("Start wx failed: ~p", [Reason]))})
+ end,
+ exit(normal)
+ end),
+ receive
+ {'DOWN', Ref, _, _, normal} ->
+ init_per_suite(Config);
+ {'DOWN', Ref, _, _, {skipped, _} = Skipped} ->
+ Skipped;
+ {'DOWN', Ref, _, _, Reason} ->
+ exit({wx_init_per_suite, Reason})
+ after timer:minutes(1) ->
+ exit({wx_init_per_suite, timeout})
+ end.
+
+wx_end_per_suite(Config) ->
+ end_per_suite(Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_testcase(_Func, Config) when is_list(Config) ->
+ set_kill_timer(Config),
+ global:register_name(reltool_global_logger, group_leader()),
+ Config.
+
+end_per_testcase(_Func, Config) when is_list(Config) ->
+ global:unregister_name(reltool_global_logger),
+ reset_kill_timer(Config),
+ Config.
+
+%% Backwards compatible with test_server
+tc_info(suite) -> [];
+tc_info(doc) -> "".
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Use ?log(Format, Args) as wrapper
+log(Format, Args, LongFile, Line) ->
+ File = filename:basename(LongFile),
+ Format2 = lists:concat([File, "(", Line, ")", ": ", Format]),
+ log(Format2, Args).
+
+log(Format, Args) ->
+ case global:whereis_name(reltool_global_logger) of
+ undefined ->
+ io:format(user, Format, Args);
+ Pid ->
+ io:format(Pid, Format, Args)
+ end.
+
+verbose(Format, Args, File, Line) ->
+ Arg = reltool_test_verbose,
+ case get(Arg) of
+ false ->
+ ok;
+ true ->
+ log(Format, Args, File, Line);
+ undefined ->
+ case init:get_argument(Arg) of
+ {ok, List} when is_list(List) ->
+ case lists:last(List) of
+ ["true"] ->
+ put(Arg, true),
+ log(Format, Args, File, Line);
+ _ ->
+ put(Arg, false),
+ ok
+ end;
+ _ ->
+ put(Arg, false),
+ ok
+ end
+ end.
+
+error(Format, Args, File, Line) ->
+ global:send(reltool_global_logger, {failed, File, Line}),
+ Fail = {filename:basename(File),Line,Args},
+ case global:whereis_name(reltool_test_case_sup) of
+ undefined -> ignore;
+ Pid -> Pid ! Fail
+ %% global:send(reltool_test_case_sup, Fail),
+ end,
+ log("<ERROR>~n" ++ Format, Args, File, Line).
+
+
+pick_msg() ->
+ receive
+ Message -> Message
+ after 4000 -> timeout
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Utility functions
+
+user_available(Config) ->
+ false /= proplists:get_value(user, Config, false).
+
+
+wx_destroy(Frame, Config) ->
+ case proplists:get_value(user, Config, false) of
+ false ->
+ timer:sleep(100),
+ ?m(ok, wxFrame:destroy(Frame)),
+ ?m(ok, wx:destroy());
+ true ->
+ timer:sleep(500),
+ ?m(ok, wxFrame:destroy(Frame)),
+ ?m(ok, wx:destroy());
+ step -> %% Wait for user to close window
+ ?m(ok, wxEvtHandler:connect(Frame, close_window, [{skip,true}])),
+ wait_for_close()
+ end.
+
+wait_for_close() ->
+ receive
+ #wx{event=#wxClose{}} ->
+ ?log("Got close~n",[]),
+ ?m(ok, wx:destroy());
+ #wx{obj=Obj, event=Event} ->
+ try
+ Name = wxTopLevelWindow:getTitle(Obj),
+ ?log("~p Event: ~p~n", [Name, Event])
+ catch _:_ ->
+ ?log("Event: ~p~n", [Event])
+ end,
+ wait_for_close();
+ Other ->
+ ?log("Unexpected: ~p~n", [Other]),
+ wait_for_close()
+ end.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% A small test server, which can be run standalone in a shell
+
+run_test(Test = {_,_},Config) ->
+ run_test([Test],Config);
+run_test([{Module, TC} | Rest], Config) ->
+ log("\n\n=== Eval test suite: ~w ===~n", [Module]),
+ case catch Module:init_per_suite(Config) of
+ {skipped, Reason} ->
+ log("Test suite skipped: ~s~n", [Reason]),
+ [{skipped, Reason}];
+ NewConfig when is_list(NewConfig) ->
+ Res =
+ if
+ TC =:= all ->
+ [do_run_test(Module, Test, NewConfig) || Test <- Module:all()];
+ is_list(TC) ->
+ [do_run_test(Module, Test, NewConfig) || Test <- TC];
+ true ->
+ [do_run_test(Module, TC, NewConfig)]
+ end,
+ Module:end_per_suite(NewConfig),
+ Res ++ run_test(Rest, NewConfig);
+ Error ->
+ ?error("Test suite skipped: ~w~n", [Error]),
+ [{skipped, Error}]
+ end;
+run_test([], _Config) ->
+ [].
+
+do_run_test(Module, all, Config) ->
+ All = [{Module, Test} || Test <- Module:all()],
+ run_test(All, Config);
+do_run_test(Module, TestCase, Config) ->
+ log("Eval test case: ~w~n", [{Module, TestCase}]),
+ Sec = timer:seconds(1) * 1000,
+ {T, Res} =
+ timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]),
+ log("Tested ~w in ~w sec~n", [TestCase, T div Sec]),
+ {T div Sec, Res}.
+
+eval_test_case(Mod, Fun, Config) ->
+ flush(),
+ global:register_name(reltool_test_case_sup, self()),
+ Flag = process_flag(trap_exit, true),
+ Pid = spawn_link(?MODULE, test_case_evaluator, [Mod, Fun, [Config]]),
+ R = wait_for_evaluator(Pid, Mod, Fun, Config),
+ global:unregister_name(reltool_test_case_sup),
+ process_flag(trap_exit, Flag),
+ R.
+
+test_case_evaluator(Mod, Fun, [Config]) ->
+ NewConfig = Mod:init_per_testcase(Fun, Config),
+ R = apply(Mod, Fun, [NewConfig]),
+ Mod:fin_per_testcase(Fun, NewConfig),
+ exit({test_case_ok, R}).
+
+wait_for_evaluator(Pid, Mod, Fun, Config) ->
+ receive
+ {'EXIT', Pid, {test_case_ok, _PidRes}} ->
+ Errors = flush(),
+ Res =
+ case Errors of
+ [] -> ok;
+ Errors -> failed
+ end,
+ {Res, {Mod, Fun}, Errors};
+ {'EXIT', Pid, {skipped, Reason}} ->
+ log("<WARNING> Test case ~w skipped, because ~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {skip, {Mod, Fun}, Reason};
+ {'EXIT', Pid, Reason} ->
+ log("<ERROR> Eval process ~w exited, because\n\t~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {crash, {Mod, Fun}, Reason}
+ end.
+
+flush() ->
+ receive Msg -> [Msg | flush()]
+ after 0 -> []
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/reltool/test/reltool_test_lib.hrl b/lib/reltool/test/reltool_test_lib.hrl
new file mode 100644
index 0000000000..93134144ea
--- /dev/null
+++ b/lib/reltool/test/reltool_test_lib.hrl
@@ -0,0 +1,91 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-include_lib("wx/include/wx.hrl").
+
+-define(log(Format,Args), reltool_test_lib:log(Format,Args,?FILE,?LINE)).
+-define(warning(Format,Args), ?log("<WARNING>\n " ++ Format,Args)).
+-define(error(Format,Args), reltool_test_lib:error(Format,Args,?FILE,?LINE)).
+-define(verbose(Format,Args), reltool_test_lib:verbose(Format,Args,?FILE,?LINE)).
+
+-define(fatal(Format,Args),
+ ?error(Format, Args),
+ exit({test_case_fatal, Format, Args, ?FILE, ?LINE})).
+
+-define(skip(Format,Args),
+ ?warning(Format, Args),
+ exit({skipped, ?flat_format(Format, Args)})).
+
+-define(ignore(Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS
+ end()).
+
+-define(msym(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ reltool_test_lib:error("Not matching actual result was:\n ~p \nExpected ~s\n",
+ [AcTuAlReS, ??ExpectedRes],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
+
+-define(m(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ reltool_test_lib:error("Not matching actual result was:\n\t~p \nExpected:\n\t~p\n",
+ [AcTuAlReS, ExpectedRes],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
+
+-define(m_receive(ExpectedMsg),
+ ?m(ExpectedMsg,reltool_test_lib:pick_msg())).
+
+-define(m_multi_receive(ExpectedMsgs),
+ fun() ->
+ TmPeXpCtEdMsGs = lists:sort(ExpectedMsgs),
+ AcTuAlReS =
+ lists:sort(lists:map(fun(_) ->
+ reltool_test_lib:pick_msg()
+ end, TmPeXpCtEdMsGs)),
+ case AcTuAlReS of
+ TmPeXpCtEdMsGs ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ reltool_test_lib:error("Not matching actual result was:\n ~p \nExpected ~p\n",
+ [AcTuAlReS, ExpectedMsgs],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
diff --git a/lib/reltool/test/reltool_wx_SUITE.erl b/lib/reltool/test/reltool_wx_SUITE.erl
new file mode 100644
index 0000000000..2e2b355e07
--- /dev/null
+++ b/lib/reltool/test/reltool_wx_SUITE.erl
@@ -0,0 +1,62 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-module(reltool_wx_SUITE).
+
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("reltool_test_lib.hrl").
+
+%% Initialization functions.
+init_per_suite(Config) ->
+ reltool_test_lib:wx_init_per_suite(Config).
+
+end_per_suite(Config) ->
+ reltool_test_lib:wx_end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ reltool_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ reltool_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ reltool_test_lib:end_per_testcase(Func,Config).
+
+%% SUITE specification
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ start_all_windows
+ ].
+
+%% The test cases
+
+%% Display all windows and see if something crashes
+start_all_windows(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+start_all_windows(_Config) ->
+ {ok, SysPid} = ?msym({ok, _}, reltool:start([{trap_exit, false}])),
+ {ok, AppPid} = ?msym({ok, _}, reltool_sys_win:open_app(SysPid, stdlib)),
+ ?msym({ok, _}, reltool_app_win:open_mod(AppPid, escript)),
+ timer:sleep(timer:seconds(10)),
+ ?m(ok, reltool:stop(SysPid)),
+
+ ok.
diff --git a/lib/reltool/test/rtt b/lib/reltool/test/rtt
new file mode 100755
index 0000000000..2411195338
--- /dev/null
+++ b/lib/reltool/test/rtt
@@ -0,0 +1,55 @@
+#! /bin/sh -f
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+# Usage: rtt [-cerl] <args to erlang startup script>
+
+emu=erl
+while [ $# -gt 0 ]; do
+ case "$1" in
+ "-cerl")
+ shift
+ emu=cerl
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+log=test_log_$$
+latest=test_log_latest
+args=${1+"$@"}
+
+erlcmd="$emu -sname test_server -smp -pa ../../reltool/ebin $p $args -reltool_test_verbose true -reltool_test_timeout"
+
+echo "Give the following command in order to see the outcome:"
+echo ""
+echo " less $log"
+
+rm "$latest" 2>/dev/null
+ln -s "$log" "$latest"
+touch "$log"
+
+ostype=`uname -s`
+if [ "$ostype" = "SunOS" ] ; then
+ /usr/openwin/bin/xterm -T "Testing reltool" -l -lf "$log" -e $erlcmd &
+else
+ xterm -T "Testing reltool" -e script -f -c "$erlcmd" "$log" &
+fi
+
+tail -f "$log" | egrep 'Eval|<ERROR>|NYI'
diff --git a/lib/reltool/test/rtt.erl b/lib/reltool/test/rtt.erl
new file mode 100644
index 0000000000..6755b8400f
--- /dev/null
+++ b/lib/reltool/test/rtt.erl
@@ -0,0 +1,154 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-module(rtt).
+-compile(export_all).
+
+%% Modules or suites can be shortcuts, for example server expands to reltool_server_SUITE.
+%%
+%% t(Tests) run reltool testcases.
+%% Tests can be module, {module, test_case} or [module|{module,test_case}]
+
+t() ->
+ t(read_test_case()).
+t(Test) ->
+ t(Test, []).
+
+t(Mod, TC) when is_atom(Mod), is_atom(TC) ->
+ t({Mod,TC}, []);
+t(all, Config) when is_list(Config) ->
+ Fs = filelib:wildcard("reltool_*_SUITE.erl"),
+ t([list_to_atom(filename:rootname(File)) || File <- Fs], Config);
+t(Test,Config) when is_list(Config) ->
+ Tests = resolve(Test),
+ write_test_case(Test),
+ Res = reltool_test_lib:run_test(Tests, Config),
+ append_test_case_info(Test, Res).
+
+user() ->
+ user(read_test_case()).
+user(Mod) ->
+ t(Mod, [{user,step}]).
+user(Mod,Tc) when is_atom(Tc) ->
+ t({Mod,Tc}, [{user,step}]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Resolves the name of test suites and test cases
+%% according to the alias definitions. Single atoms
+%% are assumed to be the name of a test suite.
+
+resolve(Suite0) when is_atom(Suite0) ->
+ case alias(Suite0) of
+ Suite when is_atom(Suite) ->
+ {Suite, all};
+ {Suite, Case} ->
+ {Suite, Case}
+ end;
+resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) ->
+ case alias(Suite0) of
+ Suite when is_atom(Suite) ->
+ {Suite, Case};
+ {Suite, Case2} ->
+ {Suite, Case2}
+ end;
+resolve(List) when is_list(List) ->
+ [resolve(Case) || Case <- List].
+
+alias(Suite) when is_atom(Suite) ->
+ Str = atom_to_list(Suite),
+ case {Str, lists:reverse(Str)} of
+ {"reltool" ++ _, "ETIUS" ++ _} ->
+ Suite;
+ _ ->
+ list_to_atom("reltool_" ++ Str ++ "_SUITE")
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+config_fname() ->
+ "reltool_test_case_config".
+
+%% Read default config file
+read_config() ->
+ Fname = config_fname(),
+ reltool_test_lib:log("Consulting file ~s...~n", [Fname]),
+ case file:consult(Fname) of
+ {ok, Config} ->
+ reltool_test_lib:log("Read config ~w~n", [Config]),
+ Config;
+ _Error ->
+ Config = reltool_test_lib:default_config(),
+ reltool_test_lib:log("<>WARNING<> Using default config: ~w~n", [Config]),
+ Config
+ end.
+
+%% Write new default config file
+write_config(Config) when is_list(Config) ->
+ Fname = config_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ write_list(Fd, Config),
+ file:close(Fd).
+
+write_list(Fd, [H | T]) ->
+ ok = io:format(Fd, "~p.~n",[H]),
+ write_list(Fd, T);
+write_list(_, []) ->
+ ok.
+
+test_case_fname() ->
+ "reltool_test_case_info".
+
+%% Read name of test case
+read_test_case() ->
+ Fname = test_case_fname(),
+ case file:open(Fname, [read]) of
+ {ok, Fd} ->
+ Res = io:read(Fd, []),
+ file:close(Fd),
+ case Res of
+ {ok, TestCase} ->
+ reltool_test_lib:log("Using test case ~w from file ~s~n",
+ [TestCase, Fname]),
+ TestCase;
+ {error, _} ->
+ default_test_case(Fname)
+ end;
+ {error, _} ->
+ default_test_case(Fname)
+ end.
+
+default_test_case(Fname) ->
+ TestCase = all,
+ reltool_test_lib:log("<>WARNING<> Cannot read file ~s, "
+ "using default test case: ~w~n",
+ [Fname, TestCase]),
+ TestCase.
+
+write_test_case(TestCase) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ file:close(Fd).
+
+append_test_case_info(TestCase, TestCaseInfo) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, [read, write]),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ ok = io:format(Fd, "~p.~n",[TestCaseInfo]),
+ file:close(Fd),
+ TestCaseInfo.
diff --git a/lib/ssh/doc/src/Makefile b/lib/ssh/doc/src/Makefile
index e02f04e7ad..c4d8d9901c 100644
--- a/lib/ssh/doc/src/Makefile
+++ b/lib/ssh/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -58,6 +58,9 @@ XML_CHAPTER_FILES = notes.xml
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
# ----------------------------------------------------
HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index ef49bb8b3d..9597137cdf 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>SSH Release Notes</title>
@@ -31,6 +31,17 @@
<section><title>Ssh 1.1.8</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ In some cases SSH ceased to collect more data from the transport layer.</p>
+ <p>
+ Own Id: OTP-8401 Aux Id: seq11479</p>
+ </item>
+ </list>
+ </section>
+
<section><title>Improvements and New Features</title>
<list>
<item>
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index 3bf772b42b..5329373862 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -1,24 +1,25 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
{"%VSN%",
[
+ {"1.1.7", [{load_module, ssh_connection_handler, soft_purge, soft_purge, []}]},
{"1.1.6", [{restart_application, ssh}]},
{"1.1.5", [{restart_application, ssh}]},
{"1.1.4", [{restart_application, ssh}]},
@@ -26,6 +27,7 @@
{"1.1.2", [{restart_application, ssh}]}
],
[
+ {"1.1.7", [{load_module, ssh_connection_handler, soft_purge, soft_purge, []}]},
{"1.1.6", [{restart_application, ssh}]},
{"1.1.5", [{restart_application, ssh}]},
{"1.1.4", [{restart_application, ssh}]},
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 5240b4b4c5..822ef8f8f9 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -530,6 +530,7 @@ handle_info({Protocol, Socket, Data}, Statename,
case size(EncData0) + size(Data) >= max(8, BlockSize) of
true ->
{Ssh, SshPacketLen, DecData, EncData} =
+
ssh_transport:decrypt_first_block(<<EncData0/binary,
Data/binary>>, Ssh0),
case SshPacketLen > ?SSH_MAX_PACKET_SIZE of
@@ -737,7 +738,8 @@ next_packet(#state{decoded_data_buffer = <<>>,
State) when Buff =/= <<>> andalso size(Buff) >= 8 ->
%% More data from the next packet has been received
%% Fake a socket-recive message so that the data will be processed
- self() ! {Protocol, Socket, <<>>} ,
+ inet:setopts(Socket, [{active, once}]),
+ self() ! {Protocol, Socket, <<>>},
State;
next_packet(#state{socket = Socket} = State) ->
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 2b9df4ae60..bc7bceeb24 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -3,7 +3,8 @@
SSH_VSN = 1.1.8
APP_VSN = "ssh-$(SSH_VSN)"
-TICKETS = OTP-8356
+TICKETS = OTP-8356 \
+ OTP-8401
TICKETS_1.1.7 = OTP-8121 \
OTP-8277 \
diff --git a/lib/ssl/doc/src/Makefile b/lib/ssl/doc/src/Makefile
index 54d274ef83..fa263d28ab 100644
--- a/lib/ssl/doc/src/Makefile
+++ b/lib/ssl/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -52,6 +52,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES = warning.gif
PS_FILES =
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 178c055cdf..d9377fe3d6 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -1115,13 +1115,12 @@ do_server_hello(Type, #state{negotiated_version = Version,
case ssl_handshake:master_secret(Version, Session,
ConnectionStates0, server) of
{_, ConnectionStates1} ->
- {ConnectionStates, Hashes} =
- finished(State#state{connection_states =
- ConnectionStates1}),
- {next_state, abbreviated,
- next_record(State#state{connection_states =
- ConnectionStates,
- tls_handshake_hashes = Hashes})};
+ State1 = State#state{connection_states=ConnectionStates1,
+ session = Session},
+ {ConnectionStates, Hashes} = finalize_server_handshake(State1),
+ Resumed = State1#state{connection_states = ConnectionStates,
+ tls_handshake_hashes = Hashes},
+ {next_state, abbreviated, next_record(Resumed)};
#alert{} = Alert ->
handle_own_alert(Alert, Version, hello, State),
{stop, normal, State}
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 829e0c2ba6..8c598135ca 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -860,9 +860,31 @@ certificate_types(_) ->
%% a RSA_FIXED_DH or DSS_FIXED_DH
<<?BYTE(?RSA_SIGN)>>.
-certificate_authorities(_) ->
- %%TODO Make list of know CA:s
- <<>>.
+certificate_authorities(CertDbRef) ->
+ Authorities = certificate_authorities_from_db(CertDbRef),
+ Enc = fun(#'OTPCertificate'{tbsCertificate=TBSCert}) ->
+ OTPSubj = TBSCert#'OTPTBSCertificate'.subject,
+ Subj = public_key:pkix_transform(OTPSubj, encode),
+ {ok, DNEncoded} = 'OTP-PUB-KEY':encode('Name', Subj),
+ DNEncodedBin = iolist_to_binary(DNEncoded),
+ DNEncodedLen = byte_size(DNEncodedBin),
+ <<?UINT16(DNEncodedLen), DNEncodedBin/binary>>
+ end,
+ list_to_binary([Enc(Cert) || {_, Cert} <- Authorities]).
+
+certificate_authorities_from_db(CertDbRef) ->
+ certificate_authorities_from_db(CertDbRef, no_candidate, []).
+
+certificate_authorities_from_db(CertDbRef, PrevKey, Acc) ->
+ case ssl_certificate_db:issuer_candidate(PrevKey) of
+ no_more_candidates ->
+ lists:reverse(Acc);
+ {{CertDbRef, _, _} = Key, Cert} ->
+ certificate_authorities_from_db(CertDbRef, Key, [Cert|Acc]);
+ {Key, _Cert} ->
+ %% skip certs not from this ssl connection
+ certificate_authorities_from_db(CertDbRef, Key, Acc)
+ end.
digitally_signed(Hashes, #'RSAPrivateKey'{} = Key) ->
public_key:encrypt_private(Hashes, Key,
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
new file mode 100644
index 0000000000..bd86120c98
--- /dev/null
+++ b/lib/ssl/test/Makefile
@@ -0,0 +1,137 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1999-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+#
+
+# SSL test suite Makefile
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(GS_VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES = \
+ ssl_test_lib \
+ ssl_basic_SUITE \
+ ssl_packet_SUITE \
+ ssl_payload_SUITE \
+ ssl_to_openssl_SUITE \
+ ssl_test_MACHINE \
+ old_ssl_active_SUITE \
+ old_ssl_active_once_SUITE \
+ old_ssl_passive_SUITE \
+ old_ssl_verify_SUITE \
+ old_ssl_peer_cert_SUITE \
+ old_ssl_misc_SUITE \
+ old_ssl_protocol_SUITE \
+ old_transport_accept_SUITE \
+ old_ssl_dist_SUITE \
+ make_certs
+
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES = ssl_test_MACHINE.hrl
+
+HRL_FILES_SRC = \
+ ssl_pkix.hrl \
+ ssl_alert.hrl \
+ ssl_handshake.hrl
+
+HRL_FILES_INC = \
+ OTP-PKIX.hrl
+
+HRL_FILES_NEEDED_IN_TEST = \
+ $(HRL_FILES_SRC:%=../src/%) \
+ $(HRL_FILES_INC:%=../include/%)
+
+TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INCLUDES = -I. -I$(ERL_TOP)/lib/test_server/include/
+
+DATADIRS = ssl_basic_SUITE_data
+
+EMAKEFILE=Emakefile
+MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
+
+COVER_FILE = ssl.cover
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/ssl_test
+
+# ----------------------------------------------------
+# FLAGS
+# The path to the test_server ebin dir is needed when
+# running the target "targets".
+# ----------------------------------------------------
+ERL_COMPILE_FLAGS += -pa ../../../internal_tools/test_server/ebin \
+ $(INCLUDES)
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+tests debug opt: $(BUILDTARGET)
+
+targets: $(TARGET_FILES)
+
+.PHONY: emakebuild
+
+emakebuild: $(EMAKEFILE)
+
+$(EMAKEFILE):
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' | grep -v Warning > $(EMAKEFILE)
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) | grep -v Warning >> $(EMAKEFILE)
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core *~
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(HRL_FILES_NEEDED_IN_TEST) $(COVER_FILE) $(RELSYSDIR)
+ $(INSTALL_DATA) ssl.spec $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
+
+# Dependencies
+
+$(TARGET_FILES): $(HRL_FILES)
diff --git a/lib/ssl/test/make_certs.erl b/lib/ssl/test/make_certs.erl
new file mode 100644
index 0000000000..0cdf33c3e2
--- /dev/null
+++ b/lib/ssl/test/make_certs.erl
@@ -0,0 +1,288 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(make_certs).
+
+-export([all/2]).
+
+-record(dn, {commonName,
+ organizationalUnitName = "Erlang OTP",
+ organizationName = "Ericsson AB",
+ localityName = "Stockholm",
+ countryName = "SE",
+ emailAddress = "[email protected]"}).
+
+all(DataDir, PrivDir) ->
+ OpenSSLCmd = "openssl",
+ create_rnd(DataDir, PrivDir), % For all requests
+ rootCA(PrivDir, OpenSSLCmd, "erlangCA"),
+ intermediateCA(PrivDir, OpenSSLCmd, "otpCA", "erlangCA"),
+ endusers(PrivDir, OpenSSLCmd, "otpCA", ["client", "server"]),
+ collect_certs(PrivDir, ["erlangCA", "otpCA"], ["client", "server"]),
+ %% Create keycert files
+ SDir = filename:join([PrivDir, "server"]),
+ SC = filename:join([SDir, "cert.pem"]),
+ SK = filename:join([SDir, "key.pem"]),
+ SKC = filename:join([SDir, "keycert.pem"]),
+ append_files([SK, SC], SKC),
+ CDir = filename:join([PrivDir, "client"]),
+ CC = filename:join([CDir, "cert.pem"]),
+ CK = filename:join([CDir, "key.pem"]),
+ CKC = filename:join([CDir, "keycert.pem"]),
+ append_files([CK, CC], CKC),
+ remove_rnd(PrivDir).
+
+append_files(FileNames, ResultFileName) ->
+ {ok, ResultFile} = file:open(ResultFileName, [write]),
+ do_append_files(FileNames, ResultFile).
+
+do_append_files([], RF) ->
+ ok = file:close(RF);
+do_append_files([F|Fs], RF) ->
+ {ok, Data} = file:read_file(F),
+ ok = file:write(RF, Data),
+ do_append_files(Fs, RF).
+
+rootCA(Root, OpenSSLCmd, Name) ->
+ create_ca_dir(Root, Name, ca_cnf(Name)),
+ DN = #dn{commonName = Name},
+ create_self_signed_cert(Root, OpenSSLCmd, Name, req_cnf(DN)),
+ ok.
+
+intermediateCA(Root, OpenSSLCmd, CA, ParentCA) ->
+ CA = "otpCA",
+ create_ca_dir(Root, CA, ca_cnf(CA)),
+ CARoot = filename:join([Root, CA]),
+ DN = #dn{commonName = CA},
+ CnfFile = filename:join([CARoot, "req.cnf"]),
+ file:write_file(CnfFile, req_cnf(DN)),
+ KeyFile = filename:join([CARoot, "private", "key.pem"]),
+ ReqFile = filename:join([CARoot, "req.pem"]),
+ create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
+ CertFile = filename:join([CARoot, "cert.pem"]),
+ sign_req(Root, OpenSSLCmd, ParentCA, "ca_cert", ReqFile, CertFile).
+
+endusers(Root, OpenSSLCmd, CA, Users) ->
+ lists:foreach(fun(User) -> enduser(Root, OpenSSLCmd, CA, User) end, Users).
+
+enduser(Root, OpenSSLCmd, CA, User) ->
+ UsrRoot = filename:join([Root, User]),
+ file:make_dir(UsrRoot),
+ CnfFile = filename:join([UsrRoot, "req.cnf"]),
+ DN = #dn{commonName = User},
+ file:write_file(CnfFile, req_cnf(DN)),
+ KeyFile = filename:join([UsrRoot, "key.pem"]),
+ ReqFile = filename:join([UsrRoot, "req.pem"]),
+ create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
+ CertFile = filename:join([UsrRoot, "cert.pem"]),
+ sign_req(Root, OpenSSLCmd, CA, "user_cert", ReqFile, CertFile).
+
+collect_certs(Root, CAs, Users) ->
+ Bins = lists:foldr(
+ fun(CA, Acc) ->
+ File = filename:join([Root, CA, "cert.pem"]),
+ {ok, Bin} = file:read_file(File),
+ [Bin, "\n" | Acc]
+ end, [], CAs),
+ lists:foreach(
+ fun(User) ->
+ File = filename:join([Root, User, "cacerts.pem"]),
+ file:write_file(File, Bins)
+ end, Users).
+
+create_self_signed_cert(Root, OpenSSLCmd, CAName, Cnf) ->
+ CARoot = filename:join([Root, CAName]),
+ CnfFile = filename:join([CARoot, "req.cnf"]),
+ file:write_file(CnfFile, Cnf),
+ KeyFile = filename:join([CARoot, "private", "key.pem"]),
+ CertFile = filename:join([CARoot, "cert.pem"]),
+ Cmd = [OpenSSLCmd, " req"
+ " -new"
+ " -x509"
+ " -config ", CnfFile,
+ " -keyout ", KeyFile,
+ " -out ", CertFile],
+ Env = [{"ROOTDIR", Root}],
+ cmd(Cmd, Env).
+
+create_ca_dir(Root, CAName, Cnf) ->
+ CARoot = filename:join([Root, CAName]),
+ file:make_dir(CARoot),
+ create_dirs(CARoot, ["certs", "crl", "newcerts", "private"]),
+ create_rnd(Root, filename:join([CAName, "private"])),
+ create_files(CARoot, [{"serial", "01\n"},
+ {"index.txt", ""},
+ {"ca.cnf", Cnf}]).
+
+create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile) ->
+ Cmd = [OpenSSLCmd, " req"
+ " -new"
+ " -config ", CnfFile,
+ " -keyout ", KeyFile,
+ " -out ", ReqFile],
+ Env = [{"ROOTDIR", Root}],
+ cmd(Cmd, Env).
+
+sign_req(Root, OpenSSLCmd, CA, CertType, ReqFile, CertFile) ->
+ CACnfFile = filename:join([Root, CA, "ca.cnf"]),
+ Cmd = [OpenSSLCmd, " ca"
+ " -batch"
+ " -notext"
+ " -config ", CACnfFile,
+ " -extensions ", CertType,
+ " -in ", ReqFile,
+ " -out ", CertFile],
+ Env = [{"ROOTDIR", Root}],
+ cmd(Cmd, Env).
+
+%%
+%% Misc
+%%
+
+create_dirs(Root, Dirs) ->
+ lists:foreach(fun(Dir) ->
+ file:make_dir(filename:join([Root, Dir])) end,
+ Dirs).
+
+create_files(Root, NameContents) ->
+ lists:foreach(
+ fun({Name, Contents}) ->
+ file:write_file(filename:join([Root, Name]), Contents) end,
+ NameContents).
+
+create_rnd(FromDir, ToDir) ->
+ From = filename:join([FromDir, "RAND"]),
+ To = filename:join([ToDir, "RAND"]),
+ file:copy(From, To).
+
+remove_rnd(Dir) ->
+ File = filename:join([Dir, "RAND"]),
+ file:delete(File).
+
+cmd(Cmd, Env) ->
+ FCmd = lists:flatten(Cmd),
+ Port = open_port({spawn, FCmd}, [stream, eof, exit_status, stderr_to_stdout,
+ {env, Env}]),
+ eval_cmd(Port).
+
+eval_cmd(Port) ->
+ receive
+ {Port, {data, _}} ->
+ eval_cmd(Port);
+ {Port, eof} ->
+ ok
+ end,
+ receive
+ {Port, {exit_status, Status}} when Status /= 0 ->
+ %% io:fwrite("exit status: ~w~n", [Status]),
+ exit({eval_cmd, Status})
+ after 0 ->
+ ok
+ end.
+
+%%
+%% Contents of configuration files
+%%
+
+req_cnf(DN) ->
+ ["# Purpose: Configuration for requests (end users and CAs)."
+ "\n"
+ "ROOTDIR = $ENV::ROOTDIR\n"
+ "\n"
+
+ "[req]\n"
+ "input_password = secret\n"
+ "output_password = secret\n"
+ "default_bits = 1024\n"
+ "RANDFILE = $ROOTDIR/RAND\n"
+ "encrypt_key = no\n"
+ "default_md = sha1\n"
+ "#string_mask = pkix\n"
+ "x509_extensions = ca_ext\n"
+ "prompt = no\n"
+ "distinguished_name= name\n"
+ "\n"
+
+ "[name]\n"
+ "commonName = ", DN#dn.commonName, "\n"
+ "organizationalUnitName = ", DN#dn.organizationalUnitName, "\n"
+ "organizationName = ", DN#dn.organizationName, "\n"
+ "localityName = ", DN#dn.localityName, "\n"
+ "countryName = ", DN#dn.countryName, "\n"
+ "emailAddress = ", DN#dn.emailAddress, "\n"
+ "\n"
+
+ "[ca_ext]\n"
+ "basicConstraints = critical, CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
+ "subjectKeyIdentifier = hash\n"
+ "subjectAltName = email:copy\n"].
+
+
+ca_cnf(CA) ->
+ ["# Purpose: Configuration for CAs.\n"
+ "\n"
+ "ROOTDIR = $ENV::ROOTDIR\n"
+ "default_ca = ca\n"
+ "\n"
+
+ "[ca]\n"
+ "dir = $ROOTDIR/", CA, "\n"
+ "certs = $dir/certs\n"
+ "crl_dir = $dir/crl\n"
+ "database = $dir/index.txt\n"
+ "new_certs_dir = $dir/newcerts\n"
+ "certificate = $dir/cert.pem\n"
+ "serial = $dir/serial\n"
+ "crl = $dir/crl.pem\n"
+ "private_key = $dir/private/key.pem\n"
+ "RANDFILE = $dir/private/RAND\n"
+ "\n"
+ "x509_extensions = user_cert\n"
+ "default_days = 3600\n"
+ "default_md = sha1\n"
+ "preserve = no\n"
+ "policy = policy_match\n"
+ "\n"
+
+ "[policy_match]\n"
+ "commonName = supplied\n"
+ "organizationalUnitName = optional\n"
+ "organizationName = match\n"
+ "countryName = match\n"
+ "localityName = match\n"
+ "emailAddress = supplied\n"
+ "\n"
+
+ "[user_cert]\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid,issuer:always\n"
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"
+ "\n"
+
+ "[ca_cert]\n"
+ "basicConstraints = critical,CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid:always,issuer:always\n"
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"].
diff --git a/lib/ssl/test/old_ssl_active_SUITE.erl b/lib/ssl/test/old_ssl_active_SUITE.erl
new file mode 100644
index 0000000000..fc44fa23dd
--- /dev/null
+++ b/lib/ssl/test/old_ssl_active_SUITE.erl
@@ -0,0 +1,387 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_active_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ cinit_return_chkclose/1,
+ sinit_return_chkclose/1,
+ cinit_big_return_chkclose/1,
+ sinit_big_return_chkclose/1,
+ cinit_big_echo_chkclose/1,
+ cinit_huge_echo_chkclose/1,
+ sinit_big_echo_chkclose/1,
+ cinit_few_echo_chkclose/1,
+ cinit_many_echo_chkclose/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in active mode.";
+all(suite) ->
+ {conf,
+ config,
+ [cinit_return_chkclose,
+ sinit_return_chkclose,
+ cinit_big_return_chkclose,
+ sinit_big_return_chkclose,
+ cinit_big_echo_chkclose,
+ cinit_huge_echo_chkclose,
+ sinit_big_echo_chkclose,
+ cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains, and record the number of available "
+ "file descriptors";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+ case os:type() of
+ {unix, _} ->
+ ?line io:format("Max fd value: ~s", [os:cmd("ulimit -n")]);
+ _ ->
+ ok
+ end,
+ %% XXX Also record: Erlang/SSL version, version of OpenSSL,
+ %% operating system, version of OTP, Erts, kernel and stdlib.
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+cinit_return_chkclose(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_return_chkclose(suite) ->
+ [];
+cinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_return_chkclose(doc) ->
+ "Server sends 1000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_return_chkclose(suite) ->
+ [];
+sinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_return_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_big_return_chkclose(suite) ->
+ [];
+cinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_return_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_big_return_chkclose(suite) ->
+ [];
+sinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_echo_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_big_echo_chkclose(suite) ->
+ [];
+cinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_huge_echo_chkclose(doc) ->
+ "Client sends 500000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_huge_echo_chkclose(suite) ->
+ [];
+cinit_huge_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 500000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_echo_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that echoes them back "
+ "and closes. Server waits for close. Both have certs.";
+sinit_big_echo_chkclose(suite) ->
+ [];
+sinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {echo, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
+%% This case is repeated several times.
+
+cinit_few_echo_chkclose(X) -> cinit_many_echo_chkclose(X, 7).
+
+cinit_many_echo_chkclose(X) -> cinit_many_echo_chkclose(X, ?MANYCONNS).
+
+cinit_many_echo_chkclose(doc, _NConns) ->
+ "N client sends 10000 bytes to server, that echoes them back "
+ "and closes. Clients wait for close. All have certs.";
+cinit_many_echo_chkclose(suite, _NConns) ->
+ [];
+cinit_many_echo_chkclose(Config, NConns) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 10000, LPort = 3456,
+ Timeout = 80000,
+
+ io:format("~w connections", [NConns]),
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
+cinit_cnocert(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Client has no cert, "
+ "but server has.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
diff --git a/lib/ssl/test/old_ssl_active_once_SUITE.erl b/lib/ssl/test/old_ssl_active_once_SUITE.erl
new file mode 100644
index 0000000000..6224b17aa7
--- /dev/null
+++ b/lib/ssl/test/old_ssl_active_once_SUITE.erl
@@ -0,0 +1,409 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_active_once_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ server_accept_timeout/1,
+ cinit_return_chkclose/1,
+ sinit_return_chkclose/1,
+ cinit_big_return_chkclose/1,
+ sinit_big_return_chkclose/1,
+ cinit_big_echo_chkclose/1,
+ cinit_huge_echo_chkclose/1,
+ sinit_big_echo_chkclose/1,
+ cinit_few_echo_chkclose/1,
+ cinit_many_echo_chkclose/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in passive mode.";
+all(suite) ->
+ {conf,
+ config,
+ [server_accept_timeout,
+ cinit_return_chkclose,
+ sinit_return_chkclose,
+ cinit_big_return_chkclose,
+ sinit_big_return_chkclose,
+ cinit_big_echo_chkclose,
+ cinit_huge_echo_chkclose,
+ sinit_big_echo_chkclose,
+ cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+server_accept_timeout(doc) ->
+ "Server has one pending accept with timeout. Checks that return "
+ "value is {error, timeout}.";
+server_accept_timeout(suite) ->
+ [];
+server_accept_timeout(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+ AccTimeout = 3000,
+
+ ?line {ok, {_, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, AccTimeout},
+ accept_timeout],
+ ?line test_server_only(NConns, LCmds, ACmds, Timeout, ?MODULE,
+ Config).
+
+cinit_return_chkclose(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_return_chkclose(suite) ->
+ [];
+cinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_return_chkclose(doc) ->
+ "Server sends 1000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_return_chkclose(suite) ->
+ [];
+sinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_return_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_big_return_chkclose(suite) ->
+ [];
+cinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ %% Set {active, false} so that accept is passive to begin with.
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {sockopts, [{active, once}]}, % {active, once} here.
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_return_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_big_return_chkclose(suite) ->
+ [];
+sinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_echo_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_big_echo_chkclose(suite) ->
+ [];
+cinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_huge_echo_chkclose(doc) ->
+ "Client sends 500000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_huge_echo_chkclose(suite) ->
+ [];
+cinit_huge_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 500000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_echo_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that echoes them back "
+ "and closes. Server waits for close. Both have certs.";
+sinit_big_echo_chkclose(suite) ->
+ [];
+sinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {echo, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_few_echo_chkclose(X) -> cinit_many_echo_chkclose(X, 7).
+
+cinit_many_echo_chkclose(X) -> cinit_many_echo_chkclose(X, ?MANYCONNS).
+
+cinit_many_echo_chkclose(doc, _NConns) ->
+ "client send 10000 bytes to server, that echoes them back "
+ "and closes. Clients wait for close. All have certs.";
+cinit_many_echo_chkclose(suite, _NConns) ->
+ [];
+cinit_many_echo_chkclose(Config, NConns) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 10000, LPort = 3456,
+ Timeout = 80000,
+
+ io:format("~w connections", [NConns]),
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_cnocert(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Client has no cert, "
+ "but server has.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
diff --git a/lib/ssl/test/old_ssl_dist_SUITE.erl b/lib/ssl/test/old_ssl_dist_SUITE.erl
new file mode 100644
index 0000000000..56209c3530
--- /dev/null
+++ b/lib/ssl/test/old_ssl_dist_SUITE.erl
@@ -0,0 +1,595 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+
+%%%-------------------------------------------------------------------
+%%% File : ssl_dist_SUITE.erl
+%%% Author : Rickard Green
+%%% Description : Test that the Erlang distribution works over ssl.
+%%%
+%%% Created : 15 Nov 2007 by Rickard Green
+%%%-------------------------------------------------------------------
+-module(old_ssl_dist_SUITE).
+
+-include("test_server.hrl").
+
+-define(DEFAULT_TIMETRAP_SECS, 240).
+
+-define(AWAIT_SLL_NODE_UP_TIMEOUT, 30000).
+
+-export([all/1]).
+-export([init_per_suite/1,
+ end_per_suite/1,
+ init_per_testcase/2,
+ fin_per_testcase/2]).
+-export([cnct2tstsrvr/1]).
+
+-export([basic/1]).
+
+-record(node_handle, {connection_handler, socket, name, nodename}).
+
+all(doc) ->
+ [];
+all(suite) ->
+ [basic].
+
+init_per_suite(Config) ->
+ add_ssl_opts_config(Config).
+
+end_per_suite(Config) ->
+ Config.
+
+init_per_testcase(Case, Config) when list(Config) ->
+ Dog = ?t:timetrap(?t:seconds(?DEFAULT_TIMETRAP_SECS)),
+ [{watchdog, Dog},{testcase, Case}|Config].
+
+fin_per_testcase(_Case, Config) when list(Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% %%
+%% Testcases %%
+%% %%
+
+basic(doc) ->
+ ["Test that two nodes can connect via ssl distribution"];
+basic(suite) ->
+ [];
+basic(Config) when is_list(Config) ->
+ ?line NH1 = start_ssl_node(Config),
+ ?line Node1 = NH1#node_handle.nodename,
+ ?line NH2 = start_ssl_node(Config),
+ ?line Node2 = NH2#node_handle.nodename,
+
+ ?line pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
+
+ ?line [Node2] = apply_on_ssl_node(NH1, fun () -> nodes() end),
+ ?line [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end),
+
+ %% The test_server node has the same cookie as the ssl nodes
+ %% but it should not be able to communicate with the ssl nodes
+ %% via the erlang distribution.
+ ?line pang = net_adm:ping(Node1),
+ ?line pang = net_adm:ping(Node2),
+
+
+ %%
+ %% Check that we are able to communicate over the erlang
+ %% distribution between the ssl nodes.
+ %%
+ ?line Ref = make_ref(),
+ ?line spawn(fun () ->
+ apply_on_ssl_node(
+ NH1,
+ fun () ->
+ tstsrvr_format("Hi from ~p!~n",
+ [node()]),
+ send_to_tstcntrl({Ref, self()}),
+ receive
+ {From, ping} ->
+ From ! {self(), pong}
+ end
+ end)
+ end),
+ ?line receive
+ {Ref, SslPid} ->
+ ?line ok = apply_on_ssl_node(
+ NH2,
+ fun () ->
+ tstsrvr_format("Hi from ~p!~n",
+ [node()]),
+ SslPid ! {self(), ping},
+ receive
+ {SslPid, pong} ->
+ ok
+ end
+ end)
+ end,
+
+ ?line stop_ssl_node(NH1),
+ ?line stop_ssl_node(NH2),
+ ?line success(Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% %%
+%% Internal functions %%
+%% %%
+
+%%
+%% ssl_node side api
+%%
+
+tstsrvr_format(Fmt, ArgList) ->
+ send_to_tstsrvr({format, Fmt, ArgList}).
+
+send_to_tstcntrl(Message) ->
+ send_to_tstsrvr({message, Message}).
+
+
+%%
+%% test_server side api
+%%
+
+apply_on_ssl_node(Node, M, F, A) when atom(M), atom(F), list(A) ->
+ Ref = make_ref(),
+ send_to_ssl_node(Node, {apply, self(), Ref, M, F, A}),
+ receive
+ {Ref, Result} ->
+ Result
+ end.
+
+apply_on_ssl_node(Node, Fun) when is_function(Fun, 0) ->
+ Ref = make_ref(),
+ send_to_ssl_node(Node, {apply, self(), Ref, Fun}),
+ receive
+ {Ref, Result} ->
+ Result
+ end.
+
+stop_ssl_node(#node_handle{connection_handler = Handler,
+ socket = Socket,
+ name = Name}) ->
+ ?t:format("Trying to stop ssl node ~s.~n", [Name]),
+ Mon = erlang:monitor(process, Handler),
+ unlink(Handler),
+ case gen_tcp:send(Socket, term_to_binary(stop)) of
+ ok ->
+ receive
+ {'DOWN', Mon, process, Handler, Reason} ->
+ case Reason of
+ normal -> ok;
+ _ -> exit(Reason)
+ end
+ end;
+ Error ->
+ erlang:demonitor(Mon, [flush]),
+ exit(Error)
+ end.
+
+start_ssl_node(Config) ->
+ start_ssl_node(Config, "").
+
+start_ssl_node(Config, XArgs) ->
+ Name = mk_node_name(Config),
+ SSL = ?config(ssl_opts, Config),
+ SSLDistOpts = setup_dist_opts(Name, ?config(priv_dir, Config)),
+ start_ssl_node_raw(Name, SSL ++ " " ++ SSLDistOpts ++ XArgs).
+
+start_ssl_node_raw(Name, Args) ->
+ {ok, LSock} = gen_tcp:listen(0,
+ [binary, {packet, 4}, {active, false}]),
+ {ok, ListenPort} = inet:port(LSock),
+ CmdLine = mk_node_cmdline(ListenPort, Name, Args),
+ ?t:format("Attempting to start ssl node ~s: ~s~n", [Name, CmdLine]),
+ case open_port({spawn, CmdLine}, []) of
+ Port when port(Port) ->
+ unlink(Port),
+ erlang:port_close(Port),
+ case await_ssl_node_up(Name, LSock) of
+ #node_handle{} = NodeHandle ->
+ ?t:format("Ssl node ~s started.~n", [Name]),
+ NodeName = list_to_atom(Name ++ "@" ++ host_name()),
+ NodeHandle#node_handle{nodename = NodeName};
+ Error ->
+ exit({failed_to_start_node, Name, Error})
+ end;
+ Error ->
+ exit({failed_to_start_node, Name, Error})
+ end.
+
+%%
+%% command line creation
+%%
+
+host_name() ->
+ [$@ | Host] = lists:dropwhile(fun ($@) -> false; (_) -> true end,
+ atom_to_list(node())),
+ Host.
+
+mk_node_name(Config) ->
+ {A, B, C} = erlang:now(),
+ Case = ?config(testcase, Config),
+ atom_to_list(?MODULE)
+ ++ "_"
+ ++ atom_to_list(Case)
+ ++ "_"
+ ++ integer_to_list(A)
+ ++ "-"
+ ++ integer_to_list(B)
+ ++ "-"
+ ++ integer_to_list(C).
+
+mk_node_cmdline(ListenPort, Name, Args) ->
+ Static = "-detached -noinput",
+ Pa = filename:dirname(code:which(?MODULE)),
+ Prog = case catch init:get_argument(progname) of
+ {ok,[[P]]} -> P;
+ _ -> exit(no_progname_argument_found)
+ end,
+ NameSw = case net_kernel:longnames() of
+ false -> "-sname ";
+ _ -> "-name "
+ end,
+ {ok, Pwd} = file:get_cwd(),
+ Prog ++ " "
+ ++ Static ++ " "
+ ++ NameSw ++ " " ++ Name ++ " "
+ ++ "-pa " ++ Pa ++ " "
+ ++ "-run " ++ atom_to_list(?MODULE) ++ " cnct2tstsrvr "
+ ++ host_name() ++ " "
+ ++ integer_to_list(ListenPort) ++ " "
+ ++ Args ++ " "
+ ++ "-env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ Name ++ " "
+ ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()).
+
+%%
+%% Connection handler test_server side
+%%
+
+await_ssl_node_up(Name, LSock) ->
+ case gen_tcp:accept(LSock, ?AWAIT_SLL_NODE_UP_TIMEOUT) of
+ timeout ->
+ gen_tcp:close(LSock),
+ ?t:format("Timeout waiting for ssl node ~s to come up~n",
+ [Name]),
+ timeout;
+ {ok, Socket} ->
+ gen_tcp:close(LSock),
+ case gen_tcp:recv(Socket, 0) of
+ {ok, Bin} ->
+ check_ssl_node_up(Socket, Name, Bin);
+ {error, closed} ->
+ gen_tcp:close(Socket),
+ exit({lost_connection_with_ssl_node_before_up, Name})
+ end;
+ {error, Error} ->
+ gen_tcp:close(LSock),
+ exit({accept_failed, Error})
+ end.
+
+check_ssl_node_up(Socket, Name, Bin) ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ exit({bad_data_received_from_ssl_node, Name, Bin});
+ {ssl_node_up, NodeName} ->
+ case list_to_atom(Name++"@"++host_name()) of
+ NodeName ->
+ Parent = self(),
+ Go = make_ref(),
+ %% Spawn connection handler on test server side
+ Pid = spawn_link(
+ fun () ->
+ receive Go -> ok end,
+ tstsrvr_con_loop(Name, Socket, Parent)
+ end),
+ ok = gen_tcp:controlling_process(Socket, Pid),
+ Pid ! Go,
+ #node_handle{connection_handler = Pid,
+ socket = Socket,
+ name = Name};
+ _ ->
+ exit({unexpected_ssl_node_connected, NodeName})
+ end;
+ Msg ->
+ exit({unexpected_msg_instead_of_ssl_node_up, Name, Msg})
+ end.
+
+send_to_ssl_node(#node_handle{connection_handler = Hndlr}, Term) ->
+ Hndlr ! {relay_to_ssl_node, term_to_binary(Term)},
+ ok.
+
+tstsrvr_con_loop(Name, Socket, Parent) ->
+ inet:setopts(Socket,[{active,once}]),
+ receive
+ {relay_to_ssl_node, Data} when is_binary(Data) ->
+ case gen_tcp:send(Socket, Data) of
+ ok ->
+ ok;
+ _Error ->
+ gen_tcp:close(Socket),
+ exit({failed_to_relay_data_to_ssl_node, Name, Data})
+ end;
+ {tcp, Socket, Bin} ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ exit({bad_data_received_from_ssl_node, Name, Bin});
+ {format, FmtStr, ArgList} ->
+ ?t:format(FmtStr, ArgList);
+ {message, Msg} ->
+ Parent ! Msg;
+ {apply_res, To, Ref, Res} ->
+ To ! {Ref, Res};
+ bye ->
+ ?t:format("Ssl node ~s stopped.~n", [Name]),
+ gen_tcp:close(Socket),
+ exit(normal);
+ Unknown ->
+ exit({unexpected_message_from_ssl_node, Name, Unknown})
+ end;
+ {tcp_closed, Socket} ->
+ gen_tcp:close(Socket),
+ exit({lost_connection_with_ssl_node, Name})
+ end,
+ tstsrvr_con_loop(Name, Socket, Parent).
+
+%%
+%% Connection handler ssl_node side
+%%
+
+% cnct2tstsrvr() is called via command line arg -run ...
+cnct2tstsrvr([Host, Port]) when list(Host), list(Port) ->
+ %% Spawn connection handler on ssl node side
+ ConnHandler
+ = spawn(fun () ->
+ case catch gen_tcp:connect(Host,
+ list_to_integer(Port),
+ [binary,
+ {packet, 4},
+ {active, false}]) of
+ {ok, Socket} ->
+ notify_ssl_node_up(Socket),
+ ets:new(test_server_info,
+ [set,
+ public,
+ named_table,
+ {keypos, 1}]),
+ ets:insert(test_server_info,
+ {test_server_handler, self()}),
+ ssl_node_con_loop(Socket);
+ _Error ->
+ halt("Failed to connect to test server")
+ end
+ end),
+ spawn(fun () ->
+ Mon = erlang:monitor(process, ConnHandler),
+ receive
+ {'DOWN', Mon, process, ConnHandler, Reason} ->
+ receive after 1000 -> ok end,
+ halt("test server connection handler terminated: "
+ ++
+ lists:flatten(io_lib:format("~p", [Reason])))
+ end
+ end).
+
+notify_ssl_node_up(Socket) ->
+ case catch gen_tcp:send(Socket,
+ term_to_binary({ssl_node_up, node()})) of
+ ok -> ok;
+ _ -> halt("Failed to notify test server that I'm up")
+ end.
+
+send_to_tstsrvr(Term) ->
+ case catch ets:lookup_element(test_server_info, test_server_handler, 2) of
+ Hndlr when pid(Hndlr) ->
+ Hndlr ! {relay_to_test_server, term_to_binary(Term)}, ok;
+ _ ->
+ receive after 200 -> ok end,
+ send_to_tstsrvr(Term)
+ end.
+
+ssl_node_con_loop(Socket) ->
+ inet:setopts(Socket,[{active,once}]),
+ receive
+ {relay_to_test_server, Data} when is_binary(Data) ->
+ case gen_tcp:send(Socket, Data) of
+ ok ->
+ ok;
+ _Error ->
+ gen_tcp:close(Socket),
+ halt("Failed to relay data to test server")
+ end;
+ {tcp, Socket, Bin} ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ halt("test server sent me bad data");
+ {apply, From, Ref, M, F, A} ->
+ spawn_link(
+ fun () ->
+ send_to_tstsrvr({apply_res,
+ From,
+ Ref,
+ (catch apply(M, F, A))})
+ end);
+ {apply, From, Ref, Fun} ->
+ spawn_link(fun () ->
+ send_to_tstsrvr({apply_res,
+ From,
+ Ref,
+ (catch Fun())})
+ end);
+ stop ->
+ gen_tcp:send(Socket, term_to_binary(bye)),
+ gen_tcp:close(Socket),
+ init:stop(),
+ receive after infinity -> ok end;
+ _Unknown ->
+ halt("test server sent me an unexpected message")
+ end;
+ {tcp_closed, Socket} ->
+ halt("Lost connection to test server")
+ end,
+ ssl_node_con_loop(Socket).
+
+%%
+%% Setup ssl dist info
+%%
+
+rand_bin(N) ->
+ rand_bin(N, []).
+
+rand_bin(0, Acc) ->
+ Acc;
+rand_bin(N, Acc) ->
+ rand_bin(N-1, [random:uniform(256)-1|Acc]).
+
+make_randfile(Dir) ->
+ {ok, IoDev} = file:open(filename:join([Dir, "RAND"]), [write]),
+ {A, B, C} = erlang:now(),
+ random:seed(A, B, C),
+ ok = file:write(IoDev, rand_bin(1024)),
+ file:close(IoDev).
+
+append_files(FileNames, ResultFileName) ->
+ {ok, ResultFile} = file:open(ResultFileName, [write]),
+ do_append_files(FileNames, ResultFile).
+
+do_append_files([], RF) ->
+ ok = file:close(RF);
+do_append_files([F|Fs], RF) ->
+ {ok, Data} = file:read_file(F),
+ ok = file:write(RF, Data),
+ do_append_files(Fs, RF).
+
+setup_dist_opts(Name, PrivDir) ->
+ NodeDir = filename:join([PrivDir, Name]),
+ RGenDir = filename:join([NodeDir, "rand_gen"]),
+ ok = file:make_dir(NodeDir),
+ ok = file:make_dir(RGenDir),
+ make_randfile(RGenDir),
+ make_certs:all(RGenDir, NodeDir),
+ SDir = filename:join([NodeDir, "server"]),
+ SC = filename:join([SDir, "cert.pem"]),
+ SK = filename:join([SDir, "key.pem"]),
+ SKC = filename:join([SDir, "keycert.pem"]),
+ append_files([SK, SC], SKC),
+ CDir = filename:join([NodeDir, "client"]),
+ CC = filename:join([CDir, "cert.pem"]),
+ CK = filename:join([CDir, "key.pem"]),
+ CKC = filename:join([CDir, "keycert.pem"]),
+ append_files([CK, CC], CKC),
+ "-proto_dist inet_ssl "
+ ++ "-ssl_dist_opt server_certfile " ++ SKC ++ " "
+ ++ "-ssl_dist_opt client_certfile " ++ CKC ++ " "
+.% ++ "-ssl_dist_opt verify 1 depth 1".
+
+%%
+%% Start scripts etc...
+%%
+
+add_ssl_opts_config(Config) ->
+ %%
+ %% Start with boot scripts if on an installed system; otherwise,
+ %% just point out ssl ebin with -pa.
+ %%
+ try
+ Dir = ?config(priv_dir, Config),
+ LibDir = code:lib_dir(),
+ Apps = application:which_applications(),
+ {value, {stdlib, _, STDL_VSN}} = lists:keysearch(stdlib, 1, Apps),
+ {value, {kernel, _, KRNL_VSN}} = lists:keysearch(kernel, 1, Apps),
+ StdlDir = filename:join([LibDir, "stdlib-" ++ STDL_VSN]),
+ KrnlDir = filename:join([LibDir, "kernel-" ++ KRNL_VSN]),
+ {ok, _} = file:read_file_info(StdlDir),
+ {ok, _} = file:read_file_info(KrnlDir),
+ SSL_VSN = case lists:keysearch(ssl, 1, Apps) of
+ {value, {ssl, _, VSN}} ->
+ VSN;
+ _ ->
+ application:start(ssl),
+ try
+ {value,
+ {ssl,
+ _,
+ VSN}} = lists:keysearch(ssl,
+ 1,
+ application:which_applications()),
+ VSN
+ after
+ application:stop(ssl)
+ end
+ end,
+ SslDir = filename:join([LibDir, "ssl-" ++ SSL_VSN]),
+ {ok, _} = file:read_file_info(SslDir),
+ %% We are using an installed otp system, create the boot script.
+ Script = filename:join(Dir, atom_to_list(?MODULE)),
+ {ok, RelFile} = file:open(Script ++ ".rel", [write]),
+ io:format(RelFile,
+ "{release, ~n"
+ " {\"SSL distribution test release\", \"~s\"},~n"
+ " {erts, \"~s\"},~n"
+ " [{kernel, \"~s\"},~n"
+ " {stdlib, \"~s\"},~n"
+ " {ssl, \"~s\"}]}.~n",
+ [case catch erlang:system_info(otp_release) of
+ {'EXIT', _} -> "R11B";
+ Rel -> Rel
+ end,
+ erlang:system_info(version),
+ KRNL_VSN,
+ STDL_VSN,
+ SSL_VSN]),
+ ok = file:close(RelFile),
+ ok = systools:make_script(Script, []),
+ [{ssl_opts, "-boot " ++ Script} | Config]
+ catch
+ _:_ ->
+ [{ssl_opts, "-pa " ++ filename:dirname(code:which(ssl))}
+ | add_comment_config(
+ "Bootscript wasn't used since the test wasn't run on an "
+ "installed OTP system.",
+ Config)]
+ end.
+
+%%
+%% Add common comments to config
+%%
+
+add_comment_config(Comment, []) ->
+ [{comment, Comment}];
+add_comment_config(Comment, [{comment, OldComment} | Cs]) ->
+ [{comment, Comment ++ " " ++ OldComment} | Cs];
+add_comment_config(Comment, [C|Cs]) ->
+ [C|add_comment_config(Comment, Cs)].
+
+%%
+%% Call when test case success
+%%
+
+success(Config) ->
+ case lists:keysearch(comment, 1, Config) of
+ {value, {comment, _} = Res} -> Res;
+ _ -> ok
+ end.
diff --git a/lib/ssl/test/old_ssl_misc_SUITE.erl b/lib/ssl/test/old_ssl_misc_SUITE.erl
new file mode 100644
index 0000000000..55d1b71025
--- /dev/null
+++ b/lib/ssl/test/old_ssl_misc_SUITE.erl
@@ -0,0 +1,105 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_misc_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ seed/1,
+ app/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, 5).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of misc in ssl.erl interface.";
+all(suite) ->
+ {conf,
+ config,
+ [seed, app],
+ finish
+ }.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+seed(doc) ->
+ "Test that ssl:seed/1 works.";
+seed(suite) ->
+ [];
+seed(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ LCmds = [{seed, "tjosan"},
+ {sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ?line test_server_only(NConns, LCmds, [], Timeout, ?MODULE,
+ Config).
+
+app(doc) ->
+ "Test that the ssl app file is ok";
+app(suite) ->
+ [];
+app(Config) when list(Config) ->
+ ?line ok = test_server:app_test(ssl).
+
+
diff --git a/lib/ssl/test/old_ssl_passive_SUITE.erl b/lib/ssl/test/old_ssl_passive_SUITE.erl
new file mode 100644
index 0000000000..4cb8c1f0cd
--- /dev/null
+++ b/lib/ssl/test/old_ssl_passive_SUITE.erl
@@ -0,0 +1,374 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_passive_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ server_accept_timeout/1,
+ cinit_return_chkclose/1,
+ sinit_return_chkclose/1,
+ cinit_big_return_chkclose/1,
+ sinit_big_return_chkclose/1,
+ cinit_big_echo_chkclose/1,
+ sinit_big_echo_chkclose/1,
+ cinit_few_echo_chkclose/1,
+ cinit_many_echo_chkclose/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in passive mode.";
+all(suite) ->
+ {conf,
+ config,
+ [server_accept_timeout,
+ cinit_return_chkclose,
+ sinit_return_chkclose,
+ cinit_big_return_chkclose,
+ sinit_big_return_chkclose,
+ cinit_big_echo_chkclose,
+ sinit_big_echo_chkclose,
+ cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+server_accept_timeout(doc) ->
+ "Server has one pending accept with timeout. Checks that return "
+ "value is {error, timeout}.";
+server_accept_timeout(suite) ->
+ [];
+server_accept_timeout(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+ AccTimeout = 3000,
+
+ ?line {ok, {_, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, AccTimeout},
+ accept_timeout],
+ ?line test_server_only(NConns, LCmds, ACmds, Timeout, ?MODULE, Config).
+
+cinit_return_chkclose(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_return_chkclose(suite) ->
+ [];
+cinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_return_chkclose(doc) ->
+ "Server sends 1000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_return_chkclose(suite) ->
+ [];
+sinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_return_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_big_return_chkclose(suite) ->
+ [];
+cinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_return_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_big_return_chkclose(suite) ->
+ [];
+sinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_echo_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_big_echo_chkclose(suite) ->
+ [];
+cinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_echo_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that echoes them back "
+ "and closes. Server waits for close. Both have certs.";
+sinit_big_echo_chkclose(suite) ->
+ [];
+sinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {echo, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
+cinit_few_echo_chkclose(X) -> cinit_many_echo_chkclose(X, 7).
+
+cinit_many_echo_chkclose(X) -> cinit_many_echo_chkclose(X, ?MANYCONNS).
+
+cinit_many_echo_chkclose(doc, _NConns) ->
+ "clients send 10000 bytes to server, that echoes them back "
+ "and closes. Clients wait for close. All have certs.";
+cinit_many_echo_chkclose(suite, _NConns) ->
+ [];
+cinit_many_echo_chkclose(Config, NConns) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 10000, LPort = 3456,
+ Timeout = 80000,
+
+ io:format("~w connections", [NConns]),
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_cnocert(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Client has no cert, "
+ "but server has.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
diff --git a/lib/ssl/test/old_ssl_peer_cert_SUITE.erl b/lib/ssl/test/old_ssl_peer_cert_SUITE.erl
new file mode 100644
index 0000000000..f0b8db2607
--- /dev/null
+++ b/lib/ssl/test/old_ssl_peer_cert_SUITE.erl
@@ -0,0 +1,180 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_peer_cert_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ cinit_plain/1,
+ cinit_both_verify/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl verification and peer certificate retrieval.";
+all(suite) ->
+ {conf,
+ config,
+ [cinit_plain,
+ cinit_both_verify,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+cinit_plain(doc) ->
+ "Server closes after accept, Client waits for close. Both have certs "
+ "but both use the defaults for verify and depth, but still tries "
+ "to retreive each others certificates.";
+cinit_plain(suite) ->
+ [];
+cinit_plain(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ nopeercert,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ peercert,
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+cinit_both_verify(doc) ->
+ "Server closes after accept, Client waits for close. Both have certs "
+ "and both verify each other.";
+cinit_both_verify(suite) ->
+ [];
+cinit_both_verify(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts0, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line CsslOpts = [{verify, 2}, {depth, 2} | CsslOpts0],
+ ?line SsslOpts = [{verify, 2}, {depth, 3} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ peercert,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ peercert,
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+cinit_cnocert(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line SsslOpts = [{verify, 0}, {depth, 2} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ peercert,
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+
diff --git a/lib/ssl/test/old_ssl_protocol_SUITE.erl b/lib/ssl/test/old_ssl_protocol_SUITE.erl
new file mode 100644
index 0000000000..7bde5d6749
--- /dev/null
+++ b/lib/ssl/test/old_ssl_protocol_SUITE.erl
@@ -0,0 +1,169 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_protocol_SUITE).
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2, config/1,
+ finish/1, sslv2/1, sslv3/1, tlsv1/1, sslv2_sslv3/1,
+ sslv2_tlsv1/1, sslv3_tlsv1/1, sslv2_sslv3_tlsv1/1]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of configuration protocol_version.";
+all(suite) ->
+ {conf,
+ config,
+ [sslv2, sslv3, tlsv1, sslv2_sslv3, sslv2_tlsv1, sslv3_tlsv1,
+ sslv2_sslv3_tlsv1],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no other purpose than closing the conf case.";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+%%%%%
+
+sslv2(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose SSLv2.";
+sslv2(suite) ->
+ [];
+sslv2(Config) when list(Config) ->
+ do_run_test(Config, [sslv2]).
+
+sslv3(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose SSLv3.";
+sslv3(suite) ->
+ [];
+sslv3(Config) when list(Config) ->
+ do_run_test(Config, [sslv3]).
+
+tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose TLSv1.";
+tlsv1(suite) ->
+ [];
+tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [tlsv1]).
+
+sslv2_sslv3(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv2 and SSLv3.";
+sslv2_sslv3(suite) ->
+ [];
+sslv2_sslv3(Config) when list(Config) ->
+ do_run_test(Config, [sslv2, sslv3]).
+
+sslv2_tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv2 and TLSv1.";
+sslv2_tlsv1(suite) ->
+ [];
+sslv2_tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [sslv2, tlsv1]).
+
+sslv3_tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv3 and TLSv1.";
+sslv3_tlsv1(suite) ->
+ [];
+sslv3_tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [sslv3, tlsv1]).
+
+sslv2_sslv3_tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv2, SSLv3, and TLSv1.";
+sslv2_sslv3_tlsv1(suite) ->
+ [];
+sslv2_sslv3_tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [sslv2, sslv3, tlsv1]).
+
+%%%%
+
+do_run_test(Config0, Protocols) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+ DataSize = 10,
+
+ ?line {ok, {_, SsslOpts0}} = mk_ssl_cert_opts(Config0),
+ ?line SsslOpts = [{verify, 0}, {depth, 2} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ connection_info,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ connection_info,
+ {send, DataSize},
+ await_close],
+ Config1 = [{env, [{protocol_version, Protocols}]} | Config0],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config1).
+
+
diff --git a/lib/ssl/test/old_ssl_verify_SUITE.erl b/lib/ssl/test/old_ssl_verify_SUITE.erl
new file mode 100644
index 0000000000..5db964526f
--- /dev/null
+++ b/lib/ssl/test/old_ssl_verify_SUITE.erl
@@ -0,0 +1,141 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_verify_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ cinit_both_verify/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in active mode.";
+all(suite) ->
+ {conf,
+ config,
+ [cinit_both_verify,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+cinit_both_verify(doc) ->
+ "Server closes after accept, Client waits for close. Both have certs "
+ "and both verify each other.";
+cinit_both_verify(suite) ->
+ [];
+cinit_both_verify(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts0, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line CsslOpts = [{verify, 2}, {depth, 2} | CsslOpts0],
+ ?line SsslOpts = [{verify, 2}, {depth, 3} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+cinit_cnocert(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line SsslOpts = [{verify, 0}, {depth, 2} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+
diff --git a/lib/ssl/test/old_transport_accept_SUITE.erl b/lib/ssl/test/old_transport_accept_SUITE.erl
new file mode 100644
index 0000000000..4bb09cee19
--- /dev/null
+++ b/lib/ssl/test/old_transport_accept_SUITE.erl
@@ -0,0 +1,238 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_transport_accept_SUITE).
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+-define(application, ssh).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ echo_once/1,
+ echo_twice/1,
+ close_before_ssl_accept/1,
+ server/5,
+ tolerant_server/5,
+ client/5
+ ]).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?default_timeout),
+ [{watchdog, WatchDog}, {protomod, gen_tcp}, {serialize_accept, true}|
+ Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test transport_accept and ssl_accept";
+all(suite) ->
+ [config, echo_once, echo_twice, close_before_ssl_accept].
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+ ok.
+
+echo_once(doc) ->
+ "Client sends 256 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+echo_once(suite) ->
+ [];
+echo_once(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ {ok, Host} = inet:gethostname(),
+ {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config),
+ N = 1,
+ Msg = lists:seq(0, 255),
+ Self = self(),
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ Node = start_node(server, Params),
+ CNode = start_node(client, Params),
+ Server = spawn_link(Node, ?MODULE, server, [Self, LPort, SOpts, Msg, N]),
+ Client = spawn_link(Node, ?MODULE, client, [Host, LPort, COpts, Msg, N]),
+ ok = receive
+ {Server, listening} ->
+ Client ! {Server, listening},
+ ok;
+ E ->
+ io:format("bad receive (1) ~p\n", [E]),
+ E
+ end,
+ receive
+ {Server, done} ->
+ ok
+ end,
+ test_server:stop_node(Node),
+ test_server:stop_node(CNode).
+
+close_before_ssl_accept(doc) ->
+ "Client sends 256 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+close_before_ssl_accept(suite) ->
+ [];
+close_before_ssl_accept(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ {ok, Host} = inet:gethostname(),
+ {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config),
+ Msg = lists:seq(0, 255),
+ Self = self(),
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ Node = start_node(server, Params),
+ CNode = start_node(client, Params),
+ Server = spawn_link(Node, ?MODULE, tolerant_server,
+ [Self, LPort, SOpts, Msg, 2]),
+ Client = spawn_link(Node, ?MODULE, client,
+ [Host, LPort, COpts, Msg, 1]),
+ ok = receive
+ {Server, listening} ->
+ {ok, S} = gen_tcp:connect(Host, LPort, []),
+ gen_tcp:close(S),
+ Client ! {Server, listening},
+ ok;
+ E ->
+ io:format("bad receive (1) ~p\n", [E]),
+ E
+ end,
+ receive
+ {Server, done} ->
+ ok
+ end,
+ test_server:stop_node(Node),
+ test_server:stop_node(CNode).
+
+client(Host, LPort, COpts, Msg, N) ->
+ ok = receive
+ {_Server, listening} ->
+ ok;
+ E ->
+ io:format("bad receive (2) ~p\n", [E]),
+ E
+ end,
+ Opts = COpts ++ [{packet, raw}, {active, false}],
+ app(),
+ lists:foreach(fun(_) ->
+ {ok, S} = ssl:connect(Host, LPort, Opts),
+ ssl:send(S, Msg),
+ {ok, Msg} = ssl:recv(S, length(Msg)),
+ ssl:close(S)
+ end, lists:seq(1, N)).
+
+echo_twice(doc) ->
+ "Two clients sends 256 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+echo_twice(suite) ->
+ [];
+echo_twice(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ {ok, Host} = inet:gethostname(),
+ {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config),
+ N = 2,
+ Msg = lists:seq(0, 255),
+ Self = self(),
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ Node = start_node(server, Params),
+ CNode = start_node(client, Params),
+ Server = spawn_link(Node, ?MODULE, server,
+ [Self, LPort, SOpts, Msg, N]),
+ Client = spawn_link(Node, ?MODULE, client,
+ [Host, LPort, COpts, Msg, N]),
+ ok = receive
+ {Server, listening} ->
+ Client ! {Server, listening},
+ ok;
+ E ->
+ io:format("bad receive (3) ~p\n", [E]),
+ E
+ end,
+ receive
+ {Server, done} ->
+ ok
+ end,
+ test_server:stop_node(Node),
+ test_server:stop_node(CNode).
+
+server(Client, Port, SOpts, Msg, N) ->
+ app(),
+ process_flag(trap_exit, true),
+ Opts = SOpts ++ [{packet, raw}, {active, false}],
+ {ok, LSock} = ssl:listen(Port, Opts),
+ Client ! {self(), listening},
+ server_loop(Client, LSock, Msg, N).
+
+server_loop(Client, _, _, 0) ->
+ Client ! {self(), done};
+server_loop(Client, LSock, Msg, N) ->
+ {ok, S} = ssl:transport_accept(LSock),
+ ok = ssl:ssl_accept(S),
+ %% P = ssl:controlling_process(S, Proxy),
+ {ok, Msg} = ssl:recv(S, length(Msg)),
+ ok = ssl:send(S, Msg),
+ ok = ssl:close(S),
+ server_loop(Client, LSock, Msg, N-1).
+
+tolerant_server(Client, Port, SOpts, Msg, N) ->
+ app(),
+ process_flag(trap_exit, true),
+ Opts = SOpts ++ [{packet, raw}, {active, false}],
+ {ok, LSock} = ssl:listen(Port, Opts),
+ Client ! {self(), listening},
+ tolerant_server_loop(Client, LSock, Msg, N).
+
+tolerant_server_loop(Client, _, _, 0) ->
+ Client ! {self(), done};
+tolerant_server_loop(Client, LSock, Msg, N) ->
+ {ok, S} = ssl:transport_accept(LSock),
+ case ssl:ssl_accept(S) of
+ ok ->
+ %% P = ssl:controlling_process(S, Proxy),
+ {ok, Msg} = ssl:recv(S, length(Msg)),
+ ok = ssl:send(S, Msg),
+ ok = ssl:close(S);
+ E ->
+ io:format("ssl_accept error: ~p\n", [E])
+ end,
+ tolerant_server_loop(Client, LSock, Msg, N-1).
+
+app() ->
+ case application:get_application(ssl) of
+ undefined ->
+ application:start(ssl);
+ _ ->
+ ok
+ end.
+
+start_node(Kind, Params) ->
+ S = atom_to_list(?MODULE)++"_" ++ atom_to_list(Kind),
+ {ok, Node} = test_server:start_node(list_to_atom(S), slave, [{args, Params}]),
+ Node.
+
diff --git a/lib/ssl/test/ssl.cover b/lib/ssl/test/ssl.cover
new file mode 100644
index 0000000000..138bf96b9d
--- /dev/null
+++ b/lib/ssl/test/ssl.cover
@@ -0,0 +1,7 @@
+{exclude, [ssl_pkix_oid,
+ 'PKIX1Algorithms88',
+ 'PKIX1Explicit88',
+ 'PKIX1Implicit88',
+ 'PKIXAttributeCertificate',
+ 'SSL-PKIX']}.
+
diff --git a/lib/ssl/test/ssl.spec b/lib/ssl/test/ssl.spec
new file mode 100644
index 0000000000..6ef4fb73db
--- /dev/null
+++ b/lib/ssl/test/ssl.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../ssl_test"}}.
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
new file mode 100644
index 0000000000..2b247532ee
--- /dev/null
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -0,0 +1,2075 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_basic_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+-define('24H_in_sec', 86400).
+-define(TIMEOUT, 60000).
+-define(EXPIRE, 10).
+
+-behaviour(ssl_session_cache_api).
+
+%% For the session cache tests
+-export([init/0, terminate/1, lookup/2, update/3,
+ delete/2, foldl/3, select_session/2]).
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initialization before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ crypto:start(),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config))),
+ test_server:format("Make certs ~p~n", [Result]),
+ ssl_test_lib:cert_options(Config).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ssl:stop(),
+ crypto:stop().
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initialization before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initialization before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(session_cache_process_list, Config) ->
+ init_customized_session_cache(Config);
+
+init_per_testcase(session_cache_process_mnesia, Config) ->
+ mnesia:start(),
+ init_customized_session_cache(Config);
+
+init_per_testcase(reuse_session_expired, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ssl_test_lib:timetrap(?EXPIRE * 1000 * 5),
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, session_lifetime, ?EXPIRE),
+ ssl:start(),
+ [{watchdog, Dog} | Config];
+
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = test_server:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+init_customized_session_cache(Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = test_server:timetrap(?TIMEOUT),
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, session_cb, ?MODULE),
+ ssl:start(),
+ [{watchdog, Dog} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(session_cache_process_list, Config) ->
+ application:unset_env(ssl, session_cb),
+ end_per_testcase(default_action, Config);
+end_per_testcase(session_cache_process_mnesia, Config) ->
+ application:unset_env(ssl, session_cb),
+ mnesia:stop(),
+ end_per_testcase(default_action, Config);
+end_per_testcase(reuse_session_expired, Config) ->
+ application:unset_env(ssl, session_lifetime),
+ end_per_testcase(default_action, Config);
+end_per_testcase(_TestCase, Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test the basic ssl functionality"];
+
+all(suite) ->
+ [app, connection_info, controlling_process, controller_dies,
+ peercert, connect_dist,
+ peername, sockname, socket_options, versions, cipher_suites, upgrade,
+ upgrade_with_timeout,
+ ipv6, ekeyfile, ecertfile, ecacertfile, eoptions, shutdown,
+ shutdown_write, shutdown_both, shutdown_error, ciphers,
+ send_close,
+ server_verify_peer_passive,
+ server_verify_peer_active, server_verify_peer_active_once,
+ server_verify_none_passive, server_verify_none_active,
+ server_verify_none_active_once,
+ server_verify_no_cacerts, client_verify_none_passive,
+ client_verify_none_active, client_verify_none_active_once
+ %%, session_cache_process_list, session_cache_process_mnesia
+ ,reuse_session, reuse_session_expired, server_does_not_want_to_reuse_session
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+app(doc) ->
+ "Test that the ssl app file is ok";
+app(suite) ->
+ [];
+app(Config) when is_list(Config) ->
+ ok = test_server:app_test(ssl).
+
+connection_info(doc) ->
+ ["Test the API function ssl:connection_info/1"];
+connection_info(suite) ->
+ [];
+connection_info(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options,
+ [{ciphers,[{rsa,rc4_128,sha,no_export}]} |
+ ClientOpts]}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ ServerMsg = ClientMsg = {ok, {Version, {rsa,rc4_128,sha,no_export}}},
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+connection_info_result(Socket) ->
+ ssl:connection_info(Socket).
+
+%%--------------------------------------------------------------------
+
+controlling_process(doc) ->
+ ["Test API function controlling_process/2"];
+
+controlling_process(suite) ->
+ [];
+
+controlling_process(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ClientMsg = "Hello server",
+ ServerMsg = "Hello client",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ controlling_process_result, [self(),
+ ServerMsg]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controlling_process_result, [self(),
+ ClientMsg]}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ receive
+ {ssl, _, ServerMsg} ->
+ receive
+ {ssl, _, ClientMsg} ->
+ ok
+ end;
+ {ssl, _, ClientMsg} ->
+ receive
+ {ssl, _, ServerMsg} ->
+ ok
+ end;
+ Unexpected ->
+ test_server:fail(Unexpected)
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+controlling_process_result(Socket, Pid, Msg) ->
+ ok = ssl:controlling_process(Socket, Pid),
+ %% Make sure other side has evaluated controlling_process
+ %% before message is sent
+ test_server:sleep(100),
+ ssl:send(Socket, Msg),
+ no_result_msg.
+
+
+controller_dies(doc) ->
+ ["Test that the socket is closed after controlling process dies"];
+controller_dies(suite) -> [];
+controller_dies(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ClientMsg = "Hello server",
+ ServerMsg = "Hello client",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ServerMsg]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ClientMsg]}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n", [self(), Client, Server]),
+ timer:sleep(200), %% so that they are connected
+
+ process_flag(trap_exit, true),
+
+ %% Test that clients die
+ exit(Client, killed),
+ get_close(Client, ?LINE),
+
+ %% Test that clients die when process disappear
+ Server ! listen, timer:sleep(200),
+ Tester = self(),
+ Connect = fun(Pid) ->
+ {ok, Socket} = ssl:connect(Hostname, Port,
+ [{reuseaddr,true},{ssl_imp,new}]),
+ Pid ! {self(), connected, Socket},
+ receive die_nice -> normal end
+ end,
+ Client2 = spawn_link(fun() -> Connect(Tester) end),
+ receive {Client2, connected, _Socket} -> Client2 ! die_nice end,
+
+ get_close(Client2, ?LINE),
+
+ %% Test that clients die when the controlling process have changed
+ Server ! listen, timer:sleep(200),
+
+ Client3 = spawn_link(fun() -> Connect(Tester) end),
+ Controller = spawn_link(fun() -> receive die_nice -> normal end end),
+ receive
+ {Client3, connected, Socket} ->
+ ok = ssl:controlling_process(Socket, Controller),
+ Client3 ! die_nice
+ end,
+
+ test_server:format("Wating on exit ~p~n",[Client3]),
+ receive {'EXIT', Client3, normal} -> ok end,
+
+ receive %% Client3 is dead but that doesn't matter, socket should not be closed.
+ Unexpected ->
+ test_server:format("Unexpected ~p~n",[Unexpected]),
+ test_server:fail({line, ?LINE-1})
+ after 1000 ->
+ ok
+ end,
+ Controller ! die_nice,
+ get_close(Controller, ?LINE),
+
+ %% Test that servers die
+ Server ! listen, timer:sleep(200),
+ LastClient = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ClientMsg]}},
+ {options, [{reuseaddr,true}|ClientOpts]}]),
+ timer:sleep(200), %% so that they are connected
+
+ exit(Server, killed),
+ get_close(Server, ?LINE),
+ process_flag(trap_exit, false),
+ ssl_test_lib:close(LastClient).
+
+controller_dies_result(_Socket, _Pid, _Msg) ->
+ receive Result -> Result end.
+
+get_close(Pid, Where) ->
+ receive
+ {'EXIT', Pid, _Reason} ->
+ receive
+ {_, {ssl_closed, Socket}} ->
+ test_server:format("Socket closed ~p~n",[Socket]);
+ Unexpected ->
+ test_server:format("Unexpected ~p~n",[Unexpected]),
+ test_server:fail({line, ?LINE-1})
+ after 5000 ->
+ test_server:fail({timeout, {line, ?LINE, Where}})
+ end;
+ Unexpected ->
+ test_server:format("Unexpected ~p~n",[Unexpected]),
+ test_server:fail({line, ?LINE-1})
+ after 5000 ->
+ test_server:fail({timeout, {line, ?LINE, Where}})
+ end.
+
+%%--------------------------------------------------------------------
+peercert(doc) ->
+ [""];
+
+peercert(suite) ->
+ [];
+
+peercert(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, peercert_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, peercert_result, []}},
+ {options, ClientOpts}]),
+
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ {ok, [{cert, BinCert, _}]} = public_key:pem_to_der(CertFile),
+ {ok, ErlCert} = public_key:pkix_decode_cert(BinCert, otp),
+
+ ServerMsg = {{error, no_peercert}, {error, no_peercert}},
+ ClientMsg = {{ok, BinCert}, {ok, ErlCert}},
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+peercert_result(Socket) ->
+ Result1 = ssl:peercert(Socket),
+ Result2 = ssl:peercert(Socket, [ssl]),
+ {Result1, Result2}.
+
+%%--------------------------------------------------------------------
+connect_dist(doc) ->
+ ["Test a simple connect as is used by distribution"];
+
+connect_dist(suite) ->
+ [];
+
+connect_dist(Config) when is_list(Config) ->
+ ClientOpts0 = ?config(client_kc_opts, Config),
+ ClientOpts = [{ssl_imp, new},{active, false}, {packet,4}|ClientOpts0],
+ ServerOpts0 = ?config(server_kc_opts, Config),
+ ServerOpts = [{ssl_imp, new},{active, false}, {packet,4}|ServerOpts0],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connect_dist_s, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connect_dist_c, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+connect_dist_s(S) ->
+ Msg = term_to_binary({erlang,term}),
+ ok = ssl:send(S, <<(size(Msg)):32, Msg/binary>>).
+
+connect_dist_c(S) ->
+ Test = binary_to_list(term_to_binary({erlang,term})),
+ {ok, Test} = ssl:recv(S, 0, 10000),
+ ok.
+
+
+%%--------------------------------------------------------------------
+peername(doc) ->
+ ["Test API function peername/1"];
+
+peername(suite) ->
+ [];
+
+peername(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, peername_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, peername_result, []}},
+ {options, [{port, 0} | ClientOpts]}]),
+
+ ClientPort = ssl_test_lib:inet_port(Client),
+ ServerIp = ssl_test_lib:node_to_hostip(ServerNode),
+ ClientIp = ssl_test_lib:node_to_hostip(ClientNode),
+ ServerMsg = {ok, {ClientIp, ClientPort}},
+ ClientMsg = {ok, {ServerIp, Port}},
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+peername_result(S) ->
+ ssl:peername(S).
+
+%%--------------------------------------------------------------------
+sockname(doc) ->
+ ["Test API function sockname/1"];
+
+sockname(suite) ->
+ [];
+
+sockname(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, sockname_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, sockname_result, []}},
+ {options, [{port, 0} | ClientOpts]}]),
+ ClientPort = ssl_test_lib:inet_port(Client),
+ ServerIp = ssl_test_lib:node_to_hostip(ServerNode),
+ ClientIp = ssl_test_lib:node_to_hostip(ClientNode),
+ ServerMsg = {ok, {ServerIp, Port}},
+ ClientMsg = {ok, {ClientIp, ClientPort}},
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+sockname_result(S) ->
+ ssl:sockname(S).
+
+%%--------------------------------------------------------------------
+cipher_suites(doc) ->
+ ["Test API function cipher_suites/0"];
+
+cipher_suites(suite) ->
+ [];
+
+cipher_suites(Config) when is_list(Config) ->
+ MandatoryCipherSuite = {rsa,'3des_ede_cbc',sha,no_export},
+ [_|_] = Suites = ssl:cipher_suites(),
+ true = lists:member(MandatoryCipherSuite, Suites).
+%%--------------------------------------------------------------------
+socket_options(doc) ->
+ ["Test API function getopts/2 and setopts/2"];
+
+socket_options(suite) ->
+ [];
+
+socket_options(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Values = [{mode, list}, {packet, 0}, {header, 0},
+ {active, true}],
+ %% Shall be the reverse order of Values!
+ Options = [active, header, packet, mode],
+
+ NewValues = [{mode, binary}, {active, once}],
+ %% Shall be the reverse order of NewValues!
+ NewOptions = [active, mode],
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
+ %% Test get/set emulated opts
+ {ok, DefaultValues} = ssl:getopts(Socket, Options),
+ ssl:setopts(Socket, NewValues),
+ {ok, NewValues} = ssl:getopts(Socket, NewOptions),
+ %% Test get/set inet opts
+ {ok,[{nodelay,false}]} = ssl:getopts(Socket, [nodelay]),
+ ok.
+
+%%--------------------------------------------------------------------
+versions(doc) ->
+ ["Test API function versions/0"];
+
+versions(suite) ->
+ [];
+
+versions(Config) when is_list(Config) ->
+ [_|_] = Versions = ssl:versions(),
+ test_server:format("~p~n", [Versions]).
+
+%%--------------------------------------------------------------------
+send_recv(doc) ->
+ [""];
+
+send_recv(suite) ->
+ [];
+
+send_recv(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+send_close(doc) ->
+ [""];
+
+send_close(suite) ->
+ [];
+
+send_close(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {ok, TcpS} = rpc:call(ClientNode, gen_tcp, connect,
+ [Hostname,Port,[binary, {active, false}, {reuseaddr, true}]]),
+ {ok, SslS} = rpc:call(ClientNode, ssl, connect,
+ [TcpS,[{active, false}|ClientOpts]]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), self(), Server]),
+ ok = ssl:send(SslS, "HejHopp"),
+ {ok,<<"Hejhopp">>} = ssl:recv(SslS, 7),
+ gen_tcp:close(TcpS),
+ {error, _} = ssl:send(SslS, "HejHopp"),
+ ssl_test_lib:close(Server).
+
+%%--------------------------------------------------------------------
+upgrade(doc) ->
+ ["Test that you can upgrade an tcp connection to an ssl connection"];
+
+upgrade(suite) ->
+ [];
+
+upgrade(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_upgrade_client([{node, ClientNode},
+ {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+upgrade_result(Socket) ->
+ ok = ssl:send(Socket, "Hejhopp"),
+ %% Make sure binary is inherited from tcp socket and that we do
+ %% not get the list default!
+ receive
+ {ssl, _, <<"Hejhopp">>} ->
+ ok
+ end.
+
+%%--------------------------------------------------------------------
+upgrade_with_timeout(doc) ->
+ ["Test ssl_accept/3"];
+
+upgrade_with_timeout(suite) ->
+ [];
+
+upgrade_with_timeout(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE,
+ upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_upgrade_client([{node, ClientNode},
+ {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+ipv6(doc) ->
+ ["Test ipv6."];
+ipv6(suite) ->
+ [];
+ipv6(Config) when is_list(Config) ->
+ {ok, Hostname0} = inet:gethostname(),
+
+ case lists:member(list_to_atom(Hostname0), ?config(ipv6_hosts, Config)) of
+ true ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} =
+ ssl_test_lib:run_where(Config, ipv6),
+ Server = ssl_test_lib:start_server([{node, ServerNode},
+ {port, 0}, {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options,
+ [inet6, {active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options,
+ [inet6, {active, false} | ClientOpts]}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client);
+ false ->
+ {skip, "Host does not support IPv6"}
+ end.
+
+%%--------------------------------------------------------------------
+
+ekeyfile(doc) ->
+ ["Test what happens with an invalid key file"];
+
+ekeyfile(suite) ->
+ [];
+
+ekeyfile(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ BadOpts = ?config(server_bad_key, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Port = ssl_test_lib:inet_port(ServerNode),
+
+ Server =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, BadOpts}]),
+ Client =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()}, {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, {error, ekeyfile}, Client,
+ {error, closed}).
+
+%%--------------------------------------------------------------------
+
+ecertfile(doc) ->
+ ["Test what happens with an invalid cert file"];
+
+ecertfile(suite) ->
+ [];
+
+ecertfile(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerBadOpts = ?config(server_bad_cert, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Port = ssl_test_lib:inet_port(ServerNode),
+
+ Server0 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, ServerBadOpts}]),
+ Client0 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server0, {error, ecertfile}, Client0,
+ {error, closed}).
+
+
+%%--------------------------------------------------------------------
+ecacertfile(doc) ->
+ ["Test what happens with an invalid cacert file"];
+
+ecacertfile(suite) ->
+ [];
+
+ecacertfile(Config) when is_list(Config) ->
+ ClientOpts = [{reuseaddr, true}|?config(client_opts, Config)],
+ ServerBadOpts = [{reuseaddr, true}|?config(server_bad_ca, Config)],
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Port = ssl_test_lib:inet_port(ServerNode),
+
+ Server0 =
+ ssl_test_lib:start_server_error([{node, ServerNode},
+ {port, Port}, {from, self()},
+ {options, ServerBadOpts}]),
+ Client0 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server0, {error, ecacertfile},
+ Client0, {error, closed}),
+
+ File0 = proplists:get_value(cacertfile, ServerBadOpts),
+ File = File0 ++ "do_not_exit.pem",
+ ServerBadOpts1 = [{cacertfile, File}|proplists:delete(cacertfile, ServerBadOpts)],
+
+ Server1 =
+ ssl_test_lib:start_server_error([{node, ServerNode},
+ {port, Port}, {from, self()},
+ {options, ServerBadOpts1}]),
+ Client1 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server1, {error, ecacertfile},
+ Client1, {error, closed}),
+ ok.
+
+
+
+%%--------------------------------------------------------------------
+eoptions(doc) ->
+ ["Test what happens when we give invalid options"];
+
+eoptions(suite) ->
+ [];
+
+eoptions(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Port = ssl_test_lib:inet_port(ServerNode),
+
+ %% Emulated opts
+ Server0 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{active, trice} | ServerOpts]}]),
+ Client0 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, [{active, trice} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server0, {error, {eoptions, {active,trice}}},
+ Client0, {error, {eoptions, {active,trice}}}),
+
+ test_server:sleep(500),
+
+ Server1 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{header, a} | ServerOpts]}]),
+ Client1 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{header, a} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server1, {error, {eoptions, {header, a}}},
+ Client1, {error, {eoptions, {header, a}}}),
+
+ test_server:sleep(500),
+
+
+ Server2 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{mode, a} | ServerOpts]}]),
+
+ Client2 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, [{mode, a} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server2, {error, {eoptions, {mode, a}}},
+ Client2, {error, {eoptions, {mode, a}}}),
+
+
+ test_server:sleep(500),
+
+ Server3 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{packet, 8.0} | ServerOpts]}]),
+ Client3 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, [{packet, 8.0} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server3, {error, {eoptions, {packet, 8.0}}},
+ Client3, {error, {eoptions, {packet, 8.0}}}),
+
+ test_server:sleep(500),
+
+ %% ssl
+ Server4 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{verify, 4} | ServerOpts]}]),
+ Client4 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{verify, 4} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server4, {error, {eoptions, {verify, 4}}},
+ Client4, {error, {eoptions, {verify, 4}}}),
+
+ test_server:sleep(500),
+
+ Server5 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{depth, four} | ServerOpts]}]),
+ Client5 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{depth, four} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server5, {error, {eoptions, {depth, four}}},
+ Client5, {error, {eoptions, {depth, four}}}),
+
+ test_server:sleep(500),
+
+ Server6 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{cacertfile, ""} | ServerOpts]}]),
+ Client6 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{cacertfile, ""} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server6, {error, {eoptions, {cacertfile, ""}}},
+ Client6, {error, {eoptions, {cacertfile, ""}}}),
+
+
+ test_server:sleep(500),
+
+ Server7 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{certfile, 'cert.pem'} | ServerOpts]}]),
+ Client7 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{certfile, 'cert.pem'} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server7,
+ {error, {eoptions, {certfile, 'cert.pem'}}},
+ Client7, {error, {eoptions, {certfile, 'cert.pem'}}}),
+
+ test_server:sleep(500),
+
+ Server8 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{keyfile,'key.pem' } | ServerOpts]}]),
+ Client8 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()}, {options, [{keyfile, 'key.pem'}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server8,
+ {error, {eoptions, {keyfile, 'key.pem'}}},
+ Client8, {error, {eoptions, {keyfile, 'key.pem'}}}),
+
+ test_server:sleep(500),
+
+ Server9 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{key, 'key.pem' } | ServerOpts]}]),
+ Client9 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()}, {options, [{key, 'key.pem'}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server9, {error, {eoptions, {key, 'key.pem'}}},
+ Client9, {error, {eoptions, {key, 'key.pem'}}}),
+
+
+ test_server:sleep(500),
+
+ Server10 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{password, foo} | ServerOpts]}]),
+ Client10 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{password, foo} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server10, {error, {eoptions, {password, foo}}},
+ Client10, {error, {eoptions, {password, foo}}}),
+
+ test_server:sleep(500),
+
+ %% Misc
+ Server11 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{ssl_imp, cool} | ServerOpts]}]),
+ Client11 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{ssl_imp, cool} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server11, {error, {eoptions, {ssl_imp, cool}}},
+ Client11, {error, {eoptions, {ssl_imp, cool}}}),
+
+
+ test_server:sleep(500),
+
+ Server12 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{debug, cool} | ServerOpts]}]),
+ Client12 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{debug, cool} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server12, {error, {eoptions, {debug, cool}}},
+ Client12, {error, {eoptions, {debug, cool}}}).
+
+%%--------------------------------------------------------------------
+shutdown(doc) ->
+ [""];
+
+shutdown(suite) ->
+ [];
+
+shutdown(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_result, [server]}},
+ {options, [{exit_on_close, false},
+ {active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, shutdown_result, [client]}},
+ {options,
+ [{exit_on_close, false},
+ {active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+shutdown_result(Socket, server) ->
+ ssl:send(Socket, "Hej"),
+ ssl:shutdown(Socket, write),
+ {ok, "Hej hopp"} = ssl:recv(Socket, 8),
+ ok;
+
+shutdown_result(Socket, client) ->
+ {ok, "Hej"} = ssl:recv(Socket, 3),
+ ssl:send(Socket, "Hej hopp"),
+ ssl:shutdown(Socket, write),
+ ok.
+
+%%--------------------------------------------------------------------
+shutdown_write(doc) ->
+ [""];
+
+shutdown_write(suite) ->
+ [];
+
+shutdown_write(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_write_result, [server]}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_write_result, [client]}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, {error, closed}).
+
+shutdown_write_result(Socket, server) ->
+ test_server:sleep(500),
+ ssl:shutdown(Socket, write);
+shutdown_write_result(Socket, client) ->
+ ssl:recv(Socket, 0).
+
+%%--------------------------------------------------------------------
+shutdown_both(doc) ->
+ [""];
+
+shutdown_both(suite) ->
+ [];
+
+shutdown_both(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_both_result, [server]}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_both_result, [client]}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, {error, closed}).
+
+shutdown_both_result(Socket, server) ->
+ test_server:sleep(500),
+ ssl:shutdown(Socket, read_write);
+shutdown_both_result(Socket, client) ->
+ ssl:recv(Socket, 0).
+
+%%--------------------------------------------------------------------
+shutdown_error(doc) ->
+ [""];
+
+shutdown_error(suite) ->
+ [];
+
+shutdown_error(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ Port = ssl_test_lib:inet_port(node()),
+ {ok, Listen} = ssl:listen(Port, ServerOpts),
+ {error, enotconn} = ssl:shutdown(Listen, read_write),
+ ok = ssl:close(Listen),
+ {error, closed} = ssl:shutdown(Listen, read_write).
+
+%%--------------------------------------------------------------------
+ciphers(doc) ->
+ [""];
+
+ciphers(suite) ->
+ [];
+
+ciphers(Config) when is_list(Config) ->
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ Ciphers = ssl:cipher_suites(),
+ Result = lists:map(fun(Cipher) ->
+ cipher(Cipher, Version, Config) end,
+ Ciphers),
+ case lists:flatten(Result) of
+ [] ->
+ ok;
+ Error ->
+ test_server:format("Cipher suite errors: ~p~n", [Error]),
+ test_server:fail(cipher_suite_failed_see_test_case_log)
+ end.
+
+cipher(CipherSuite, Version, Config) ->
+ process_flag(trap_exit, true),
+ test_server:format("Testing CipherSuite ~p~n", [CipherSuite]),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options,
+ [{ciphers,[CipherSuite]} |
+ ClientOpts]}]),
+
+ ServerMsg = ClientMsg = {ok, {Version, CipherSuite}},
+
+ Result = ssl_test_lib:wait_for_result(Server, ServerMsg,
+ Client, ClientMsg),
+ ssl_test_lib:close(Server),
+ receive
+ {'EXIT', Server, normal} ->
+ ok
+ end,
+ ssl_test_lib:close(Client),
+ receive
+ {'EXIT', Client, normal} ->
+ ok
+ end,
+ process_flag(trap_exit, false),
+ case Result of
+ ok ->
+ [];
+ Error ->
+ [{CipherSuite, Error}]
+ end.
+
+%%--------------------------------------------------------------------
+reuse_session(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+reuse_session(suite) ->
+ [];
+
+reuse_session(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ test_server:format("Expected: ~p, Unexpected: ~p~n",
+ [SessionInfo, Other]),
+ test_server:fail(session_not_reused)
+ end,
+
+ Server ! listen,
+
+ Client2 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, [{reuse_sessions, false}
+ | ClientOpts]}]),
+ receive
+ {Client2, SessionInfo} ->
+ test_server:fail(
+ session_reused_when_session_reuse_disabled_by_client);
+ {Client2, _} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ ssl_test_lib:close(Client2),
+
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, [{reuse_sessions, false} | ServerOpts]}]),
+
+ Port1 = ssl_test_lib:inet_port(Server1),
+ Client3 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ SessionInfo1 =
+ receive
+ {Server1, Info1} ->
+ Info1
+ end,
+
+ Server1 ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client4 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ receive
+ {Client4, SessionInfo1} ->
+ test_server:fail(
+ session_reused_when_session_reuse_disabled_by_server);
+ {Client4, _Other} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client3),
+ ssl_test_lib:close(Client4),
+ process_flag(trap_exit, false).
+
+
+session_info_result(Socket) ->
+ ssl:session_info(Socket).
+
+%%--------------------------------------------------------------------
+reuse_session_expired(doc) ->
+ ["Test sessions is not reused when it has expired"];
+
+reuse_session_expired(suite) ->
+ [];
+
+reuse_session_expired(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ test_server:format("Expected: ~p, Unexpected: ~p~n",
+ [SessionInfo, Other]),
+ test_server:fail(session_not_reused)
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is unregistered due to expiration
+ test_server:sleep((?EXPIRE+1) * 1000),
+
+ Client2 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client2, SessionInfo} ->
+ test_server:fail(session_reused_when_session_expired);
+ {Client2, _} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ ssl_test_lib:close(Client2),
+ process_flag(trap_exit, false).
+%%--------------------------------------------------------------------
+server_does_not_want_to_reuse_session(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+server_does_not_want_to_reuse_session(suite) ->
+ [];
+
+server_does_not_want_to_reuse_session(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, [{reuse_session, fun(_,_,_,_) ->
+ false
+ end} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ test_server:fail(session_reused_when_server_does_not_want_to);
+ {Client1, _Other} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ process_flag(trap_exit, false).
+
+%%--------------------------------------------------------------------
+
+server_verify_peer_passive(doc) ->
+ ["Test server option verify_peer"];
+
+server_verify_peer_passive(suite) ->
+ [];
+
+server_verify_peer_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false}, {verify, verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+server_verify_peer_active(doc) ->
+ ["Test server option verify_peer"];
+
+server_verify_peer_active(suite) ->
+ [];
+
+server_verify_peer_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true}, {verify, verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+server_verify_peer_active_once(doc) ->
+ ["Test server option verify_peer"];
+
+server_verify_peer_active_once(suite) ->
+ [];
+
+server_verify_peer_active_once(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once}, {verify, verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+server_verify_none_passive(doc) ->
+ ["Test server option verify_none"];
+
+server_verify_none_passive(suite) ->
+ [];
+
+server_verify_none_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false}, {verify, verify_none}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+server_verify_none_active(doc) ->
+ ["Test server option verify_none"];
+
+server_verify_none_active(suite) ->
+ [];
+
+server_verify_none_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true}, {verify, verify_none} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+server_verify_none_active_once(doc) ->
+ ["Test server option verify_none"];
+
+server_verify_none_active_once(suite) ->
+ [];
+
+server_verify_none_active_once(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once}, {verify, verify_none}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+
+server_verify_no_cacerts(doc) ->
+ ["Test server must have cacerts if it wants to verify client"];
+
+server_verify_no_cacerts(suite) ->
+ [];
+
+server_verify_no_cacerts(Config) when is_list(Config) ->
+ ServerOpts = ServerOpts = ?config(server_opts, Config),
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [{verify, verify_peer}
+ | ServerOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, {eoptions, {cacertfile, ""}}}).
+
+%%--------------------------------------------------------------------
+
+client_verify_none_passive(doc) ->
+ ["Test client option verify_none"];
+
+client_verify_none_passive(suite) ->
+ [];
+
+client_verify_none_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false},
+ {verify, verify_none}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+client_verify_none_active(doc) ->
+ ["Test client option verify_none"];
+
+client_verify_none_active(suite) ->
+ [];
+
+client_verify_none_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_active, []}},
+ {options, [{active, true}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_active, []}},
+ {options, [{active, true},
+ {verify, verify_none}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+client_verify_none_active_once(doc) ->
+ ["Test client option verify_none"];
+
+client_verify_none_active_once(suite) ->
+ [];
+
+client_verify_none_active_once(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ %% TODO: send message to test process to make sure
+ %% verifyfun has beeen run as it has the same behavior as
+ %% the default fun
+ VerifyFun = fun([{bad_cert, unknown_ca}]) ->
+ true;
+ (_) ->
+ false
+ end,
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_active_once,
+ []}},
+ {options, [{active, once},
+ {verify, verify_none},
+ {verify_fun, VerifyFun}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+send_recv_result(Socket) ->
+ ssl:send(Socket, "Hejhopp"),
+ test_server:sleep(100),
+ {ok,"Hejhopp"} = ssl:recv(Socket, 7),
+ ok.
+
+send_recv_result_active(Socket) ->
+ ssl:send(Socket, "Hejhopp"),
+ test_server:sleep(100),
+ receive
+ {ssl, Socket, "Hejhopp"} ->
+ ok
+ end.
+
+send_recv_result_active_once(Socket) ->
+ ssl:send(Socket, "Hejhopp"),
+ test_server:sleep(100),
+ receive
+ {ssl, Socket, "Hejhopp"} ->
+ ok
+ end.
+
+session_cache_process_list(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+session_cache_process_list(suite) ->
+ [];
+session_cache_process_list(Config) when is_list(Config) ->
+ session_cache_process(list,Config).
+
+session_cache_process_mnesia(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+session_cache_process_mnesia(suite) ->
+ [];
+session_cache_process_mnesia(Config) when is_list(Config) ->
+ session_cache_process(mnesia,Config).
+
+session_cache_process(Type,Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ setup_session_cb(Type),
+
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options,
+ [{session_cache_cb, ?MODULE}|
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ test_server:format("Expected: ~p, Unexpected: ~p~n",
+ [SessionInfo, Other]),
+ test_server:fail(session_not_reused)
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options,
+ [{reuse_sessions, false} | ServerOpts]}]),
+ Port1 = ssl_test_lib:inet_port(Server1),
+
+ Client3 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ SessionInfo1 =
+ receive
+ {Server1, Info1} ->
+ Info1
+ end,
+
+ Server1 ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client4 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ receive
+ {Client4, SessionInfo1} ->
+ test_server:fail(
+ session_reused_when_session_reuse_disabled_by_server);
+ {Client4, _Other} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client3),
+ ssl_test_lib:close(Client4),
+ process_flag(trap_exit, false).
+
+setup_session_cb(Type) ->
+ ssl_test = ets:new(ssl_test,[named_table, set,public]),
+ ets:insert(ssl_test, {type,Type}).
+
+session_cb() ->
+ [{type,Type}] = ets:lookup(ssl_test, type),
+ Type.
+
+init() ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ spawn(fun() -> session_loop([]) end);
+ mnesia ->
+ mnesia:start(),
+ {atomic,ok} = mnesia:create_table(sess_cache, [])
+ end.
+
+terminate(Cache) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! terminate;
+ mnesia ->
+ {atomic,ok} = mnesia:delete_table(sess_cache, [])
+ end.
+
+lookup(Cache, Key) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {self(), lookup, Key},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ case mnesia:transaction(fun() ->
+ mnesia:read(sess_cache,
+ Key, read)
+ end) of
+ {atomic, [Session]} -> Session;
+ _ -> undefined
+ end
+ end.
+
+update(Cache, Key, Value) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {update, Key, Value};
+ mnesia ->
+ {atomic, ok} =
+ mnesia:transaction(fun() ->
+ mnesia:write(sess_cache,
+ Key, Value)
+ end)
+ end.
+
+delete(Cache, Key) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {delete, Key};
+ mnesia ->
+ {atomic, ok} =
+ mnesia:transaction(fun() ->
+ mnesia:delete(sess_cache, Key)
+ end)
+ end.
+
+foldl(Fun, Acc, Cache) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {self(),foldl,Fun,Acc},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ Foldl = fun() ->
+ mnesia:foldl(Fun, Acc, sess_cache)
+ end,
+ {atomic, Res} = mnesia:transaction(Foldl),
+ Res
+ end.
+
+select_session(Cache, PartialKey) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {self(),select_session, PartialKey},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ Sel = fun() ->
+ mnesia:select(Cache,
+ [{{{PartialKey,'$1'}, '$2'},
+ [],['$$']}])
+ end,
+ {atomic, Res} = mnesia:transaction(Sel),
+ Res
+ end.
+
+session_loop(Sess) ->
+ receive
+ terminate ->
+ ok;
+ {Pid, lookup, Key} ->
+ case lists:keysearch(Key,1,Sess) of
+ {value, {Key,Value}} ->
+ Pid ! {self(), Value};
+ _ ->
+ Pid ! {self(), undefined}
+ end,
+ session_loop(Sess);
+ {update, Key, Value} ->
+ session_loop([{Key,Value}|Sess]);
+ {delete, Key} ->
+ session_loop(lists:keydelete(Key,1,Sess));
+ {Pid,foldl,Fun,Acc} ->
+ Res = lists:foldl(Fun, Acc,Sess),
+ Pid ! {self(), Res},
+ session_loop(Sess);
+ {Pid,select_session,PKey} ->
+ Sel = fun({{Head, _},Session}, Acc) when Head =:= PKey ->
+ [Session|Acc];
+ (_,Acc) ->
+ Acc
+ end,
+ Pid ! {self(), lists:foldl(Sel, [], Sess)},
+ session_loop(Sess)
+ end.
+
diff --git a/lib/ssl/test/ssl_basic_SUITE_data/RAND b/lib/ssl/test/ssl_basic_SUITE_data/RAND
new file mode 100644
index 0000000000..70997bd01f
--- /dev/null
+++ b/lib/ssl/test/ssl_basic_SUITE_data/RAND
Binary files differ
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
new file mode 100644
index 0000000000..c59a5c9256
--- /dev/null
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -0,0 +1,1486 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_packet_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(BYTE(X), X:8/unsigned-big-integer).
+-define(UINT16(X), X:16/unsigned-big-integer).
+-define(UINT24(X), X:24/unsigned-big-integer).
+-define(UINT32(X), X:32/unsigned-big-integer).
+-define(UINT64(X), X:64/unsigned-big-integer).
+-define(STRING(X), ?UINT32((size(X))), (X)/binary).
+
+-define(byte(X), << ?BYTE(X) >> ).
+-define(uint16(X), << ?UINT16(X) >> ).
+-define(uint24(X), << ?UINT24(X) >> ).
+-define(uint32(X), << ?UINT32(X) >> ).
+-define(uint64(X), << ?UINT64(X) >> ).
+-define(TIMEOUT, 120000).
+
+-define(MANY, 1000).
+-define(SOME, 50).
+
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initialization before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ crypto:start(),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config))),
+ test_server:format("Make certs ~p~n", [Result]),
+ ssl_test_lib:cert_options(Config).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ssl:stop(),
+ crypto:stop().
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initialization before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initialization before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ssl_test_lib:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test that erlang:decode_packet/3 seems to be handled correctly."
+ "We only use the most basic packet types in our tests as testing of"
+ "the packet types are for inet to verify"
+ ];
+
+all(suite) ->
+ [packet_raw_passive_many_small,
+ packet_0_passive_many_small, packet_1_passive_many_small,
+ packet_2_passive_many_small, packet_4_passive_many_small,
+ packet_raw_passive_some_big, packet_0_passive_some_big,
+ packet_1_passive_some_big,
+ packet_2_passive_some_big, packet_4_passive_some_big,
+ packet_raw_active_once_many_small,
+ packet_0_active_once_many_small, packet_1_active_once_many_small,
+ packet_2_active_once_many_small, packet_4_active_once_many_small,
+ packet_raw_active_once_some_big,
+ packet_0_active_once_some_big, packet_1_active_once_some_big,
+ packet_2_active_once_some_big, packet_4_active_once_some_big,
+ packet_raw_active_many_small, packet_0_active_many_small,
+ packet_1_active_many_small,
+ packet_2_active_many_small, packet_4_active_many_small,
+ packet_raw_active_some_big, packet_0_active_some_big,
+ packet_1_active_some_big, packet_2_active_some_big,
+ packet_4_active_some_big,
+ packet_wait_passive, packet_wait_active,
+ packet_baddata_passive, packet_baddata_active,
+ packet_size_passive, packet_size_active
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+packet_raw_passive_many_small(doc) ->
+ ["Test packet option {packet, raw} in passive mode."];
+
+packet_raw_passive_many_small(suite) ->
+ [];
+
+packet_raw_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, raw}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?MANY]}},
+ {options,
+ [{active, false},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+packet_raw_passive_some_big(doc) ->
+ ["Test packet option {packet, raw} in passive mode."];
+
+packet_raw_passive_some_big(suite) ->
+ [];
+
+packet_raw_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?SOME]}},
+ {options,
+ [{active, false},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_passive_many_small(doc) ->
+ ["Test packet option {packet, 0} in passive mode."];
+
+packet_0_passive_many_small(suite) ->
+ [];
+
+packet_0_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 0}, equivalent to packet raw.",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_passive_some_big(doc) ->
+ ["Test packet option {packet, 0} in passive mode."];
+
+packet_0_passive_some_big(suite) ->
+ [];
+
+packet_0_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_passive_many_small(doc) ->
+ ["Test packet option {packet, 1} in passive mode."];
+
+packet_1_passive_many_small(suite) ->
+ [];
+
+packet_1_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 1}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_passive_some_big(doc) ->
+ ["Test packet option {packet, 1} in passive mode."];
+
+packet_1_passive_some_big(suite) ->
+ [];
+
+packet_1_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(255, "1")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_passive_many_small(doc) ->
+ ["Test packet option {packet, 2} in passive mode"];
+
+packet_2_passive_many_small(suite) ->
+ [];
+
+packet_2_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 2}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_passive_some_big(doc) ->
+ ["Test packet option {packet, 2} in passive mode"];
+
+packet_2_passive_some_big(suite) ->
+ [];
+
+packet_2_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_passive_many_small(doc) ->
+ ["Test packet option {packet, 4} in passive mode"];
+
+packet_4_passive_many_small(suite) ->
+ [];
+
+packet_4_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 4}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, send_4 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_passive_some_big(doc) ->
+ ["Test packet option {packet, 4} in passive mode"];
+
+packet_4_passive_some_big(suite) ->
+ [];
+
+packet_4_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_4 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_raw_active_once_many_small(doc) ->
+ ["Test packet option {packet, raw} in active once mode."];
+
+packet_raw_active_once_many_small(suite) ->
+ [];
+
+packet_raw_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, raw}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_once_raw, [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_raw_active_once_some_big(doc) ->
+ ["Test packet option {packet, raw} in active once mode."];
+
+packet_raw_active_once_some_big(suite) ->
+ [];
+
+packet_raw_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_once_raw, [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_active_once_many_small(doc) ->
+ ["Test packet option {packet, 0} in active once mode."];
+
+packet_0_active_once_many_small(suite) ->
+ [];
+
+packet_0_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 0}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_once_raw,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_0_active_once_some_big(doc) ->
+ ["Test packet option {packet, 0} in active once mode."];
+
+packet_0_active_once_some_big(suite) ->
+ [];
+
+packet_0_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,
+ [Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_once_raw,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_active_once_many_small(doc) ->
+ ["Test packet option {packet, 1} in active once mode."];
+
+packet_1_active_once_many_small(suite) ->
+ [];
+
+packet_1_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 1}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_active_once_some_big(doc) ->
+ ["Test packet option {packet, 1} in active once mode."];
+
+packet_1_active_once_some_big(suite) ->
+ [];
+
+packet_1_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(255, "1")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_active_once_many_small(doc) ->
+ ["Test packet option {packet, 2} in active once mode"];
+
+packet_2_active_once_many_small(suite) ->
+ [];
+
+packet_2_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 2}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_2_active_once_some_big(doc) ->
+ ["Test packet option {packet, 2} in active once mode"];
+
+packet_2_active_once_some_big(suite) ->
+ [];
+
+packet_2_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_active_once_many_small(doc) ->
+ ["Test packet option {packet, 4} in active once mode"];
+
+packet_4_active_once_many_small(suite) ->
+ [];
+
+packet_4_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 4}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_4 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_active_once_some_big(doc) ->
+ ["Test packet option {packet, 4} in active once mode"];
+
+packet_4_active_once_some_big(suite) ->
+ [];
+
+packet_4_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_4 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_raw_active_many_small(doc) ->
+ ["Test packet option {packet, raw} in active mode."];
+
+packet_raw_active_many_small(suite) ->
+ [];
+
+packet_raw_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, raw}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_raw,
+ [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_raw_active_some_big(doc) ->
+ ["Test packet option {packet, raw} in active mode."];
+
+packet_raw_active_some_big(suite) ->
+ [];
+
+packet_raw_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_raw, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_active_many_small(doc) ->
+ ["Test packet option {packet, 0} in active mode."];
+
+packet_0_active_many_small(suite) ->
+ [];
+
+packet_0_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 0}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_raw,
+ [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_active_some_big(doc) ->
+ ["Test packet option {packet, 0} in active mode."];
+
+packet_0_active_some_big(suite) ->
+ [];
+
+packet_0_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_raw,
+ [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_1_active_many_small(doc) ->
+ ["Test packet option {packet, 1} in active mode."];
+
+packet_1_active_many_small(suite) ->
+ [];
+
+packet_1_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 1}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_active_some_big(doc) ->
+ ["Test packet option {packet, 1} in active mode."];
+
+packet_1_active_some_big(suite) ->
+ [];
+
+packet_1_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(255, "1")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_active_many_small(doc) ->
+ ["Test packet option {packet, 2} in active mode"];
+
+packet_2_active_many_small(suite) ->
+ [];
+
+packet_2_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 2}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_active_some_big(doc) ->
+ ["Test packet option {packet, 2} in active mode"];
+
+packet_2_active_some_big(suite) ->
+ [];
+
+packet_2_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_active_many_small(doc) ->
+ ["Test packet option {packet, 4} in active mode"];
+
+packet_4_active_many_small(suite) ->
+ [];
+
+packet_4_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 4}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_4 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_4_active_some_big(doc) ->
+ ["Test packet option {packet, 4} in active mode"];
+
+packet_4_active_some_big(suite) ->
+ [];
+
+packet_4_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_4 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+
+
+%%--------------------------------------------------------------------
+packet_wait_active(doc) ->
+ ["Test waiting when complete packages have not arrived"];
+
+packet_wait_active(suite) ->
+ [];
+
+packet_wait_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_packet,
+ [binary_to_list(Data), ?SOME]}},
+ {options, [{active, true},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_wait_passive(doc) ->
+ ["Test waiting when complete packages have not arrived"];
+
+packet_wait_passive(suite) ->
+ [];
+
+packet_wait_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [binary_to_list(Data), ?SOME]}},
+ {options, [{active, false},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_baddata_active(doc) ->
+ ["Test that if a bad packet arrives error msg is sent and socket is closed"];
+packet_baddata_active(suite) ->
+ [];
+
+packet_baddata_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_packet, [Data, 1]}},
+ {options, [{active, true},
+ {packet, cdr} |
+ ClientOpts]}]),
+ receive
+ {Client, {other, {ssl_error, _Socket, {invalid_packet, _}},{error,closed},1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_baddata_passive(doc) ->
+ ["Test that if a bad packet arrives error msg is sent and socket is closed"];
+
+packet_baddata_passive(suite) ->
+ [];
+
+packet_baddata_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, 1]}},
+ {options, [{active, false},
+ {packet, cdr} |
+ ClientOpts]}]),
+
+ receive
+ {Client, {other, {error, {invalid_packet, _}},{error,closed}, 1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_size_active(doc) ->
+ ["Test that if a packet of size larger than packet_size arrives error msg is sent and socket is closed"];
+packet_size_active(suite) ->
+ [];
+
+packet_size_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_packet, [Data, 1]}},
+ {options, [{active, true},
+ {packet, 4}, {packet_size, 10} |
+ ClientOpts]}]),
+ receive
+ {Client, {other, {ssl_error, _Socket, {invalid_packet, _}},{error,closed},1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_size_passive(doc) ->
+ ["Test that if a packet of size larger than packet_size arrives error msg is sent and socket is closed"];
+packet_size_passive(suite) ->
+ [];
+
+packet_size_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet, [Data, 1]}},
+ {options, [{active, false},
+ {packet, 4}, {packet_size, 30} |
+ ClientOpts]}]),
+ receive
+ {Client, {other, {error, {invalid_packet, _}},{error,closed},1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+%% Internal functions
+
+send_raw(_,_, 0) ->
+ no_result_msg;
+send_raw(Socket, Data, N) ->
+ ssl:send(Socket, Data),
+ send_raw(Socket, Data, N-1).
+
+passive_raw(_, _, 0) ->
+ ok;
+passive_raw(Socket, Data, N) ->
+ Length = length(Data),
+ {ok, Data} = ssl:recv(Socket, Length),
+ passive_raw(Socket, Data, N-1).
+
+passive_recv_packet(_, _, 0) ->
+ ok;
+passive_recv_packet(Socket, Data, N) ->
+ case ssl:recv(Socket, 0) of
+ {ok, Data} ->
+ passive_recv_packet(Socket, Data, N-1);
+ Other ->
+ {other, Other, ssl:session_info(Socket), N}
+ end.
+
+send_1(_,_, 0) ->
+ no_result_msg;
+send_1(Socket, Data, N) ->
+ Length = length(Data),
+ ssl:send(Socket, [?byte(Length), Data]),
+ send_1(Socket, Data, N-1).
+
+send_2(_,_, 0) ->
+ no_result_msg;
+send_2(Socket, Data, N) ->
+ Length = length(Data),
+ ssl:send(Socket, [?uint16(Length), Data]),
+ send_2(Socket, Data, N-1).
+
+send_4(_,_, 0) ->
+ no_result_msg;
+send_4(Socket, Data, N) ->
+ Length = length(Data),
+ ssl:send(Socket, [?uint32(Length), Data]),
+ send_4(Socket, Data, N-1).
+
+send_incomplete(Socket, Data, N) ->
+ send_incomplete(Socket, Data, N, <<>>).
+send_incomplete(Socket, _Data, 0, Prev) ->
+ ssl:send(Socket, Prev),
+ no_result_msg;
+send_incomplete(Socket, Data, N, Prev) ->
+ Length = size(Data),
+ <<Part1:42/binary, Rest/binary>> = Data,
+ ssl:send(Socket, [Prev, ?uint32(Length), Part1]),
+ send_incomplete(Socket, Data, N-1, Rest).
+
+active_once_raw(Socket, Data, N) ->
+ active_once_raw(Socket, Data, N, []).
+
+active_once_raw(_, _, 0, _) ->
+ ok;
+active_once_raw(Socket, Data, N, Acc) ->
+ receive
+ {ssl, Socket, Data} ->
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_raw(Socket, Data, N-1, []);
+ {ssl, Socket, Other} ->
+ case Acc ++ Other of
+ Data ->
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_raw(Socket, Data, N-1, []);
+ NewAcc ->
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_raw(Socket, Data, N, NewAcc)
+ end
+ end.
+
+active_once_packet(_,_, 0) ->
+ ok;
+active_once_packet(Socket, Data, N) ->
+ receive
+ {ssl, Socket, Data} ->
+ ok
+ end,
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_packet(Socket, Data, N-1).
+
+active_raw(Socket, Data, N) ->
+ active_raw(Socket, Data, N, []).
+
+active_raw(_, _, 0, _) ->
+ ok;
+active_raw(Socket, Data, N, Acc) ->
+ receive
+ {ssl, Socket, Data} ->
+ active_raw(Socket, Data, N-1, []);
+ {ssl, Socket, Other} ->
+ case Acc ++ Other of
+ Data ->
+ active_raw(Socket, Data, N-1, []);
+ NewAcc ->
+ active_raw(Socket, Data, NewAcc)
+ end
+ end.
+
+active_packet(_, _, 0) ->
+ ok;
+active_packet(Socket, Data, N) ->
+ receive
+ {ssl, Socket, Data} ->
+ active_packet(Socket, Data, N -1);
+ Other ->
+ {other, Other, ssl:session_info(Socket),N}
+ end.
diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl
new file mode 100644
index 0000000000..a0aa92bdf2
--- /dev/null
+++ b/lib/ssl/test/ssl_payload_SUITE.erl
@@ -0,0 +1,726 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ssl_payload_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(TIMEOUT, 600000).
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initialization before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ crypto:start(),
+ ssl:start(),
+ make_certs:all(?config(data_dir, Config), ?config(priv_dir, Config)),
+ ssl_test_lib:cert_options(Config).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ssl:stop(),
+ crypto:stop().
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initialization before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initialization before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ssl_test_lib:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test payload over ssl in all socket modes, active, active_once,"
+ "and passive mode."];
+
+all(suite) ->
+ [server_echos_passive_small, server_echos_active_once_small,
+ server_echos_active_small,
+ client_echos_passive_small, client_echos_active_once_small,
+ client_echos_active_small,
+ server_echos_passive_big, server_echos_active_once_big,
+ server_echos_active_big,
+ client_echos_passive_big, client_echos_active_once_big,
+ client_echos_active_big,
+ server_echos_passive_huge, server_echos_active_once_huge,
+ server_echos_active_huge,
+ client_echos_passive_huge, client_echos_active_once_huge,
+ client_echos_active_huge
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+server_echos_passive_small(doc) ->
+ ["Client sends 1000 bytes in passive mode to server, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_passive_small(suite) ->
+ [];
+
+server_echos_passive_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_passive(Str, 1000, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_once_small(doc) ->
+ ["Client sends 1000 bytes in active once mode to server, that receives "
+ " them, sends them back, and closes."];
+
+server_echos_active_once_small(suite) ->
+ [];
+
+server_echos_active_once_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active_once(Str, 1000, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_small(doc) ->
+ ["Client sends 1000 bytes in active mode to server, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_active_small(suite) ->
+ [];
+
+server_echos_active_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active(Str, 1000, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_passive_small(doc) ->
+ ["Server sends 1000 bytes in passive mode to client, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_passive_small(suite) ->
+ [];
+
+client_echos_passive_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_passive(Str, 1000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_once_small(doc) ->
+ ["Server sends 1000 bytes in active once mode to client, that receives "
+ "them, sends them back, and closes."];
+
+client_echos_active_once_small(suite) ->
+ [];
+
+client_echos_active_once_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active_once(Str, 1000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_small(doc) ->
+ ["Server sends 1000 bytes in active mode to client, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_active_small(suite) ->
+ [];
+
+client_echos_active_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active(Str, 1000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+
+%%--------------------------------------------------------------------
+server_echos_passive_big(doc) ->
+ ["Client sends 50000 bytes to server in passive mode, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_passive_big(suite) ->
+ [];
+
+server_echos_passive_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_passive(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_once_big(doc) ->
+ ["Client sends 50000 bytes to server in active once mode, that receives "
+ "them, sends them back, and closes."];
+
+server_echos_active_once_big(suite) ->
+ [];
+
+server_echos_active_once_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active_once(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_big(doc) ->
+ ["Client sends 50000 bytes to server in active once mode, that receives "
+ " them, sends them back, and closes."];
+
+server_echos_active_big(suite) ->
+ [];
+
+server_echos_active_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_passive_big(doc) ->
+ ["Server sends 50000 bytes to client in passive mode, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_passive_big(suite) ->
+ [];
+
+client_echos_passive_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_passive(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_once_big(doc) ->
+ ["Server sends 50000 bytes to client in active once mode, that receives"
+ " them, sends them back, and closes."];
+
+client_echos_active_once_big(suite) ->
+ [];
+
+client_echos_active_once_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active_once(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_big(doc) ->
+ ["Server sends 50000 bytes to client in active mode, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_active_big(suite) ->
+ [];
+
+client_echos_active_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+server_echos_passive_huge(doc) ->
+ ["Client sends 500000 bytes to server in passive mode, that receives "
+ " them, sends them back, and closes."];
+
+server_echos_passive_huge(suite) ->
+ [];
+
+server_echos_passive_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_passive(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+server_echos_active_once_huge(doc) ->
+ ["Client sends 500000 bytes to server in active once mode, that receives "
+ "them, sends them back, and closes."];
+
+server_echos_active_once_huge(suite) ->
+ [];
+
+server_echos_active_once_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active_once(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+server_echos_active_huge(doc) ->
+ ["Client sends 500000 bytes to server in active mode, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_active_huge(suite) ->
+ [];
+
+server_echos_active_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_passive_huge(doc) ->
+ ["Server sends 500000 bytes to client in passive mode, that receives "
+ "them, sends them back, and closes."];
+
+client_echos_passive_huge(suite) ->
+ [];
+
+client_echos_passive_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+ client_echos_passive(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_once_huge(doc) ->
+ ["Server sends 500000 bytes to client in active once mode, that receives "
+ "them, sends them back, and closes."];
+
+client_echos_active_once_huge(suite) ->
+ [];
+
+client_echos_active_once_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+ client_echos_active_once(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_huge(doc) ->
+ ["Server sends 500000 bytes to client in active mode, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_active_huge(suite) ->
+ [];
+
+client_echos_active_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+ client_echos_active(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_passive(Data, Length, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer,
+ [Data, Length]}},
+ {options,
+ [{active, false},{mode, binary}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender,
+ [Data,
+ Length]}},
+ {options,
+ [{active, false}, {mode, binary} |
+ ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+server_echos_active_once(Data, Length, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_once,
+ [Data, Length]}},
+ {options, [{active, once},
+ {mode, binary}|
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_once,
+ [Data, Length]}},
+ {options, [{active, once},
+ {mode, binary} |
+ ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+server_echos_active(Data, Length, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_active,
+ [Data, Length]}},
+ {options,
+ [{active, true},
+ {mode, binary} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_active,
+ [Data,
+ Length]}},
+ {options,
+ [{active, true}, {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+client_echos_passive(Data, Length, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender,
+ [Data, Length]}},
+ {options,
+ [{active, false}, {mode, binary} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer,
+ [Data,
+ Length]}},
+ {options,
+ [{active, false}, {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+client_echos_active_once(Data, Length,
+ ClientOpts, ServerOpts, ClientNode, ServerNode,
+ Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_once,
+ [Data, Length]}},
+ {options, [{active, once},
+ {mode, binary} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_once,
+ [Data,
+ Length]}},
+ {options,[{active, once},
+ {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+client_echos_active(Data, Length, ClientOpts, ServerOpts, ClientNode,
+ ServerNode,
+ Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_active,
+ [Data, Length]}},
+ {options, [{active, true},
+ {mode, binary}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_active,
+ [Data,
+ Length]}},
+ {options, [{active, true},
+ {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+send(_, _, _, 0,_) ->
+ ok;
+send(Socket, Data, Size, Repeate,F) ->
+ NewData = lists:duplicate(Size div 10, Data),
+ ssl:send(Socket, NewData),
+ F(),
+ send(Socket, Data, Size, Repeate - 1,F).
+
+sender(Socket, Data, Size) ->
+ ok = send(Socket, Data, Size, 100, fun() -> do_recv(Socket, Data, Size, <<>>, false) end),
+ test_server:format("Sender recv: ~p~n", [ssl:getopts(Socket, [active])]),
+ ok.
+
+sender_once(Socket, Data, Size) ->
+ send(Socket, Data, Size, 100,
+ fun() -> do_active_once(Socket, Data, Size, <<>>, false) end),
+ test_server:format("Sender active once: ~p~n",
+ [ssl:getopts(Socket, [active])]),
+ ok.
+
+sender_active(Socket, Data, Size) ->
+ F = fun() -> do_active(Socket, Data, Size, <<>>, false) end,
+ send(Socket, Data, Size, 100, F),
+ test_server:format("Sender active: ~p~n", [ssl:getopts(Socket, [active])]),
+ ok.
+
+echoer(Socket, Data, Size) ->
+ test_server:format("Echoer recv: ~p~n", [ssl:getopts(Socket, [active])]),
+ echo(fun() -> do_recv(Socket, Data, Size, <<>>, true) end, 100).
+
+echoer_once(Socket, Data, Size) ->
+ test_server:format("Echoer active once: ~p ~n",
+ [ssl:getopts(Socket, [active])]),
+ echo(fun() -> do_active_once(Socket, Data, Size, <<>>, true) end, 100).
+
+echoer_active(Socket, Data, Size) ->
+ test_server:format("Echoer active: ~p~n", [ssl:getopts(Socket, [active])]),
+ echo(fun() -> do_active(Socket, Data, Size, <<>>, true) end, 100).
+
+echo(_Fun, 0) -> ok;
+echo(Fun, N) ->
+ Fun(),
+ echo(Fun, N-1).
+
+
+do_recv(_Socket, _Data, 0, _Acc, true) ->
+ ok;
+do_recv(_Socket, Data, 0, Acc, false) ->
+ Data = lists:sublist(binary_to_list(Acc), 10);
+
+do_recv(Socket, Data, Size, Acc, Echo) ->
+ {ok, NewData} = ssl:recv(Socket, 0),
+ NewSize = size(NewData),
+ case Echo of
+ true ->
+ ssl:send(Socket, NewData),
+ NewSize = size(NewData),
+ do_recv(Socket, Data, Size - NewSize, [], Echo);
+ false ->
+ case size(Acc) < 10 of
+ true ->
+ do_recv(Socket, Data, Size - NewSize,
+ <<Acc/binary, NewData/binary>>, Echo);
+ false ->
+ do_recv(Socket, Data, Size - NewSize, Acc, Echo)
+ end
+ end.
+
+do_active_once(_Socket, _Data, 0, _Acc, true) ->
+ ok;
+do_active_once(_Socket, Data, 0, Acc, false) ->
+ Data = lists:sublist(binary_to_list(Acc), 10);
+
+do_active_once(Socket, Data, Size, Acc, Echo) ->
+ receive
+ {ssl, Socket, NewData} ->
+ NewSize = size(NewData),
+ case Echo of
+ true ->
+ ssl:send(Socket, NewData),
+ ssl:setopts(Socket, [{active, once}]),
+ do_active_once(Socket, Data, Size - NewSize, [], Echo);
+ false ->
+ case size(Acc) < 10 of
+ true ->
+ ssl:setopts(Socket, [{active, once}]),
+ do_active_once(Socket, Data, Size - NewSize,
+ <<Acc/binary, NewData/binary>>,
+ Echo);
+ false ->
+ ssl:setopts(Socket, [{active, once}]),
+ do_active_once(Socket, Data,
+ Size - NewSize, Acc, Echo)
+ end
+ end
+ end.
+
+do_active(_Socket, _Data, 0, _Acc, true) ->
+ ok;
+do_active(_Socket, Data, 0, Acc, false) ->
+ Data = lists:sublist(binary_to_list(Acc), 10);
+
+do_active(Socket, Data, Size, Acc, Echo) ->
+ receive
+ {ssl, Socket, NewData} ->
+ NewSize = size(NewData),
+ case Echo of
+ true ->
+ ssl:send(Socket, NewData),
+ do_active(Socket, Data, Size - NewSize, [], Echo);
+ false ->
+ case size(Acc) < 10 of
+ true ->
+ do_active(Socket, Data, Size - NewSize,
+ <<Acc/binary, NewData/binary>>,
+ Echo);
+ false ->
+ do_active(Socket, Data,
+ Size - NewSize, Acc, Echo)
+ end
+ end
+ end.
diff --git a/lib/ssl/test/ssl_test_MACHINE.erl b/lib/ssl/test/ssl_test_MACHINE.erl
new file mode 100644
index 0000000000..e75f7079ed
--- /dev/null
+++ b/lib/ssl/test/ssl_test_MACHINE.erl
@@ -0,0 +1,935 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_test_MACHINE).
+
+-export([many_conns/0, mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+
+-export([process_init/3, do_start/1]).
+
+
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(WAIT_TIMEOUT, 10000).
+-define(CLOSE_WAIT, 1000).
+
+%%
+%% many_conns() -> ManyConnections
+%%
+%% Choose a suitable number of "many connections" depending on platform
+%% and current limit for file descriptors.
+%%
+many_conns() ->
+ case os:type() of
+ {unix,_} -> many_conns_1();
+ _ -> 10
+ end.
+
+many_conns_1() ->
+ N0 = os:cmd("ulimit -n"),
+ N1 = lists:reverse(N0),
+ N2 = lists:dropwhile(fun($\r) -> true;
+ ($\n) -> true;
+ (_) -> false
+ end, N1),
+ N = list_to_integer(lists:reverse(N2)),
+ lists:min([(N - 10) div 2, 501]).
+
+%%
+%% mk_ssl_cert_opts(Config) -> {ok, {COpts, SOpts}}
+%%
+%%
+mk_ssl_cert_opts(_Config) ->
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ COpts = [{cacertfile, filename:join([Dir, "client", "cacerts.pem"])},
+ {certfile, filename:join([Dir, "client", "cert.pem"])},
+ {keyfile, filename:join([Dir, "client", "key.pem"])}],
+ SOpts = [{cacertfile, filename:join([Dir, "server", "cacerts.pem"])},
+ {certfile, filename:join([Dir, "server", "cert.pem"])},
+ {keyfile, filename:join([Dir, "server", "key.pem"])}],
+ {ok, {COpts, SOpts}}.
+
+%%
+%% Cmds:
+%% {protomod, gen_tcp | ssl} default = ssl
+%% {serialize_accept, true | false} default = false
+%% {timeout, Timeout}
+%% {sockopts, Opts}
+%% {sslopts, Opts}
+%% {protocols, Protocols} [sslv2|sslv3|tlsv1]
+%% {listen, Port}
+%% {lsock, LSock} listen socket for acceptor
+%% peercert
+%% accept
+%% {connect, {Host, Port}}
+%% {recv, N}
+%% {send, N}
+%% {echo, N} async echo back
+%% close close connection socket
+%% {close, Time} wait time and then close socket
+%% lclose close listen socket
+%% await_close wait for close
+%% wait_sync listener's wait for sync from parent
+%% connection_info
+%% {exit, Reason} exit
+%%
+%%
+%% We cannot have more than `backlog' acceptors at the same time.
+%%
+
+
+%%
+%% test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, Suite, Config)
+%%
+%% Creates one client and one server node, and runs one listener on
+%% the server node (according to LCmds), and creates NConns acceptors
+%% on the server node, and the same number of connectors on the client
+%% node. The acceptors and and connectors execute according to ACmds
+%% and CCmds, respectively.
+%%
+%% It is a good idea to have the backlog size in LCmds set to
+%% be at least as large as NConns.
+%%
+test_one_listener(NConns, LCmds0, ACmds0, CCmds0, Timeout, Suite, Config) ->
+ ProtoMod = get_protomod(Config),
+ SerializeAccept = get_serialize_accept(Config),
+ ?line {ok, {CNode, SNode}} = start_client_server_nodes(Suite),
+ case ProtoMod of
+ ssl ->
+ ?line ok = start_ssl([CNode, SNode], Config);
+ gen_tcp ->
+ ok
+ end,
+ LCmds = [{protomod, ProtoMod}| LCmds0],
+ ACmds = [{protomod, ProtoMod}, {serialize_accept, SerializeAccept}|
+ ACmds0],
+ CCmds = [{protomod, ProtoMod}| CCmds0],
+
+ ?line {ok, Listener} = start_process(SNode, self(), LCmds, listener),
+ ?line {ok, LSock} = wait_lsock(Listener, ?WAIT_TIMEOUT),
+ ?line {ok, Accs0} = start_processes(NConns, SNode, self(),
+ [{lsock, LSock}| ACmds], acceptor),
+ Accs = case ProtoMod of
+ gen_tcp ->
+ [Acc1| Accs1] = Accs0,
+ Acc1 ! {continue_accept, self()},
+ Accs1;
+ ssl ->
+ Accs0
+ end,
+ ?line {ok, Conns} = start_processes(NConns, CNode, self(),
+ CCmds, connector),
+ ?line case wait_ack(Accs, Accs0 ++ Conns, Timeout) of
+ ok ->
+ ?line sync([Listener]),
+ ?line wait_ack([], [Listener], ?WAIT_TIMEOUT);
+ {error, Reason} ->
+ ?line stop_node(SNode),
+ ?line stop_node(CNode),
+ exit(Reason)
+ end,
+ ?line stop_node(SNode),
+ ?line stop_node(CNode),
+ ok.
+
+%%
+%% test_server_only(NConns, LCmds, ACmds, Timeout, Suite, Config)
+%%
+%% Creates only one server node, and runs one listener on
+%% the server node (according to LCmds), and creates NConns acceptors
+%% on the server node. The acceptors execute according to ACmds.
+%% There are no connectors.
+%%
+test_server_only(NConns, LCmds0, ACmds0, Timeout, Suite, Config) ->
+ ProtoMod = get_protomod(Config),
+ ?line {ok, SNode} = start_server_node(Suite),
+ case ProtoMod of
+ ssl ->
+ ?line ok = start_ssl([SNode], Config);
+ gen_tcp ->
+ ok
+ end,
+ LCmds = [{protomod, ProtoMod}| LCmds0],
+ ACmds = [{protomod, ProtoMod}| ACmds0],
+ ?line {ok, Listener} = start_process(SNode, self(), LCmds, listener),
+ ?line {ok, LSock} = wait_lsock(Listener, ?WAIT_TIMEOUT),
+ ?line {ok, Accs0} = start_processes(NConns, SNode, self(),
+ [{lsock, LSock}| ACmds], acceptor),
+ Accs = case ProtoMod of
+ gen_tcp ->
+ [Acc1| Accs1] = Accs0,
+ Acc1 ! {continue_accept, self()},
+ Accs1;
+ ssl ->
+ Accs0
+ end,
+ ?line case wait_ack(Accs, Accs0, Timeout) of
+ ok ->
+ ?line sync([Listener]),
+ ?line wait_ack([], [Listener], ?WAIT_TIMEOUT);
+ {error, Reason} ->
+ ?line stop_node(SNode),
+ exit(Reason)
+ end,
+ ?line stop_node(SNode),
+ ok.
+
+%%
+%% start_client_server_nodes(Suite) -> {ok, {CNode, SNode}}
+%%
+start_client_server_nodes(Suite) ->
+ {ok, CNode} = start_client_node(Suite),
+ {ok, SNode} = start_server_node(Suite),
+ {ok, {CNode, SNode}}.
+
+start_client_node(Suite) ->
+ start_node(lists:concat([Suite, "_client"])).
+
+start_server_node(Suite) ->
+ start_node(lists:concat([Suite, "_server"])).
+
+%%
+%% start_ssl(Nodes, Config)
+%%
+start_ssl(Nodes, Config) ->
+ Env0 = lists:flatten([Env00 || {env, Env00} <- Config]),
+ Env1 = case os:getenv("SSL_DEBUG") of
+ false ->
+ [];
+ _ ->
+ Dir = ?config(priv_dir, Config),
+ [{debug, true}, {debugdir, Dir}]
+ end,
+ Env = Env0 ++ Env1,
+ lists:foreach(
+ fun(Node) -> rpc:call(Node, ?MODULE, do_start, [Env]) end, Nodes),
+ ok.
+
+do_start(Env) ->
+ application:load(ssl),
+ lists:foreach(
+ fun({Par, Val}) -> application:set_env(ssl, Par, Val) end, Env),
+ application:start(ssl),
+ application:start(crypto).
+
+%%
+%% start_node(Name) -> {ok, Node}
+%% start_node(Name, ExtraParams) -> {ok, Node}
+%%
+start_node(Name) ->
+ start_node(Name, []).
+start_node(Name, ExtraParams) ->
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++
+ ExtraParams,
+ test_server:start_node(Name, slave, [{args, Params}]).
+
+stop_node(Node) ->
+ test_server:stop_node(Node).
+
+%%
+%% start_processes(N, Node, Parent, Cmds, Type) -> {ok, Pids}
+%%
+start_processes(M, Node, Parent, Cmds, Type) ->
+ start_processes1(0, M, Node, Parent, Cmds, Type, []).
+start_processes1(M, M, _, _, _, _, Pids) ->
+ {ok, lists:reverse(Pids)};
+start_processes1(N, M, Node, Parent, Cmds, Type, Pids) ->
+ {ok, Pid} = start_process(Node, Parent, Cmds, {Type, N + 1}),
+ start_processes1(N + 1, M, Node, Parent, Cmds, Type, [Pid| Pids]).
+
+%%
+%% start_process(Node, Parent, Cmds, Type) -> {ok, Pid}
+%%
+start_process(Node, Parent, Cmds0, Type) ->
+ Cmds = case os:type() of
+ {win32, _} ->
+ lists:map(fun(close) -> {close, ?CLOSE_WAIT};
+ (Term) -> Term end, Cmds0);
+ _ ->
+ Cmds0
+ end,
+ Pid = spawn_link(Node, ?MODULE, process_init, [Parent, Cmds, Type]),
+ {ok, Pid}.
+
+process_init(Parent, Cmds, Type) ->
+ ?debug("#### ~w start~n", [{Type, self()}]),
+ pre_main_loop(Cmds, #st{parent = Parent, type = Type}).
+
+%%
+%% pre_main_loop
+%%
+pre_main_loop([], St) ->
+ ?debug("#### ~w end~n", [{St#st.type, self()}]),
+ main_loop([], St);
+pre_main_loop(Cmds, St) ->
+ ?debug("#### ~w -> ~w~n",
+ [{St#st.type, self(), St#st.sock, St#st.port,
+ St#st.peer, St#st.active}, hd(Cmds)]),
+ main_loop(Cmds, St).
+
+%%
+%% main_loop(Cmds, St)
+%%
+main_loop([{protomod, ProtoMod}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{protomod = ProtoMod});
+
+main_loop([{serialize_accept, Bool}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{serialize_accept = Bool});
+
+main_loop([{sockopts, Opts}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{sockopts = Opts});
+
+main_loop([{sslopts, Opts}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{sslopts = Opts});
+
+main_loop([{protocols, Protocols}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{protocols = Protocols});
+
+main_loop([{timeout, T}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{timeout = T});
+
+main_loop([{lsock, LSock}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{lsock = LSock});
+
+main_loop([{seed, Data}| Cmds], St) ->
+ case ssl:seed("tjosan") of
+ ok ->
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in seed: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([{listen, Port}| Cmds], St) ->
+ case listen(St, Port) of
+ {ok, LSock} ->
+ ack_lsock(St#st.parent, LSock),
+ NSt = get_active(St#st{port = Port, sock = LSock, lsock = LSock}),
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in listen: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([accept| Cmds], St) ->
+ case St#st.serialize_accept of
+ true ->
+ Parent = St#st.parent,
+ receive
+ {continue_accept, Parent} ->
+ ok
+ end;
+ false ->
+ ok
+ end,
+ case accept(St) of
+ {ok, Sock, Port, Peer} ->
+ case St#st.serialize_accept of
+ true ->
+ St#st.parent ! {one_accept_done, self()};
+ false ->
+ ok
+ end,
+ NSt = get_active(St#st{sock = Sock, port = Port, peer = Peer}),
+ pre_main_loop(Cmds, NSt);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in accept: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([accept_timeout| Cmds], St) ->
+ case accept(St) of
+ {error, timeout} ->
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in accept_timeout: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+
+main_loop([{connect, {Host, Port}}| Cmds], St) ->
+ case connect(St, Host, Port) of
+ {ok, Sock, LPort, Peer} ->
+ NSt = get_active(St#st{sock = Sock, port = LPort, peer = Peer}),
+ pre_main_loop(Cmds, NSt);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in connect: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([connection_info| Cmds], St) ->
+ case connection_info(St) of
+ {ok, ProtoInfo} ->
+ io:fwrite("Got connection_info:~n~p~n", [ProtoInfo]),
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in connection_info: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([peercert| Cmds], St) ->
+ case peercert(St) of
+ {ok, Cert} ->
+ io:fwrite("Got cert:~n~p~n", [Cert]),
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in peercert: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([nopeercert| Cmds], St) ->
+ case peercert(St) of
+ {error, Reason} ->
+ io:fwrite("Got no cert as expected. reason:~n~p~n", [Reason]),
+ pre_main_loop(Cmds, St);
+ {ok, Cert} ->
+ ?error("#### ~w(~w) in peercert: error: got cert: ~p~n",
+ [St#st.type, self(), Cert]),
+ exit(peercert)
+ end;
+
+main_loop([{recv, N}| Cmds], St) ->
+ recv_loop([{recv, N}| Cmds], fun recv/1, St); % Returns to main_loop/2.
+
+main_loop([{send, N}| Cmds], St) ->
+ Msg = mk_msg(N),
+ case send(St, Msg) of
+ ok ->
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in send: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([{echo, N}| Cmds], St) ->
+ recv_loop([{echo, N}| Cmds], fun echo/1, St); % Returns to main_loop/2.
+
+main_loop([{close, WaitTime}| Cmds], St) ->
+ wait(WaitTime),
+ pre_main_loop([close| Cmds], St);
+
+main_loop([close| Cmds], St) ->
+ case close(St) of
+ ok ->
+ pre_main_loop(Cmds, St#st{sock = nil});
+ {error, Reason} ->
+ ?error("#### ~w(~w) in close: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([lclose| Cmds], St) ->
+ case lclose(St) of
+ ok ->
+ pre_main_loop(Cmds, St#st{lsock = nil});
+ {error, Reason} ->
+ ?error("#### ~w(~w) in lclose: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([await_close| Cmds], St) ->
+ case await_close(St) of
+ ok ->
+ pre_main_loop(Cmds, St#st{sock = nil});
+ {error, Reason} ->
+ ?error("#### ~w(~w) in await_close: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([wait_sync| Cmds], St) ->
+ wait_sync(St),
+ pre_main_loop(Cmds, St);
+
+main_loop({exit, Reason}, _St) ->
+ exit(Reason);
+
+main_loop([], _St) ->
+ ok.
+
+%%
+%% recv_loop(Cmds, F, St)
+%%
+%% F = recv/1 | echo/1
+%%
+recv_loop([{_Tag, 0}| Cmds], _, St) ->
+ pre_main_loop(Cmds, St);
+recv_loop([{_Tag, N}| _Cmds], _, St) when N < 0 ->
+ ?error("#### ~w(~w) in recv_loop: error: too much: ~w~n",
+ [St#st.type, self(), N]),
+ exit(toomuch); % XXX or {error, Reason}?
+recv_loop([{Tag, N}| Cmds], F, St) ->
+ case F(St) of
+ {ok, Len} ->
+ NSt = St#st{active = new_active(St#st.active)},
+ if
+ Len == N ->
+ pre_main_loop(Cmds, NSt);
+ true ->
+ ?debug("#### ~w -> ~w~n",
+ [{NSt#st.type, self(), NSt#st.sock, NSt#st.port,
+ NSt#st.peer, NSt#st.active}, {Tag, N - Len}]),
+ recv_loop([{Tag, N - Len}| Cmds], F, NSt)
+ end;
+ {error, Reason} ->
+ ?error("#### ~w(~w) in recv_loop: error: ~w, ~w bytes remain~n",
+ [St#st.type, self(), Reason, N]),
+ exit(Reason)
+ end.
+
+new_active(once) ->
+ false;
+new_active(A) ->
+ A.
+
+get_active(St) ->
+ A = case proplists:get_value(active, St#st.sockopts, undefined) of
+ undefined ->
+ Mod = case St#st.protomod of
+ ssl ->
+ ssl;
+ gen_tcp ->
+ inet
+ end,
+ {ok, [{active, Ax}]} = Mod:getopts(St#st.sock, [active]),
+ Ax;
+ Ay ->
+ Ay
+ end,
+ ?debug("#### ~w(~w) get_active: ~p\n", [St#st.type, self(), A]),
+ St#st{active = A}.
+
+
+%%
+%% SOCKET FUNCTIONS
+%%
+
+%%
+%% ssl
+%%
+
+%%
+%% listen(St, LPort) -> {ok, LSock} | {error, Reason}
+%%
+listen(St, LPort) ->
+ case St#st.protomod of
+ ssl ->
+ ssl:listen(LPort, St#st.sockopts ++ St#st.sslopts);
+ gen_tcp ->
+ gen_tcp:listen(LPort, St#st.sockopts)
+ end.
+
+%%
+%% accept(St) -> {ok, Sock} | {error, Reason}
+%%
+accept(St) ->
+ case St#st.protomod of
+ ssl ->
+ case ssl:transport_accept(St#st.lsock, St#st.timeout) of
+ {ok, Sock} ->
+ case ssl:ssl_accept(Sock, St#st.timeout) of
+ ok ->
+ {ok, Port} = ssl:sockname(Sock),
+ {ok, Peer} = ssl:peername(Sock),
+ {ok, Sock, Port, Peer};
+ Other ->
+ Other
+ end;
+ Other ->
+ Other
+ end;
+ gen_tcp ->
+ case gen_tcp:accept(St#st.lsock, St#st.timeout) of
+ {ok, Sock} ->
+ {ok, Port} = inet:port(Sock),
+ {ok, Peer} = inet:peername(Sock),
+ {ok, Sock, Port, Peer};
+ Other ->
+ Other
+ end
+ end.
+
+%%
+%% connect(St, Host, Port) -> {ok, Sock} | {error, Reason}
+%%
+connect(St, Host, Port) ->
+
+ case St#st.protomod of
+ ssl ->
+ case ssl:connect(Host, Port, St#st.sockopts ++ St#st.sslopts,
+ St#st.timeout) of
+ {ok, Sock} ->
+ {ok, LPort} = ssl:sockname(Sock),
+ {ok, Peer} = ssl:peername(Sock),
+ {ok, Sock, LPort, Peer};
+ Other ->
+ Other
+ end;
+ gen_tcp ->
+ case gen_tcp:connect(Host, Port, St#st.sockopts, St#st.timeout) of
+ {ok, Sock} ->
+ {ok, LPort} = inet:port(Sock),
+ {ok, Peer} = inet:peername(Sock),
+ {ok, Sock, LPort, Peer};
+ Other ->
+ Other
+ end
+ end.
+
+%%
+%% peercert(St) -> {ok, Cert} | {error, Reason}
+%%
+peercert(St) ->
+ case St#st.protomod of
+ ssl ->
+ ssl:peercert(St#st.sock, [ssl]);
+ gen_tcp ->
+ {ok, <<>>}
+ end.
+
+%%
+%% connection_info(St) -> {ok, ProtoInfo} | {error, Reason}
+%%
+connection_info(St) ->
+ case St#st.protomod of
+ ssl ->
+ case ssl:connection_info(St#st.sock) of
+ Res = {ok, {Proto, _}} ->
+ case St#st.protocols of
+ [] ->
+ Res;
+ Protocols ->
+ case lists:member(Proto, Protocols) of
+ true ->
+ Res;
+ false ->
+ {error, Proto}
+ end
+ end;
+ Error ->
+ Error
+ end;
+ gen_tcp ->
+ {ok, <<>>}
+ end.
+
+%%
+%% close(St) -> ok | {error, Reason}
+%%
+
+close(St) ->
+ Mod = St#st.protomod,
+ case St#st.sock of
+ nil ->
+ ok;
+ _ ->
+ Mod:close(St#st.sock)
+ end.
+
+%%
+%% lclose(St) -> ok | {error, Reason}
+%%
+lclose(St) ->
+ Mod = St#st.protomod,
+ case St#st.lsock of
+ nil ->
+ ok;
+ _ ->
+ Mod:close(St#st.lsock)
+ end.
+
+%%
+%% recv(St) = {ok, Len} | {error, Reason}
+%%
+recv(St) ->
+ case do_recv(St) of
+ {ok, Msg} ->
+ {ok, length(Msg)};
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+do_recv(St) when St#st.active == false ->
+ %% First check that we do *not* have any ssl/gen_tcp messages in the
+ %% message queue, then call the receive function.
+ Sock = St#st.sock,
+ case St#st.protomod of
+ ssl ->
+ receive
+ M = {ssl, Sock, _Msg} ->
+ {error, {unexpected_messagex, M}};
+ M = {ssl_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {ssl_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ ssl:recv(St#st.sock, 0, St#st.timeout)
+ end;
+ gen_tcp ->
+ receive
+ M = {tcp, Sock, _Msg} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ gen_tcp:recv(St#st.sock, 0, St#st.timeout)
+ end
+ end;
+do_recv(St) ->
+ Sock = St#st.sock,
+ Timeout = St#st.timeout,
+ case St#st.protomod of
+ ssl ->
+ receive
+ {ssl, Sock, Msg} ->
+ {ok, Msg};
+ {ssl_closed, Sock} ->
+ {error, closed};
+ {ssl_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end;
+ gen_tcp ->
+ receive
+ {tcp, Sock, Msg} ->
+ {ok, Msg};
+ {tcp_closed, Sock} ->
+ {error, closed};
+ {tcp_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end
+ end.
+
+%%
+%% echo(St) = {ok, Len} | {error, Reason}
+%%
+echo(St) ->
+ Sock = St#st.sock,
+ case do_recv(St) of
+ {ok, Msg} ->
+ Mod = St#st.protomod,
+ case Mod:send(Sock, Msg) of
+ ok ->
+ {ok, length(Msg)};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+%%
+%% send(St, Msg) -> ok | {error, Reason}
+%%
+send(St, Msg) ->
+ Mod = St#st.protomod,
+ Mod:send(St#st.sock, Msg).
+
+%%
+%% await_close(St) -> ok | {error, Reason}
+%%
+await_close(St) when St#st.active == false ->
+ %% First check that we do *not* have any ssl/gen_tcp messages in the
+ %% message queue, then call the receive function.
+ Sock = St#st.sock,
+ Res = case St#st.protomod of
+ ssl ->
+ receive
+ M = {ssl, Sock, _Msg0} ->
+ {error, {unexpected_message, M}};
+ M = {ssl_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {ssl_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ ok
+ end;
+ gen_tcp ->
+ receive
+ M = {tcp, Sock, _Msg0} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ ok
+ end
+ end,
+ case Res of
+ ok ->
+ Mod = St#st.protomod,
+ case Mod:recv(St#st.sock, 0, St#st.timeout) of
+ {ok, _Msg} ->
+ {error, toomuch};
+ {error, _} ->
+ ok
+ end;
+ _ ->
+ Res
+ end;
+await_close(St) ->
+ Sock = St#st.sock,
+ Timeout = St#st.timeout,
+ case St#st.protomod of
+ ssl ->
+ receive
+ {ssl, Sock, _Msg} ->
+ {error, toomuch};
+ {ssl_closed, Sock} ->
+ ok;
+ {ssl_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end;
+ gen_tcp ->
+ receive
+ {tcp, Sock, _Msg} ->
+ {error, toomuch};
+ {tcp_closed, Sock} ->
+ ok;
+ {tcp_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end
+ end.
+
+
+%%
+%% HELP FUNCTIONS
+%%
+
+wait_ack(_, [], _) ->
+ ok;
+wait_ack(AccPids0, Pids, Timeout) ->
+ ?debug("#### CONTROLLER: waiting for ~w~n", [Pids]),
+ receive
+ {one_accept_done, Pid} ->
+ case lists:delete(Pid, AccPids0) of
+ [] ->
+ wait_ack([], Pids, Timeout);
+ [AccPid| AccPids1] ->
+ AccPid ! {continue_accept, self()},
+ wait_ack(AccPids1, Pids, Timeout)
+ end;
+ {'EXIT', Pid, normal} ->
+ wait_ack(AccPids0, lists:delete(Pid, Pids), Timeout);
+ {'EXIT', Pid, Reason} ->
+ ?error("#### CONTROLLER got abnormal exit: ~w, ~w~n",
+ [Pid, Reason]),
+ {error, Reason}
+ after Timeout ->
+ ?error("#### CONTROLLER exiting because of timeout = ~w~n",
+ [Timeout]),
+ {error, Timeout}
+ end.
+
+
+%%
+%% ack_lsock(Pid, LSock)
+%%
+ack_lsock(Pid, LSock) ->
+ Pid ! {lsock, self(), LSock}.
+
+wait_lsock(Pid, Timeout) ->
+ receive
+ {lsock, Pid, LSock} ->
+ {ok, LSock}
+ after Timeout ->
+ exit(timeout)
+ end.
+
+%%
+%% sync(Pids)
+%%
+sync(Pids) ->
+ lists:foreach(fun (Pid) -> Pid ! {self(), sync} end, Pids).
+
+%%
+%% wait_sync(St)
+%%
+wait_sync(St) ->
+ Pid = St#st.parent,
+ receive
+ {Pid, sync} ->
+ ok
+ end.
+
+%%
+%% wait(Time)
+%%
+wait(Time) ->
+ receive
+ after Time ->
+ ok
+ end.
+
+%%
+%% mk_msg(Size)
+%%
+mk_msg(Size) ->
+ mk_msg(0, Size, []).
+
+mk_msg(_, 0, Acc) ->
+ Acc;
+mk_msg(Pos, Size, Acc) ->
+ C = (((Pos + Size) rem 256) - 1) band 255,
+ mk_msg(Pos, Size - 1, [C| Acc]).
+
+%%
+%% get_protomod(Config)
+%%
+get_protomod(Config) ->
+ case lists:keysearch(protomod, 1, Config) of
+ {value, {_, ProtoMod}} ->
+ ProtoMod;
+ false ->
+ ssl
+ end.
+
+%%
+%% get_serialize_accept(Config)
+%%
+get_serialize_accept(Config) ->
+ case lists:keysearch(serialize_accept, 1, Config) of
+ {value, {_, Val}} ->
+ Val;
+ false ->
+ false
+ end.
+
diff --git a/lib/ssl/test/ssl_test_MACHINE.hrl b/lib/ssl/test/ssl_test_MACHINE.hrl
new file mode 100644
index 0000000000..e78b33f505
--- /dev/null
+++ b/lib/ssl/test/ssl_test_MACHINE.hrl
@@ -0,0 +1,39 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-record(st, {protomod = ssl,
+ serialize_accept = false,
+ parent = nil,
+ type = nil,
+ active = nil,
+ port = 0,
+ peer = nil,
+ lsock = nil,
+ sock = nil,
+ timeout = infinity,
+ sockopts = [],
+ sslopts = [],
+ protocols = []}).
+
+%%-define(debug(X, Y), io:format(X, Y)).
+-define(debug(X, Y), ok).
+-define(error(X, Y), io:format(X, Y)).
+
+-define(DEFAULT_TIMEOUT, 240000).
+
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
new file mode 100644
index 0000000000..7ed19b3a05
--- /dev/null
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -0,0 +1,408 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_test_lib).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+
+timetrap(Time) ->
+ Mul = try
+ test_server:timetrap_scale_factor()
+ catch _:_ -> 1 end,
+ test_server:timetrap(1000+Time*Mul).
+
+%% For now always run locally
+run_where(_) ->
+ ClientNode = node(),
+ ServerNode = node(),
+ {ok, Host} = rpc:call(ServerNode, inet, gethostname, []),
+ {ClientNode, ServerNode, Host}.
+
+run_where(_, ipv6) ->
+ ClientNode = node(),
+ ServerNode = node(),
+ {ok, Host} = rpc:call(ServerNode, inet, gethostname, []),
+ {ClientNode, ServerNode, Host}.
+
+node_to_hostip(Node) ->
+ [_ , Host] = string:tokens(atom_to_list(Node), "@"),
+ {ok, Address} = inet:getaddr(Host, inet),
+ Address.
+
+start_server(Args) ->
+ spawn_link(?MODULE, run_server, [Args]).
+
+run_server(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Port = proplists:get_value(port, Opts),
+ Options = proplists:get_value(options, Opts),
+ Pid = proplists:get_value(from, Opts),
+ test_server:format("ssl:listen(~p, ~p)~n", [Port, Options]),
+ {ok, ListenSocket} = rpc:call(Node, ssl, listen, [Port, Options]),
+ case Port of
+ 0 ->
+ {ok, {_, NewPort}} = ssl:sockname(ListenSocket),
+ Pid ! {self(), {port, NewPort}};
+ _ ->
+ ok
+ end,
+ run_server(ListenSocket, Opts).
+
+run_server(ListenSocket, Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Pid = proplists:get_value(from, Opts),
+ test_server:format("ssl:transport_accept(~p)~n", [ListenSocket]),
+ {ok, AcceptSocket} = rpc:call(Node, ssl, transport_accept,
+ [ListenSocket]),
+ test_server:format("ssl:ssl_accept(~p)~n", [AcceptSocket]),
+ ok = rpc:call(Node, ssl, ssl_accept, [AcceptSocket]),
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ test_server:format("Server: apply(~p,~p,~p)~n",
+ [Module, Function, [AcceptSocket | Args]]),
+ case rpc:call(Node, Module, Function, [AcceptSocket | Args]) of
+ no_result_msg ->
+ ok;
+ Msg ->
+ Pid ! {self(), Msg}
+ end,
+ receive
+ listen ->
+ run_server(ListenSocket, Opts);
+ close ->
+ ok = rpc:call(Node, ssl, close, [AcceptSocket])
+ end.
+
+start_client(Args) ->
+ spawn_link(?MODULE, run_client, [Args]).
+
+run_client(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Host = proplists:get_value(host, Opts),
+ Port = proplists:get_value(port, Opts),
+ Pid = proplists:get_value(from, Opts),
+ Options = proplists:get_value(options, Opts),
+ test_server:format("ssl:connect(~p, ~p, ~p)~n", [Host, Port, Options]),
+ case rpc:call(Node, ssl, connect, [Host, Port, Options]) of
+ {ok, Socket} ->
+ test_server:format("Client: connected~n", []),
+ case proplists:get_value(port, Options) of
+ 0 ->
+ {ok, {_, NewPort}} = ssl:sockname(Socket),
+ Pid ! {self(), {port, NewPort}};
+ _ ->
+ ok
+ end,
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ test_server:format("Client: apply(~p,~p,~p)~n",
+ [Module, Function, [Socket | Args]]),
+ case rpc:call(Node, Module, Function, [Socket | Args]) of
+ no_result_msg ->
+ ok;
+ Msg ->
+ Pid ! {self(), Msg}
+ end,
+ receive
+ close ->
+ ok = rpc:call(Node, ssl, close, [Socket])
+ end;
+ {error, Reason} ->
+ test_server:format("Client: connection failed: ~p ~n", [Reason]),
+ Pid ! {self(), {error, Reason}}
+ end.
+
+close(Pid) ->
+ Pid ! close.
+
+check_result(Server, ServerMsg, Client, ClientMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ Unexpected ->
+ Reason = {{expected, {Client, ClientMsg}},
+ {got, Unexpected}},
+ test_server:fail(Reason)
+ end;
+ {Client, ClientMsg} ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ Unexpected ->
+ Reason = {{expected, {Server, ClientMsg}},
+ {got, Unexpected}},
+ test_server:fail(Reason)
+ end;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ check_result(Server, ServerMsg, Client, ClientMsg);
+
+ Unexpected ->
+ Reason = {{expected, {Client, ClientMsg}},
+ {expected, {Server, ServerMsg}}, {got, Unexpected}},
+ test_server:fail(Reason)
+ end.
+
+check_result(Pid, Msg) ->
+ receive
+ {Pid, Msg} ->
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ check_result(Pid,Msg);
+ Unexpected ->
+ Reason = {{expected, {Pid, Msg}},
+ {got, Unexpected}},
+ test_server:fail(Reason)
+ end.
+
+wait_for_result(Server, ServerMsg, Client, ClientMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ Unexpected ->
+ Unexpected
+ end;
+ {Client, ClientMsg} ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ Unexpected ->
+ Unexpected
+ end;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ wait_for_result(Server, ServerMsg, Client, ClientMsg);
+ Unexpected ->
+ Unexpected
+ end.
+
+
+wait_for_result(Pid, Msg) ->
+ receive
+ {Pid, Msg} ->
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ wait_for_result(Pid,Msg);
+ Unexpected ->
+ Unexpected
+ end.
+
+cert_options(Config) ->
+ ClientCaCertFile = filename:join([?config(priv_dir, Config),
+ "client", "cacerts.pem"]),
+ ClientCertFile = filename:join([?config(priv_dir, Config),
+ "client", "cert.pem"]),
+ ServerCaCertFile = filename:join([?config(priv_dir, Config),
+ "server", "cacerts.pem"]),
+ ServerCertFile = filename:join([?config(priv_dir, Config),
+ "server", "cert.pem"]),
+ ServerKeyFile = filename:join([?config(priv_dir, Config),
+ "server", "key.pem"]),
+ ClientKeyFile = filename:join([?config(priv_dir, Config),
+ "client", "key.pem"]),
+ ServerKeyCertFile = filename:join([?config(priv_dir, Config),
+ "server", "keycert.pem"]),
+ ClientKeyCertFile = filename:join([?config(priv_dir, Config),
+ "client", "keycert.pem"]),
+
+ BadCaCertFile = filename:join([?config(priv_dir, Config),
+ "badcacert.pem"]),
+ BadCertFile = filename:join([?config(priv_dir, Config),
+ "badcert.pem"]),
+ BadKeyFile = filename:join([?config(priv_dir, Config),
+ "badkey.pem"]),
+ [{client_opts, [{ssl_imp, new}]},
+ {client_verification_opts, [{cacertfile, ClientCaCertFile},
+ {certfile, ClientCertFile},
+ {keyfile, ClientKeyFile},
+ {ssl_imp, new}]},
+ {server_opts, [{ssl_imp, new},{reuseaddr, true},
+ {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
+ {server_verification_opts, [{ssl_imp, new},{reuseaddr, true},
+ {cacertfile, ServerCaCertFile},
+ {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
+ {client_kc_opts, [{certfile, ClientKeyCertFile}, {ssl_imp, new}]},
+ {server_kc_opts, [{ssl_imp, new},{reuseaddr, true},
+ {certfile, ServerKeyCertFile}]},
+ {client_bad_ca, [{cacertfile, BadCaCertFile},
+ {certfile, ClientCertFile},
+ {keyfile, ClientKeyFile},
+ {ssl_imp, new}]},
+ {client_bad_cert, [{cacertfile, ClientCaCertFile},
+ {certfile, BadCertFile},
+ {keyfile, ClientKeyFile},
+ {ssl_imp, new}]},
+ {server_bad_ca, [{ssl_imp, new},{cacertfile, BadCaCertFile},
+ {certfile, ServerCertFile},
+ {keyfile, ServerKeyFile}]},
+ {server_bad_cert, [{ssl_imp, new},{cacertfile, ServerCaCertFile},
+ {certfile, BadCertFile}, {keyfile, ServerKeyFile}]},
+ {server_bad_key, [{ssl_imp, new},{cacertfile, ServerCaCertFile},
+ {certfile, ServerCertFile}, {keyfile, BadKeyFile}]}
+ | Config].
+
+
+start_upgrade_server(Args) ->
+ spawn_link(?MODULE, run_upgrade_server, [Args]).
+
+run_upgrade_server(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Port = proplists:get_value(port, Opts),
+ TimeOut = proplists:get_value(timeout, Opts, infinity),
+ TcpOptions = proplists:get_value(tcp_options, Opts),
+ SslOptions = proplists:get_value(ssl_options, Opts),
+ Pid = proplists:get_value(from, Opts),
+
+ test_server:format("gen_tcp:listen(~p, ~p)~n", [Port, TcpOptions]),
+ {ok, ListenSocket} = rpc:call(Node, gen_tcp, listen, [Port, TcpOptions]),
+
+ case Port of
+ 0 ->
+ {ok, {_, NewPort}} = inet:sockname(ListenSocket),
+ Pid ! {self(), {port, NewPort}};
+ _ ->
+ ok
+ end,
+
+ test_server:format("gen_tcp:accept(~p)~n", [ListenSocket]),
+ {ok, AcceptSocket} = rpc:call(Node, gen_tcp, accept, [ListenSocket]),
+
+ {ok, SslAcceptSocket} = case TimeOut of
+ infinity ->
+ test_server:format("ssl:ssl_accept(~p, ~p)~n",
+ [AcceptSocket, SslOptions]),
+ rpc:call(Node, ssl, ssl_accept,
+ [AcceptSocket, SslOptions]);
+ _ ->
+ test_server:format("ssl:ssl_accept(~p, ~p, ~p)~n",
+ [AcceptSocket, SslOptions, TimeOut]),
+ rpc:call(Node, ssl, ssl_accept,
+ [AcceptSocket, SslOptions, TimeOut])
+ end,
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ Msg = rpc:call(Node, Module, Function, [SslAcceptSocket | Args]),
+ Pid ! {self(), Msg},
+ receive
+ close ->
+ ok = rpc:call(Node, ssl, close, [SslAcceptSocket])
+ end.
+
+start_upgrade_client(Args) ->
+ spawn_link(?MODULE, run_upgrade_client, [Args]).
+
+run_upgrade_client(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Host = proplists:get_value(host, Opts),
+ Port = proplists:get_value(port, Opts),
+ Pid = proplists:get_value(from, Opts),
+ TcpOptions = proplists:get_value(tcp_options, Opts),
+ SslOptions = proplists:get_value(ssl_options, Opts),
+
+ test_server:format("gen_tcp:connect(~p, ~p, ~p)~n",
+ [Host, Port, TcpOptions]),
+ {ok, Socket} = rpc:call(Node, gen_tcp, connect, [Host, Port, TcpOptions]),
+
+ case proplists:get_value(port, Opts) of
+ 0 ->
+ {ok, {_, NewPort}} = inet:sockname(Socket),
+ Pid ! {self(), {port, NewPort}};
+ _ ->
+ ok
+ end,
+
+ test_server:format("ssl:connect(~p, ~p)~n", [Socket, SslOptions]),
+ {ok, SslSocket} = rpc:call(Node, ssl, connect, [Socket, SslOptions]),
+
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ test_server:format("apply(~p, ~p, ~p)~n",
+ [Module, Function, [SslSocket | Args]]),
+ Msg = rpc:call(Node, Module, Function, [SslSocket | Args]),
+ Pid ! {self(), Msg},
+ receive
+ close ->
+ ok = rpc:call(Node, ssl, close, [SslSocket])
+ end.
+
+start_server_error(Args) ->
+ spawn_link(?MODULE, run_server_error, [Args]).
+
+run_server_error(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Port = proplists:get_value(port, Opts),
+ Options = proplists:get_value(options, Opts),
+ Pid = proplists:get_value(from, Opts),
+ test_server:format("ssl:listen(~p, ~p)~n", [Port, Options]),
+ case rpc:call(Node, ssl, listen, [Port, Options]) of
+ {ok, ListenSocket} ->
+ test_server:sleep(2000), %% To make sure error_client will
+ %% get {error, closed} and not {error, connection_refused}
+ test_server:format("ssl:transport_accept(~p)~n", [ListenSocket]),
+ case rpc:call(Node, ssl, transport_accept, [ListenSocket]) of
+ {error, _} = Error ->
+ Pid ! {self(), Error};
+ {ok, AcceptSocket} ->
+ test_server:format("ssl:ssl_accept(~p)~n", [AcceptSocket]),
+ Error = rpc:call(Node, ssl, ssl_accept, [AcceptSocket]),
+ Pid ! {self(), Error}
+ end;
+ Error ->
+ Pid ! {self(), Error}
+ end.
+
+start_client_error(Args) ->
+ spawn_link(?MODULE, run_client_error, [Args]).
+
+run_client_error(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Host = proplists:get_value(host, Opts),
+ Port = proplists:get_value(port, Opts),
+ Pid = proplists:get_value(from, Opts),
+ Options = proplists:get_value(options, Opts),
+ test_server:format("ssl:connect(~p, ~p, ~p)~n", [Host, Port, Options]),
+ Error = rpc:call(Node, ssl, connect, [Host, Port, Options]),
+ Pid ! {self(), Error}.
+
+inet_port(Pid) when is_pid(Pid)->
+ receive
+ {Pid, {port, Port}} ->
+ Port
+ end;
+
+inet_port(Node) ->
+ {Port, Socket} = do_inet_port(Node),
+ rpc:call(Node, gen_tcp, close, [Socket]),
+ Port.
+
+do_inet_port(Node) ->
+ {ok, Socket} = rpc:call(Node, gen_tcp, listen, [0, [{reuseaddr, true}]]),
+ {ok, Port} = rpc:call(Node, inet, port, [Socket]),
+ {Port, Socket}.
+
+no_result(_) ->
+ no_result_msg.
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
new file mode 100644
index 0000000000..c079e12b83
--- /dev/null
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -0,0 +1,772 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_to_openssl_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("ssl_pkix.hrl").
+
+-define(TIMEOUT, 120000).
+-define(SLEEP, 1000).
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initialization before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ case os:find_executable("openssl") of
+ false ->
+ {skip, "Openssl not found"};
+ _ ->
+ crypto:start(),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config))),
+ test_server:format("Make certs ~p~n", [Result]),
+ ssl_test_lib:cert_options(Config)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ssl:stop(),
+ crypto:stop().
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initialization before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initialization before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ssl_test_lib:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test erlangs ssl against openssl"];
+
+all(suite) ->
+ [erlang_client_openssl_server,
+ erlang_server_openssl_client,
+ ssl3_erlang_client_openssl_server,
+ ssl3_erlang_server_openssl_client,
+ ssl3_erlang_client_openssl_server_client_cert,
+ ssl3_erlang_server_openssl_client_client_cert,
+ ssl3_erlang_server_erlang_client_client_cert,
+ tls1_erlang_client_openssl_server,
+ tls1_erlang_server_openssl_client,
+ tls1_erlang_client_openssl_server_client_cert,
+ tls1_erlang_server_openssl_client_client_cert,
+ tls1_erlang_server_erlang_client_client_cert,
+ ciphers
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+erlang_client_openssl_server(doc) ->
+ ["Test erlang client with openssl server"];
+erlang_client_openssl_server(suite) ->
+ [];
+erlang_client_openssl_server(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile,
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+
+%%--------------------------------------------------------------------
+erlang_server_openssl_client(doc) ->
+ ["Test erlang server with openssl client"];
+erlang_server_openssl_client(suite) ->
+ [];
+erlang_server_openssl_client(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ ssl_test_lib:close(Server),
+
+ close_port(OpenSslPort),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+ssl3_erlang_client_openssl_server(doc) ->
+ ["Test erlang client with openssl server"];
+ssl3_erlang_client_openssl_server(suite) ->
+ [];
+ssl3_erlang_client_openssl_server(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ connection_info, [sslv3]}},
+ {options,
+ [{versions, [sslv3]} | ClientOpts]}]),
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Client),
+ %% Clean close down!
+ close_port(OpensslPort),
+ test_server:sleep(?SLEEP),
+ ok.
+
+%%--------------------------------------------------------------------
+
+ssl3_erlang_server_openssl_client(doc) ->
+ ["Test erlang server with openssl client"];
+ssl3_erlang_server_openssl_client(suite) ->
+ [];
+ssl3_erlang_server_openssl_client(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, connection_info, [sslv3]}},
+ {options,
+ [{versions, [sslv3]} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ close_port(OpenSslPort), %% openssl server first
+ ssl_test_lib:close(Server),
+ test_server:sleep(?SLEEP),
+ ok.
+
+%%--------------------------------------------------------------------
+ssl3_erlang_client_openssl_server_client_cert(doc) ->
+ ["Test erlang client with openssl server when client sends cert"];
+ssl3_erlang_client_openssl_server_client_cert(suite) ->
+ [];
+ssl3_erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -Verify 2 -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down!
+ close_port(OpensslPort),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+ssl3_erlang_server_openssl_client_client_cert(doc) ->
+ ["Test erlang server with openssl client when client sends cert"];
+ssl3_erlang_server_openssl_client_client_cert(suite) ->
+ [];
+ssl3_erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ CaCertFile = proplists:get_value(cacertfile, ClientOpts),
+ CertFile = proplists:get_value(certfile, ClientOpts),
+ KeyFile = proplists:get_value(keyfile, ClientOpts),
+
+ Cmd = "openssl s_client -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -port " ++ integer_to_list(Port) ++
+ " -host localhost -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ close_port(OpenSslPort), %% openssl server first
+ ssl_test_lib:close(Server),
+ %% Clean close down!
+ process_flag(trap_exit, false),
+ ok.
+
+
+%%--------------------------------------------------------------------
+
+ssl3_erlang_server_erlang_client_client_cert(doc) ->
+ ["Test erlang server with erlang client when client sends cert"];
+ssl3_erlang_server_erlang_client_client_cert(suite) ->
+ [];
+ssl3_erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl, send, [Data]}},
+ {options,
+ [{versions, [sslv3]} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_client_openssl_server(doc) ->
+ ["Test erlang client with openssl server"];
+tls1_erlang_client_openssl_server(suite) ->
+ [];
+tls1_erlang_client_openssl_server(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+
+ test_server:format("Server Opts", [ServerOpts]),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile
+ ++ " -key " ++ KeyFile ++ " -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ connection_info, [tlsv1]}},
+ {options,
+ [{versions, [tlsv1]} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Client),
+ %% Clean close down!
+ close_port(OpensslPort),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_server_openssl_client(doc) ->
+ ["Test erlang server with openssl client"];
+tls1_erlang_server_openssl_client(suite) ->
+ [];
+tls1_erlang_server_openssl_client(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, connection_info, [tlsv1]}},
+ {options,
+ [{versions, [tlsv1]} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ %% Clean close down!
+ close_port(OpenSslPort),
+ ssl_test_lib:close(Server),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_client_openssl_server_client_cert(doc) ->
+ ["Test erlang client with openssl server when client sends cert"];
+tls1_erlang_client_openssl_server_client_cert(suite) ->
+ [];
+tls1_erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -Verify 2 -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down!
+ close_port(OpensslPort),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_server_openssl_client_client_cert(doc) ->
+ ["Test erlang server with openssl client when client sends cert"];
+tls1_erlang_server_openssl_client_client_cert(suite) ->
+ [];
+tls1_erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ CaCertFile = proplists:get_value(cacertfile, ClientOpts),
+ CertFile = proplists:get_value(certfile, ClientOpts),
+ KeyFile = proplists:get_value(keyfile, ClientOpts),
+
+ Cmd = "openssl s_client -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -port " ++ integer_to_list(Port) ++
+ " -host localhost -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ %% Clean close down!
+ close_port(OpenSslPort),
+ ssl_test_lib:close(Server),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+tls1_erlang_server_erlang_client_client_cert(doc) ->
+ ["Test erlang server with erlang client when client sends cert"];
+tls1_erlang_server_erlang_client_client_cert(suite) ->
+ [];
+tls1_erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl, send, [Data]}},
+ {options,
+ [{versions, [tlsv1]} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ %% Clean close down!
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+
+ciphers(doc) ->
+ [""];
+
+ciphers(suite) ->
+ [];
+
+ciphers(Config) when is_list(Config) ->
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ Ciphers = ssl:cipher_suites(),
+ Result = lists:map(fun(Cipher) ->
+ cipher(Cipher, Version, Config) end,
+ Ciphers),
+ case lists:flatten(Result) of
+ [] ->
+ ok;
+ Error ->
+ test_server:format("Cipher suite errors: ~p~n", [Error]),
+ test_server:fail(cipher_suite_failed_see_test_case_log)
+ end.
+
+cipher(CipherSuite, Version, Config) ->
+ process_flag(trap_exit, true),
+ test_server:format("Testing CipherSuite ~p~n", [CipherSuite]),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile
+ ++ " -key " ++ KeyFile ++ "",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options,
+ [{ciphers,[CipherSuite]} |
+ ClientOpts]}]),
+
+ ClientMsg = {ok, {Version, CipherSuite}},
+
+ Result = ssl_test_lib:wait_for_result(Client, ClientMsg),
+
+ close_port(OpenSslPort),
+ %% Clean close down!
+ ssl_test_lib:close(Client),
+ receive
+ {'EXIT', Client, normal} ->
+ ok
+ end,
+
+ Return = case Result of
+ ok ->
+ [];
+ Error ->
+ [{CipherSuite, Error}]
+ end,
+ process_flag(trap_exit, false),
+ Return.
+
+%%--------------------------------------------------------------------
+
+erlang_ssl_receive(Socket, Data) ->
+ test_server:format("Connection info: ~p~n",
+ [ssl:connection_info(Socket)]),
+ receive
+ {ssl, Socket, Data} ->
+ io:format("Received ~p~n",[Data]),
+ %% open_ssl server sometimes hangs waiting in blocking read
+ ssl:send(Socket, "Got it"),
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ erlang_ssl_receive(Socket,Data);
+ Other ->
+ test_server:fail({unexpected_message, Other})
+ after 4000 ->
+ test_server:fail({did_not_get, Data})
+ end.
+
+connection_info(Socket, Version) ->
+ case ssl:connection_info(Socket) of
+ {ok, {Version, _} = Info} ->
+ test_server:format("Connection info: ~p~n", [Info]),
+ ok;
+ {ok, {OtherVersion, _}} ->
+ {wrong_version, OtherVersion}
+ end.
+
+connection_info_result(Socket) ->
+ ssl:connection_info(Socket).
+
+close_port(Port) ->
+ port_command(Port, "Q\n"),
+ %%catch port_command(Port, "quit\n"),
+ close_loop(Port, 500, false).
+
+close_loop(Port, Time, SentClose) ->
+ receive
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ close_loop(Port, Time, SentClose);
+ {ssl,_,Msg} ->
+ io:format("ssl Msg ~s~n",[Msg]),
+ close_loop(Port, Time, SentClose);
+ {Port, closed} ->
+ io:format("Port Closed~n",[]),
+ ok;
+ {'EXIT', Port, Reason} ->
+ io:format("Port Closed ~p~n",[Reason]),
+ ok;
+ Msg ->
+ io:format("Port Msg ~p~n",[Msg]),
+ close_loop(Port, Time, SentClose)
+ after Time ->
+ case SentClose of
+ false ->
+ io:format("Closing port ~n",[]),
+ catch erlang:port_close(Port),
+ close_loop(Port, Time, true);
+ true ->
+ io:format("Timeout~n",[])
+ end
+ end.
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index 603c419653..2239f2eff4 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1,25 +1,26 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
-SSL_VSN = 3.10.7
+SSL_VSN = 3.10.8
-TICKETS = OTP-8260 OTP-8218 OTP-8250
+TICKETS = OTP-8327
+#TICKETS_3.10.7 = OTP-8260 OTP-8218 OTP-8250
#TICKETS_3.10.6 = OTP-8275
diff --git a/lib/stdlib/doc/src/beam_lib.xml b/lib/stdlib/doc/src/beam_lib.xml
index f2a9c2a671..b9286f1402 100644
--- a/lib/stdlib/doc/src/beam_lib.xml
+++ b/lib/stdlib/doc/src/beam_lib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>beam_lib</title>
@@ -70,82 +70,88 @@
using <seealso marker="#strip/1">strip/1</seealso>,
<seealso marker="#strip_files/1">strip_files/1</seealso> and/or
<seealso marker="#strip_release/1">strip_release/1</seealso>.</p>
- <p><em>Reconstructing source code</em></p>
- <p>Here is an example of how to reconstruct source code from
- the debug information in a BEAM file <c>Beam</c>:</p>
- <code type="none">
+ <section>
+ <title>Reconstructing source code</title>
+ <p>Here is an example of how to reconstruct source code from
+ the debug information in a BEAM file <c>Beam</c>:</p>
+ <code type="none">
{ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Beam,[abstract_code]).
io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).</code>
- <p><em>Encrypted debug information</em></p>
- <p>The debug information can be encrypted in order to keep
- the source code secret, but still being able to use tools such as
- Xref or Debugger. </p>
- <p>To use encrypted debug information, a key must be provided to
- the compiler and <c>beam_lib</c>. The key is given as a string and
- it is recommended that it contains at least 32 characters and
- that both upper and lower case letters as well as digits and
- special characters are used.</p>
- <p></p>
- <p>The default type -- and currently the only type -- of crypto
- algorithm is <c>des3_cbc</c>, three rounds of DES. The key string
- will be scrambled using <c>erlang:md5/1</c> to generate
- the actual keys used for <c>des3_cbc</c>.</p>
- <note>
- <p>As far as we know by the time of writing, it is
- infeasible to break <c>des3_cbc</c> encryption without any
- knowledge of the key. Therefore, as long as the key is kept
- safe and is unguessable, the encrypted debug information
- <em>should</em> be safe from intruders.</p>
- </note>
- <p>There are two ways to provide the key:</p>
- <list type="ordered">
- <item>
- <p>Use the compiler option <c>{debug_info,Key}</c>, see
- <seealso marker="compiler:compile#debug_info_key">compile(3)</seealso>,
- and the function
- <seealso marker="#crypto_key_fun/1">crypto_key_fun/1</seealso>
- to register a fun which returns the key whenever
- <c>beam_lib</c> needs to decrypt the debug information.</p>
- <p>If no such fun is registered, <c>beam_lib</c> will instead
- search for a <c>.erlang.crypt</c> file, see below.</p>
- </item>
- <item>
- <p>Store the key in a text file named <c>.erlang.crypt</c>.</p>
- <p>In this case, the compiler option <c>encrypt_debug_info</c>
- can be used, see
- <seealso marker="compiler:compile#encrypt_debug_info">compile(3)</seealso>.</p>
- </item>
- </list>
- <p><em>.erlang.crypt</em></p>
- <p><c>beam_lib</c> searches for <c>.erlang.crypt</c> in the current
- directory and then the home directory for the current user. If
- the file is found and contains a key, <c>beam_lib</c> will
- implicitly create a crypto key fun and register it.</p>
- <p>The <c>.erlang.crypt</c> file should contain a single list of
- tuples:</p>
- <code type="none">
+ </section>
+ <section>
+ <title>Encrypted debug information</title>
+ <p>The debug information can be encrypted in order to keep
+ the source code secret, but still being able to use tools such as
+ Xref or Debugger. </p>
+ <p>To use encrypted debug information, a key must be provided to
+ the compiler and <c>beam_lib</c>. The key is given as a string and
+ it is recommended that it contains at least 32 characters and
+ that both upper and lower case letters as well as digits and
+ special characters are used.</p>
+ <p></p>
+ <p>The default type -- and currently the only type -- of crypto
+ algorithm is <c>des3_cbc</c>, three rounds of DES. The key string
+ will be scrambled using <c>erlang:md5/1</c> to generate
+ the actual keys used for <c>des3_cbc</c>.</p>
+ <note>
+ <p>As far as we know by the time of writing, it is
+ infeasible to break <c>des3_cbc</c> encryption without any
+ knowledge of the key. Therefore, as long as the key is kept
+ safe and is unguessable, the encrypted debug information
+ <em>should</em> be safe from intruders.</p>
+ </note>
+ <p>There are two ways to provide the key:</p>
+ <list type="ordered">
+ <item>
+ <p>Use the compiler option <c>{debug_info,Key}</c>, see
+ <seealso marker="compiler:compile#debug_info_key">compile(3)</seealso>,
+ and the function
+ <seealso marker="#crypto_key_fun/1">crypto_key_fun/1</seealso>
+ to register a fun which returns the key whenever
+ <c>beam_lib</c> needs to decrypt the debug information.</p>
+ <p>If no such fun is registered, <c>beam_lib</c> will instead
+ search for a <c>.erlang.crypt</c> file, see below.</p>
+ </item>
+ <item>
+ <p>Store the key in a text file named <c>.erlang.crypt</c>.</p>
+ <p>In this case, the compiler option <c>encrypt_debug_info</c>
+ can be used, see
+ <seealso marker="compiler:compile#encrypt_debug_info">compile(3)</seealso>.</p>
+ </item>
+ </list>
+ </section>
+ <section>
+ <title>.erlang.crypt</title>
+ <p><c>beam_lib</c> searches for <c>.erlang.crypt</c> in the current
+ directory and then the home directory for the current user. If
+ the file is found and contains a key, <c>beam_lib</c> will
+ implicitly create a crypto key fun and register it.</p>
+ <p>The <c>.erlang.crypt</c> file should contain a single list of
+ tuples:</p>
+ <code type="none">
{debug_info, Mode, Module, Key}</code>
- <p><c>Mode</c> is the type of crypto algorithm; currently, the only
- allowed value thus is <c>des3_cbc</c>. <c>Module</c> is either an
- atom, in which case <c>Key</c> will only be used for the module
- <c>Module</c>, or <c>[]</c>, in which case <c>Key</c> will be
- used for all modules. <c>Key</c> is the non-empty key string.</p>
- <p>The <c>Key</c> in the first tuple where both <c>Mode</c> and
- <c>Module</c> matches will be used.</p>
- <p>Here is an example of an <c>.erlang.crypt</c> file that returns
- the same key for all modules:</p>
- <code type="none"><![CDATA[
+ <p><c>Mode</c> is the type of crypto algorithm; currently, the only
+ allowed value thus is <c>des3_cbc</c>. <c>Module</c> is either an
+ atom, in which case <c>Key</c> will only be used for the module
+ <c>Module</c>, or <c>[]</c>, in which case <c>Key</c> will be
+ used for all modules. <c>Key</c> is the non-empty key string.</p>
+ <p>The <c>Key</c> in the first tuple where both <c>Mode</c> and
+ <c>Module</c> matches will be used.</p>
+ <p>Here is an example of an <c>.erlang.crypt</c> file that returns
+ the same key for all modules:</p>
+ <code type="none"><![CDATA[
[{debug_info, des3_cbc, [], "%>7}|pc/DM6Cga*68$Mw]L#&_Gejr]G^"}].]]></code>
- <p>And here is a slightly more complicated example of an
- <c>.erlang.crypt</c> which provides one key for the module
- <c>t</c>, and another key for all other modules:</p>
- <code type="none"><![CDATA[
+ <p>And here is a slightly more complicated example of an
+ <c>.erlang.crypt</c> which provides one key for the module
+ <c>t</c>, and another key for all other modules:</p>
+ <code type="none"><![CDATA[
[{debug_info, des3_cbc, t, "My KEY"},
{debug_info, des3_cbc, [], "%>7}|pc/DM6Cga*68$Mw]L#&_Gejr]G^"}].]]></code>
- <note>
- <p>Do not use any of the keys in these examples. Use your own
- keys.</p>
- </note>
+ <note>
+ <p>Do not use any of the keys in these examples. Use your own
+ keys.</p>
+ </note>
+ </section>
</section>
<section>
diff --git a/lib/stdlib/doc/src/io.xml b/lib/stdlib/doc/src/io.xml
index c075f11792..6f9d979c9a 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>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>io</title>
@@ -1003,7 +1003,8 @@ enter><input>bar.</input>
<title>Standard Error</title>
<p>In certain situations, especially when the standard output is redirected, access to an io_server() specific for error messages might be convenient. The io_device 'standard_error' can be used to direct output to whatever the current operating system considers a suitable device for error output. Example on a Unix-like operating system:</p>
<pre>
-$ <input>erl -noshell -noinput -eval 'io:format(standard_error,"Error: ~s~n",["error 11"]),init:stop().' > /dev/null</input>
+$ <input>erl -noshell -noinput -eval 'io:format(standard_error,"Error: ~s~n",["error 11"]),'\</input>
+<input>'init:stop().' > /dev/null</input>
Error: error 11</pre>
diff --git a/lib/stdlib/doc/src/unicode.xml b/lib/stdlib/doc/src/unicode.xml
index b3aad51591..60edd8ade9 100644
--- a/lib/stdlib/doc/src/unicode.xml
+++ b/lib/stdlib/doc/src/unicode.xml
@@ -51,7 +51,9 @@ charlist() = [unicode_char() | unicode_binary() | charlist()]
a unicode_binary is allowed as the tail of the list</code>
<code type="none">
-external_unicode_binary() = binary() with characters coded in a user specified Unicode encoding other than UTF-8 (UTF-16 or UTF-32)
+external_unicode_binary() = binary()
+ with characters coded in a user specified Unicode encoding other
+ than UTF-8 (UTF-16 or UTF-32)
external_chardata() = external_charlist() | external_unicode_binary()
diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml
index 06347b3aae..c5bf10b63d 100644
--- a/lib/stdlib/doc/src/unicode_usage.xml
+++ b/lib/stdlib/doc/src/unicode_usage.xml
@@ -76,7 +76,8 @@ charlist() = [unicode_char() | unicode_binary() | charlist()]
a unicode_binary is allowed as the tail of the list</code>
<p>The module <c>unicode</c> in stdlib even supports similar mixes with binaries containing other encodings than UTF-8, but that is a special case to allow for conversions to and from external data:</p>
<code type="none">
-external_unicode_binary() = binary() with characters coded in a user specified Unicode encoding other than UTF-8 (UTF-16 or UTF-32)
+external_unicode_binary() = binary() with characters coded in a user specified Unicode
+ encoding other than UTF-8 (UTF-16 or UTF-32)
external_chardata() = external_charlist() | external_unicode_binary()
@@ -93,7 +94,8 @@ external_charlist() = [unicode_char() | external_unicode_binary() | external_cha
<code>
&lt;&lt;Ch/utf8,_/binary&gt;&gt; = Bin1,
&lt;&lt;Ch/utf16-little,_/binary&gt;&gt; = Bin2,
-Bin3 = &lt;&lt;$H/utf32-little, $e/utf32-little, $l/utf32-little, $l/utf32-little, $o/utf32-little&gt;&gt;,</code>
+Bin3 = &lt;&lt;$H/utf32-little, $e/utf32-little, $l/utf32-little, $l/utf32-little,
+ $o/utf32-little&gt;&gt;,</code>
<p>For convenience, literal strings can be encoded with a Unicode encoding in binaries using the following (or similar) syntax:</p>
<code>
Bin4 = &lt;&lt;"Hello"/utf16&gt;&gt;,</code>
diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile
index 68708d6b02..37c836a254 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -173,8 +173,8 @@ $(BOOTSTRAP_COMPILER)/ebin/erl_parse.beam: erl_parse.yrl
$(ERLC) -o $(BOOTSTRAP_COMPILER)/egen erl_parse.yrl
$(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $(BOOTSTRAP_COMPILER)/egen/erl_parse.erl
-#$(BOOTSTRAP_COMPILER)/ebin/erl_lint.beam: erl_lint.erl
-# $(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin erl_lint.erl
+$(BOOTSTRAP_TOP)/lib/stdlib/egen/erl_parse.erl: erl_parse.yrl
+ $(ERLC) $(YRL_FLAGS) -o$(BOOTSTRAP_TOP)/lib/stdlib/egen erl_parse.yrl
$(BOOTSTRAP_COMPILER)/ebin/%.beam: %.erl
$(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $<
diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl
index 31a653bda0..0e98bbaa06 100644
--- a/lib/stdlib/src/edlin.erl
+++ b/lib/stdlib/src/edlin.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(edlin).
@@ -281,12 +281,32 @@ do_op(_, Bef, Aft, Rs) ->
%% Step over word/non-word characters pushing the stepped over ones on
%% the stack.
-over_word([C|Cs], Stack, N) ->
+
+over_word(Cs, Stack, N) ->
+ L = length([1 || $\' <- Cs]),
+ case L rem 2 of
+ 0 ->
+ over_word1(Cs, Stack, N);
+ 1 ->
+ until_quote(Cs, Stack, N)
+ end.
+
+until_quote([$\'|Cs], Stack, N) ->
+ {Cs, [$\'|Stack], N+1};
+until_quote([C|Cs], Stack, N) ->
+ until_quote(Cs, [C|Stack], N+1).
+
+over_word1([$\'=C|Cs], Stack, N) ->
+ until_quote(Cs, [C|Stack], N+1);
+over_word1(Cs, Stack, N) ->
+ over_word2(Cs, Stack, N).
+
+over_word2([C|Cs], Stack, N) ->
case word_char(C) of
- true -> over_word(Cs, [C|Stack], N+1);
+ true -> over_word2(Cs, [C|Stack], N+1);
false -> {[C|Cs],Stack,N}
end;
-over_word([], Stack, N) when is_integer(N) ->
+over_word2([], Stack, N) when is_integer(N) ->
{[],Stack,N}.
over_non_word([C|Cs], Stack, N) ->
diff --git a/lib/stdlib/src/edlin_expand.erl b/lib/stdlib/src/edlin_expand.erl
index 7ed76a6b09..516c0aa30b 100644
--- a/lib/stdlib/src/edlin_expand.erl
+++ b/lib/stdlib/src/edlin_expand.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(edlin_expand).
@@ -46,23 +46,38 @@ expand_module_name(Prefix) ->
match(Prefix, code:all_loaded(), ":").
expand_function_name(ModStr, FuncPrefix) ->
- Mod = list_to_atom(ModStr),
- case erlang:module_loaded(Mod) of
- true ->
- L = Mod:module_info(),
- case lists:keyfind(exports, 1, L) of
- {_, Exports} ->
- match(FuncPrefix, Exports, "(");
- _ ->
- {no, [], []}
- end;
- false ->
+ case to_atom(ModStr) of
+ {ok, Mod} ->
+ case erlang:module_loaded(Mod) of
+ true ->
+ L = Mod:module_info(),
+ case lists:keyfind(exports, 1, L) of
+ {_, Exports} ->
+ match(FuncPrefix, Exports, "(");
+ _ ->
+ {no, [], []}
+ end;
+ false ->
+ {no, [], []}
+ end;
+ error ->
{no, [], []}
end.
+%% if it's a quoted atom, atom_to_list/1 will do the wrong thing.
+to_atom(Str) ->
+ case erl_scan:string(Str) of
+ {ok, [{atom,_,A}], _} ->
+ {ok, A};
+ _ ->
+ error
+ end.
+
match(Prefix, Alts, Extra) ->
Len = length(Prefix),
- Matches = [{S, A} || {H, A} <- Alts, prefix(Prefix, S=atom_to_list(H))],
+ Matches = lists:sort(
+ [{S, A} || {H, A} <- Alts,
+ prefix(Prefix, S=hd(io_lib:fwrite("~w",[H])))]),
case longest_common_head([N || {N, _} <- Matches]) of
{partial, []} ->
{no, [], Matches}; % format_matches(Matches)};
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index 8b702c005b..424aed3d2e 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(epp).
@@ -111,18 +111,24 @@ format_error({bad,W}) ->
io_lib:format("badly formed '~s'", [W]);
format_error({call,What}) ->
io_lib:format("illegal macro call '~s'",[What]);
-format_error({undefined,M}) ->
- io_lib:format("undefined macro '~w'", [M]);
+format_error({undefined,M,none}) ->
+ io_lib:format("undefined macro '~s'", [M]);
+format_error({undefined,M,A}) ->
+ io_lib:format("undefined macro '~s/~p'", [M,A]);
format_error({depth,What}) ->
io_lib:format("~s too deep",[What]);
format_error({mismatch,M}) ->
- io_lib:format("argument mismatch for macro '~w'", [M]);
+ io_lib:format("argument mismatch for macro '~s'", [M]);
format_error({arg_error,M}) ->
- io_lib:format("badly formed argument for macro '~w'", [M]);
+ io_lib:format("badly formed argument for macro '~s'", [M]);
format_error({redefine,M}) ->
- io_lib:format("redefining macro '~w'", [M]);
-format_error({circular,M}) ->
- io_lib:format("circular macro '~w'", [M]);
+ io_lib:format("redefining macro '~s'", [M]);
+format_error({redefine_predef,M}) ->
+ io_lib:format("redefining predefined macro '~s'", [M]);
+format_error({circular,M,none}) ->
+ io_lib:format("circular macro '~s'", [M]);
+format_error({circular,M,A}) ->
+ io_lib:format("circular macro '~s/~p'", [M,A]);
format_error({include,W,F}) ->
io_lib:format("can't find include ~s \"~s\"", [W,F]);
format_error({illegal,How,What}) ->
@@ -258,18 +264,23 @@ user_predef([{M,Val,redefine}|Pdm], Ms) when is_atom(M) ->
user_predef(Pdm, dict:store({atom,M}, {none,Exp}, Ms));
user_predef([{M,Val}|Pdm], Ms) when is_atom(M) ->
case dict:find({atom,M}, Ms) of
- {ok,_Def} ->
+ {ok,_Defs} when is_list(_Defs) -> %% User defined macros
{error,{redefine,M}};
+ {ok,_Def} -> %% Predefined macros
+ {error,{redefine_predef,M}};
error ->
Exp = erl_parse:tokens(erl_parse:abstract(Val)),
- user_predef(Pdm, dict:store({atom,M}, {none,Exp}, Ms))
+ user_predef(Pdm, dict:store({atom,M}, [{none, {none,Exp}}], Ms))
end;
user_predef([M|Pdm], Ms) when is_atom(M) ->
case dict:find({atom,M}, Ms) of
- {ok,_Def} ->
+ {ok,_Defs} when is_list(_Defs) -> %% User defined macros
{error,{redefine,M}};
+ {ok,_Def} -> %% Predefined macros
+ {error,{redefine_predef,M}};
error ->
- user_predef(Pdm, dict:store({atom,M}, {none,[{atom,1,true}]}, Ms))
+ user_predef(Pdm,
+ dict:store({atom,M}, [{none, {none,[{atom,1,true}]}}], Ms))
end;
user_predef([Md|_Pdm], _Ms) -> {error,{bad,Md}};
user_predef([], Ms) -> {ok,Ms}.
@@ -476,57 +487,56 @@ scan_extends(_Ts, _As, Ms) -> Ms.
%% scan_define(Tokens, DefineToken, From, EppState)
-scan_define([{'(',_Lp},{atom,_Lm,M}=Mac,{',',_Lc}|Toks], _Def, From, St) ->
+scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{',',_Lc}|Toks], _Def, From, St)
+ when Type =:= atom; Type =:= var ->
case dict:find({atom,M}, St#epp.macs) of
- {ok,_OldDef} ->
- epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}),
- wait_req_scan(St);
- error ->
- scan_define_cont(From, St,
- {atom, M},
- {none,macro_expansion(Toks)})
- end;
-scan_define([{'(',_Lp},{atom,_Lm,M}=Mac,{'(',_Lc}|Toks], Def, From, St) ->
- case dict:find({atom,M}, St#epp.macs) of
- {ok,_Def} ->
- epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}),
- wait_req_scan(St);
- error ->
- case catch macro_pars(Toks, []) of
- {ok, {As, Me}} ->
- scan_define_cont(From, St,
- {atom, M},
- {As, Me});
- _ ->
- epp_reply(From, {error,{loc(Def),epp,{bad,define}}}),
- wait_req_scan(St)
- end
- end;
-scan_define([{'(',_Lp},{var,_Lm,M}=Mac,{',',_Lc}|Toks], _Def, From, St) ->
- case dict:find({atom,M}, St#epp.macs) of
- {ok,_OldDef} ->
- epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}),
- wait_req_scan(St);
- error ->
- scan_define_cont(From, St,
- {atom, M},
- {none,macro_expansion(Toks)})
+ {ok, Defs} when is_list(Defs) ->
+ %% User defined macros: can be overloaded
+ case proplists:is_defined(none, Defs) of
+ true ->
+ epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}),
+ wait_req_scan(St);
+ false ->
+ scan_define_cont(From, St,
+ {atom, M},
+ {none, {none,macro_expansion(Toks)}})
+ end;
+ {ok, _PreDef} ->
+ %% Predefined macros: cannot be overloaded
+ epp_reply(From, {error,{loc(Mac),epp,{redefine_predef,M}}}),
+ wait_req_scan(St);
+ error ->
+ scan_define_cont(From, St,
+ {atom, M},
+ {none, {none,macro_expansion(Toks)}})
end;
-scan_define([{'(',_Lp},{var,_Lm,M}=Mac,{'(',_Lc}|Toks], Def, From, St) ->
- case dict:find({atom,M}, St#epp.macs) of
- {ok,_Def} ->
- epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}),
- wait_req_scan(St);
- error ->
- case catch macro_pars(Toks, []) of
- {ok, {As, Me}} ->
- scan_define_cont(From, St,
- {atom, M},
- {As, Me});
- _ ->
- epp_reply(From, {error,{loc(Def),epp,{bad,define}}}),
- wait_req_scan(St)
- end
+scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{'(',_Lc}|Toks], Def, From, St)
+ when Type =:= atom; Type =:= var ->
+ case catch macro_pars(Toks, []) of
+ {ok, {As,Me}} ->
+ Len = length(As),
+ case dict:find({atom,M}, St#epp.macs) of
+ {ok, Defs} when is_list(Defs) ->
+ %% User defined macros: can be overloaded
+ case proplists:is_defined(Len, Defs) of
+ true ->
+ epp_reply(From,{error,{loc(Mac),epp,{redefine,M}}}),
+ wait_req_scan(St);
+ false ->
+ scan_define_cont(From, St, {atom, M},
+ {Len, {As, Me}})
+ end;
+ {ok, _PreDef} ->
+ %% Predefined macros: cannot be overloaded
+ %% (There are currently no predefined F(...) macros.)
+ epp_reply(From, {error,{loc(Mac),epp,{redefine_predef,M}}}),
+ wait_req_scan(St);
+ error ->
+ scan_define_cont(From, St, {atom, M}, {Len, {As, Me}})
+ end;
+ _ ->
+ epp_reply(From, {error,{loc(Def),epp,{bad,define}}}),
+ wait_req_scan(St)
end;
scan_define(_Toks, Def, From, St) ->
epp_reply(From, {error,{loc(Def),epp,{bad,define}}}),
@@ -541,13 +551,17 @@ scan_define(_Toks, Def, From, St) ->
%%% the information from St#epp.uses is traversed, and if a circularity
%%% is detected, an error message is thrown.
-scan_define_cont(F, St, M, Def) ->
- Ms = dict:store(M, Def, St#epp.macs),
- U = dict:store(M, macro_uses(Def), St#epp.uses),
- scan_toks(F, St#epp{uses=U, macs=Ms}).
+scan_define_cont(F, St, M, {Arity, Def}) ->
+ Ms = dict:append_list(M, [{Arity, Def}], St#epp.macs),
+ try dict:append_list(M, [{Arity, macro_uses(Def)}], St#epp.uses) of
+ U ->
+ scan_toks(F, St#epp{uses=U, macs=Ms})
+ catch
+ {error, Line, Reason} ->
+ epp_reply(F, {error,{Line,epp,Reason}}),
+ wait_req_scan(St)
+ end.
-macro_uses(undefined) ->
- undefined;
macro_uses({_Args, Tokens}) ->
Uses0 = macro_ref(Tokens),
lists:usort(Uses0).
@@ -556,31 +570,25 @@ macro_ref([]) ->
[];
macro_ref([{'?', _}, {'?', _} | Rest]) ->
macro_ref(Rest);
-macro_ref([{'?', _}, {atom, _, A} | Rest]) ->
- [{atom, A} | macro_ref(Rest)];
-macro_ref([{'?', _}, {var, _, A} | Rest]) ->
- [{atom, A} | macro_ref(Rest)];
+macro_ref([{'?', _}, {atom, Lm, A} | Rest]) ->
+ Arity = count_args(Rest, Lm, A),
+ [{{atom, A}, Arity} | macro_ref(Rest)];
+macro_ref([{'?', _}, {var, Lm, A} | Rest]) ->
+ Arity = count_args(Rest, Lm, A),
+ [{{atom, A}, Arity} | macro_ref(Rest)];
macro_ref([_Token | Rest]) ->
macro_ref(Rest).
-all_macro_uses(D0) ->
- L = dict:to_list(D0),
- D = dict:new(),
- add_macro_uses(L, D).
-
-add_macro_uses([], D) ->
- D;
-add_macro_uses([{Key, Def} | Rest], D0) ->
- add_macro_uses(Rest, dict:store(Key, macro_uses(Def), D0)).
-
%% scan_undef(Tokens, UndefToken, From, EppState)
scan_undef([{'(',_Llp},{atom,_Lm,M},{')',_Lrp},{dot,_Ld}], _Undef, From, St) ->
- scan_toks(From, St#epp{macs=dict:erase({atom,M}, St#epp.macs),
- uses=all_macro_uses(St#epp.macs)});
+ Macs = dict:erase({atom,M}, St#epp.macs),
+ Uses = dict:erase({atom,M}, St#epp.uses),
+ scan_toks(From, St#epp{macs=Macs, uses=Uses});
scan_undef([{'(',_Llp},{var,_Lm,M},{')',_Lrp},{dot,_Ld}], _Undef, From,St) ->
- scan_toks(From, St#epp{macs=dict:erase({atom,M}, St#epp.macs),
- uses=all_macro_uses(St#epp.macs)});
+ Macs = dict:erase({atom,M}, St#epp.macs),
+ Uses = dict:erase({atom,M}, St#epp.uses),
+ scan_toks(From, St#epp{macs=Macs, uses=Uses});
scan_undef(_Toks, Undef, From, St) ->
epp_reply(From, {error,{loc(Undef),epp,{bad,undef}}}),
wait_req_scan(St).
@@ -819,42 +827,57 @@ expand_macros(Type, MacT, M, Toks, Ms0) ->
%% (Type will always be 'atom')
{Ms, U} = Ms0,
Lm = loc(MacT),
- check_uses([{Type,M}], [], U, Lm),
Tinfo = element(2, MacT),
- case dict:find({Type,M}, Ms) of
+ case expand_macro1(Type, Lm, M, Toks, Ms) of
{ok,{none,Exp}} ->
- expand_macros(expand_macro(Exp, Tinfo, Toks, dict:new()), Ms0);
+ check_uses([{{Type,M}, none}], [], U, Lm),
+ Toks1 = expand_macros(expand_macro(Exp, Tinfo, [], dict:new()), Ms0),
+ expand_macros(Toks1++Toks, Ms0);
{ok,{As,Exp}} ->
+ check_uses([{{Type,M}, length(As)}], [], U, Lm),
{Bs,Toks1} = bind_args(Toks, Lm, M, As, dict:new()),
- %%io:format("Bound arguments to macro ~w (~w)~n", [M,Bs]),
- expand_macros(expand_macro(Exp, Tinfo, Toks1, Bs), Ms0);
- {ok,undefined} ->
- throw({error,Lm,{undefined,M}});
- error ->
- throw({error,Lm,{undefined,M}})
+ expand_macros(expand_macro(Exp, Tinfo, Toks1, Bs), Ms0)
+ end.
+
+expand_macro1(Type, Lm, M, Toks, Ms) ->
+ Arity = count_args(Toks, Lm, M),
+ case dict:find({Type,M}, Ms) of
+ error -> %% macro not found
+ throw({error,Lm,{undefined,M,Arity}});
+ {ok, undefined} -> %% Predefined macro without definition
+ throw({error,Lm,{undefined,M,Arity}});
+ {ok, [{none, Def}]} ->
+ {ok, Def};
+ {ok, Defs} when is_list(Defs) ->
+ case proplists:get_value(Arity, Defs) of
+ undefined ->
+ throw({error,Lm,{mismatch,M}});
+ Def ->
+ {ok, Def}
+ end;
+ {ok, PreDef} -> %% Predefined macro
+ {ok, PreDef}
end.
-check_uses(undefined, _Anc, _U, _Lm) ->
- ok;
check_uses([], _Anc, _U, _Lm) ->
ok;
check_uses([M|Rest], Anc, U, Lm) ->
case lists:member(M, Anc) of
true ->
- {_, Name} = M,
- throw({error,Lm,{circular,Name}});
+ {{_, Name},Arity} = M,
+ throw({error,Lm,{circular,Name,Arity}});
false ->
L = get_macro_uses(M, U),
check_uses(L, [M|Anc], U, Lm),
check_uses(Rest, Anc, U, Lm)
end.
-
-get_macro_uses(M, U) ->
+
+get_macro_uses({M,Arity}, U) ->
case dict:find(M, U) of
error ->
[];
{ok, L} ->
- L
+ proplists:get_value(Arity, L, proplists:get_value(none, L, []))
end.
%% Macro expansion
@@ -882,7 +905,7 @@ expand_macros([T|Ts], Ms) ->
expand_macros([], _Ms) -> [].
%% bind_args(Tokens, MacroLocation, MacroName, ArgumentVars, Bindings)
-%% Collect the arguments to a macro call and check for correct number.
+%% Collect the arguments to a macro call.
bind_args([{'(',_Llp},{')',_Lrp}|Toks], _Lm, _M, [], Bs) ->
{Bs,Toks};
@@ -890,7 +913,7 @@ bind_args([{'(',_Llp}|Toks0], Lm, M, [A|As], Bs) ->
{Arg,Toks1} = macro_arg(Toks0, [], []),
macro_args(Toks1, Lm, M, As, store_arg(Lm, M, A, Arg, Bs));
bind_args(_Toks, Lm, M, _As, _Bs) ->
- throw({error,Lm,{mismatch,M}}).
+ throw({error,Lm,{mismatch,M}}). % Cannot happen.
macro_args([{')',_Lrp}|Toks], _Lm, _M, [], Bs) ->
{Bs,Toks};
@@ -898,15 +921,39 @@ macro_args([{',',_Lc}|Toks0], Lm, M, [A|As], Bs) ->
{Arg,Toks1} = macro_arg(Toks0, [], []),
macro_args(Toks1, Lm, M, As, store_arg(Lm, M, A, Arg, Bs));
macro_args([], Lm, M, _As, _Bs) ->
- throw({error,Lm,{arg_error,M}});
+ throw({error,Lm,{arg_error,M}}); % Cannot happen.
macro_args(_Toks, Lm, M, _As, _Bs) ->
- throw({error,Lm,{mismatch,M}}).
+ throw({error,Lm,{mismatch,M}}). % Cannot happen.
store_arg(L, M, _A, [], _Bs) ->
throw({error,L,{mismatch,M}});
store_arg(_L, _M, A, Arg, Bs) ->
dict:store(A, Arg, Bs).
+%% count_args(Tokens, MacroLine, MacroName)
+%% Count the number of arguments in a macro call.
+count_args([{'(', _Llp},{')',_Lrp}|_Toks], _Lm, _M) ->
+ 0;
+count_args([{'(', _Llp},{',',_Lc}|_Toks], Lm, M) ->
+ throw({error,Lm,{arg_error,M}});
+count_args([{'(',_Llp}|Toks0], Lm, M) ->
+ {_Arg,Toks1} = macro_arg(Toks0, [], []),
+ count_args(Toks1, Lm, M, 1);
+count_args(_Toks, _Lm, _M) ->
+ none.
+
+count_args([{')',_Lrp}|_Toks], _Lm, _M, NbArgs) ->
+ NbArgs;
+count_args([{',',_Lc},{')',_Lrp}|_Toks], Lm, M, _NbArgs) ->
+ throw({error,Lm,{arg_error,M}});
+count_args([{',',_Lc}|Toks0], Lm, M, NbArgs) ->
+ {_Arg,Toks1} = macro_arg(Toks0, [], []),
+ count_args(Toks1, Lm, M, NbArgs+1);
+count_args([], Lm, M, _NbArgs) ->
+ throw({error,Lm,{arg_error,M}});
+count_args(_Toks, Lm, M, _NbArgs) ->
+ throw({error,Lm,{mismatch,M}}). % Cannot happen.
+
%% macro_arg([Tok], [ClosePar], [ArgTok]) -> {[ArgTok],[RestTok]}.
%% Collect argument tokens until we hit a ',' or a ')'. We know a
%% enough about syntax to recognise "open parentheses" and keep
diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl
index 697a69b801..c0f71fb3f5 100644
--- a/lib/stdlib/src/escript.erl
+++ b/lib/stdlib/src/escript.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(escript).
@@ -180,7 +180,8 @@ parse_and_run(File, Args, Options) ->
is_binary(FormsOrBin) ->
case Source of
archive ->
- case code:set_primary_archive(File, FormsOrBin) of
+ {ok, FileInfo} = file:read_file_info(File),
+ case code:set_primary_archive(File, FormsOrBin, FileInfo) of
ok when CheckOnly ->
case code:load_file(Module) of
{module, _} ->
diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl
index d65588f0d1..74c5172137 100644
--- a/lib/stdlib/src/filelib.erl
+++ b/lib/stdlib/src/filelib.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(filelib).
@@ -228,7 +228,17 @@ ensure_dir(F) ->
ok;
false ->
ensure_dir(Dir),
- file:make_dir(Dir)
+ case file:make_dir(Dir) of
+ {error,eexist}=EExist ->
+ case do_is_dir(Dir, file) of
+ true ->
+ ok;
+ false ->
+ EExist
+ end;
+ Err ->
+ Err
+ end
end.
diff --git a/lib/stdlib/src/re.erl b/lib/stdlib/src/re.erl
index 5417ac02e5..296a6b3d23 100644
--- a/lib/stdlib/src/re.erl
+++ b/lib/stdlib/src/re.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(re).
@@ -32,18 +32,7 @@ split(Subject,RE,Options) ->
try
{NewOpt,Convert,Unicode,Limit,Strip,Group} =
process_split_params(Options,iodata,false,-1,false,false),
- FlatSubject =
- case is_binary(Subject) of
- true ->
- Subject;
- false ->
- case Unicode of
- true ->
- unicode:characters_to_binary(Subject,unicode);
- false ->
- iolist_to_binary(Subject)
- end
- end,
+ FlatSubject = to_binary(Subject, Unicode),
case compile_split(RE,NewOpt) of
{error,_Err} ->
throw(badre);
@@ -217,19 +206,9 @@ replace(Subject,RE,Replacement,Options) ->
try
{NewOpt,Convert,Unicode} =
process_repl_params(Options,iodata,false),
- FlatSubject =
- case is_binary(Subject) of
- true ->
- Subject;
- false ->
- case Unicode of
- true ->
- unicode:characters_to_binary(Subject,unicode);
- false ->
- iolist_to_binary(Subject)
- end
- end,
- case do_replace(FlatSubject,Subject,RE,Replacement,NewOpt) of
+ FlatSubject = to_binary(Subject, Unicode),
+ FlatReplacement = to_binary(Replacement, Unicode),
+ case do_replace(FlatSubject,Subject,RE,FlatReplacement,NewOpt) of
{error,_Err} ->
throw(badre);
IoList ->
@@ -237,7 +216,12 @@ replace(Subject,RE,Replacement,Options) ->
iodata ->
IoList;
binary ->
- iolist_to_binary(IoList);
+ case Unicode of
+ false ->
+ iolist_to_binary(IoList);
+ true ->
+ unicode:characters_to_binary(IoList,unicode)
+ end;
list ->
case Unicode of
false ->
@@ -324,8 +308,7 @@ process_split_params([H|T],C,U,L,S,G) ->
{[H|NT],NC,NU,NL,NS,NG}.
apply_mlist(Subject,Replacement,Mlist) ->
- do_mlist(Subject,Subject,0,precomp_repl(iolist_to_binary(Replacement)),
- Mlist).
+ do_mlist(Subject,Subject,0,precomp_repl(Replacement), Mlist).
precomp_repl(<<>>) ->
@@ -545,7 +528,7 @@ process_uparams([],Type) ->
ucompile(RE,Options) ->
try
- re:compile(unicode:characters_to_binary(RE,unicode))
+ re:compile(unicode:characters_to_binary(RE,unicode),Options)
catch
error:AnyError ->
{'EXIT',{new_stacktrace,[{Mod,_,L}|Rest]}} =
@@ -618,18 +601,7 @@ grun(Subject,RE,{Options,NeedClean,OrigRE}) ->
grun2(Subject,RE,{Options,NeedClean}) ->
Unicode = check_for_unicode(RE,Options),
- FlatSubject =
- case is_binary(Subject) of
- true ->
- Subject;
- false ->
- case Unicode of
- true ->
- unicode:characters_to_binary(Subject,unicode);
- false ->
- iolist_to_binary(Subject)
- end
- end,
+ FlatSubject = to_binary(Subject, Unicode),
do_grun(FlatSubject,Subject,Unicode,RE,{Options,NeedClean}).
do_grun(FlatSubject,Subject,Unicode,RE,{Options0,NeedClean}) ->
@@ -749,3 +721,10 @@ runopt(global) ->
true;
runopt(_) ->
false.
+
+to_binary(Bin, _IsUnicode) when is_binary(Bin) ->
+ Bin;
+to_binary(Data, true) ->
+ unicode:characters_to_binary(Data,unicode);
+to_binary(Data, false) ->
+ iolist_to_binary(Data).
diff --git a/lib/stdlib/test/ExpandTestCaps.erl b/lib/stdlib/test/ExpandTestCaps.erl
new file mode 100644
index 0000000000..96c4115354
--- /dev/null
+++ b/lib/stdlib/test/ExpandTestCaps.erl
@@ -0,0 +1,32 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module('ExpandTestCaps').
+
+-export([a_fun_name/1,
+ a_less_fun_name/1,
+ b_comes_after_a/1]).
+
+a_fun_name(X) ->
+ X.
+
+a_less_fun_name(X) ->
+ X.
+
+b_comes_after_a(X) ->
+ X.
diff --git a/lib/stdlib/test/ExpandTestCaps1.erl b/lib/stdlib/test/ExpandTestCaps1.erl
new file mode 100644
index 0000000000..09ee9f81c4
--- /dev/null
+++ b/lib/stdlib/test/ExpandTestCaps1.erl
@@ -0,0 +1,44 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module('ExpandTestCaps1').
+
+-export([a_fun_name/1,
+ a_less_fun_name/1,
+ b_comes_after_a/1,
+ 'Quoted_fun_name'/0,
+ 'Quoted_fun_too'/0,
+ '#weird-fun-name'/0]).
+
+a_fun_name(X) ->
+ X.
+
+a_less_fun_name(X) ->
+ X.
+
+b_comes_after_a(X) ->
+ X.
+
+'Quoted_fun_name'() ->
+ whoopee.
+
+'Quoted_fun_too'() ->
+ too.
+
+'#weird-fun-name'() ->
+ weird.
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index 7a87eef5f3..9beac93eb8 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -18,6 +18,7 @@ MODULES= \
digraph_utils_SUITE \
dummy1_h \
dummy_h \
+ edlin_expand_SUITE \
epp_SUITE \
erl_eval_helper \
erl_eval_SUITE \
@@ -29,6 +30,10 @@ MODULES= \
escript_SUITE \
ets_SUITE \
ets_tough_SUITE \
+ expand_test \
+ expand_test1 \
+ ExpandTestCaps \
+ ExpandTestCaps1 \
filelib_SUITE \
file_sorter_SUITE \
filename_SUITE \
@@ -105,7 +110,7 @@ COVERFILE=stdlib.cover
make_emakefile:
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
- >> $(EMAKEFILE)
+ > $(EMAKEFILE)
tests debug opt: make_emakefile
erl $(ERL_MAKE_FLAGS) -make
diff --git a/lib/stdlib/test/calendar_SUITE.erl b/lib/stdlib/test/calendar_SUITE.erl
index ea81bb99a9..10fb72c1b1 100644
--- a/lib/stdlib/test/calendar_SUITE.erl
+++ b/lib/stdlib/test/calendar_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(calendar_SUITE).
@@ -48,7 +48,7 @@ gregorian_days(doc) ->
"At the same time valid_date is tested.";
gregorian_days(suite) ->
[];
-gregorian_days(Config) when list(Config) ->
+gregorian_days(Config) when is_list(Config) ->
?line Days = calendar:date_to_gregorian_days({?START_YEAR, 1, 1}),
?line MaxDays = calendar:date_to_gregorian_days({?END_YEAR, 1, 1}),
?line check_gregorian_days(Days, MaxDays).
@@ -60,7 +60,7 @@ gregorian_seconds(doc) ->
"every 2 days + 1 second.";
gregorian_seconds(suite) ->
[];
-gregorian_seconds(Config) when list(Config) ->
+gregorian_seconds(Config) when is_list(Config) ->
?line Secs = calendar:datetime_to_gregorian_seconds({{?START_YEAR, 1, 1},
{0, 0, 0}}),
?line MaxSecs = calendar:datetime_to_gregorian_seconds({{?END_YEAR, 1, 1},
@@ -72,7 +72,7 @@ day_of_the_week(doc) ->
"year ?START_YEAR up to ?END_YEAR.";
day_of_the_week(suite) ->
[];
-day_of_the_week(Config) when list(Config) ->
+day_of_the_week(Config) when is_list(Config) ->
?line Days = calendar:date_to_gregorian_days({?START_YEAR, 1, 1}),
?line MaxDays = calendar:date_to_gregorian_days({?END_YEAR, 1, 1}),
?line DayNumber = calendar:day_of_the_week({?START_YEAR, 1, 1}),
@@ -82,7 +82,7 @@ day_of_the_week_calibrate(doc) ->
"Tests that day_of_the_week for 1997-11-11 is Tuesday (2)";
day_of_the_week_calibrate(suite) ->
[];
-day_of_the_week_calibrate(Config) when list(Config) ->
+day_of_the_week_calibrate(Config) when is_list(Config) ->
?line 2 = calendar:day_of_the_week({1997, 11, 11}).
leap_years(doc) ->
@@ -90,7 +90,7 @@ leap_years(doc) ->
"year ?START_YEAR up to ?END_YEAR.";
leap_years(suite) ->
[];
-leap_years(Config) when list(Config) ->
+leap_years(Config) when is_list(Config) ->
?line check_leap_years(?START_YEAR, ?END_YEAR).
last_day_of_the_month(doc) ->
@@ -98,14 +98,14 @@ last_day_of_the_month(doc) ->
"year ?START_YEAR up to ?END_YEAR.";
last_day_of_the_month(suite) ->
[];
-last_day_of_the_month(Config) when list(Config) ->
+last_day_of_the_month(Config) when is_list(Config) ->
?line check_last_day_of_the_month({?START_YEAR, 1}, {?END_YEAR, 1}).
local_time_to_universal_time_dst(doc) ->
"Tests local_time_to_universal_time_dst for MET";
local_time_to_universal_time_dst(suite) ->
[];
-local_time_to_universal_time_dst(Config) when list(Config) ->
+local_time_to_universal_time_dst(Config) when is_list(Config) ->
case os:type() of
{unix,_} ->
case os:cmd("date '+%Z'") of
@@ -117,7 +117,7 @@ local_time_to_universal_time_dst(Config) when list(Config) ->
_ ->
local_time_to_universal_time_dst_x(Config)
end.
-local_time_to_universal_time_dst_x(Config) when list(Config) ->
+local_time_to_universal_time_dst_x(Config) when is_list(Config) ->
%% Assumes MET (UTC+1 / UTC+2(dst)
?line LtW = {{2003,01,15},{14,00,00}}, % Winter
?line UtW = {{2003,01,15},{13,00,00}}, %
diff --git a/lib/stdlib/test/edlin_expand_SUITE.erl b/lib/stdlib/test/edlin_expand_SUITE.erl
new file mode 100644
index 0000000000..613bfd000e
--- /dev/null
+++ b/lib/stdlib/test/edlin_expand_SUITE.erl
@@ -0,0 +1,156 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(edlin_expand_SUITE).
+-export([all/1]).
+
+-export([normal/1, quoted_fun/1, quoted_module/1, quoted_both/1]).
+
+-export([init_per_testcase/2, fin_per_testcase/2]).
+
+-include("test_server.hrl").
+
+% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(doc) ->
+ ["Test cases for edlin_expand."];
+all(suite) ->
+ [normal, quoted_fun, quoted_module, quoted_both].
+
+normal(doc) ->
+ [""];
+normal(suite) ->
+ [];
+normal(Config) when is_list(Config) ->
+ ?line {module,expand_test} = c:l(expand_test),
+ % These tests might fail if another module with the prefix "expand_" happens
+ % to also be loaded.
+ ?line {yes, "test:", []} = edlin_expand:expand(lists:reverse("expand_")),
+ ?line {no, [], []} = edlin_expand:expand(lists:reverse("expandXX_")),
+ ?line {no,[],
+ [{"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = edlin_expand:expand(lists:reverse("expand_test:")),
+ ?line {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = edlin_expand:expand(
+ lists:reverse("expand_test:a_")),
+ ok.
+
+quoted_fun(doc) ->
+ ["Normal module name, some function names using quoted atoms"];
+quoted_fun(suite) ->
+ [];
+quoted_fun(Config) when is_list(Config) ->
+ ?line {module,expand_test} = c:l(expand_test),
+ ?line {module,expand_test1} = c:l(expand_test1),
+ %% should be no colon after test this time
+ ?line {yes, "test", []} = edlin_expand:expand(lists:reverse("expand_")),
+ ?line {no, [], []} = edlin_expand:expand(lists:reverse("expandXX_")),
+ ?line {no,[],[{"'#weird-fun-name'",0},
+ {"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0},
+ {"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = edlin_expand:expand(
+ lists:reverse("expand_test1:")),
+ ?line {yes,"_",[]} = edlin_expand:expand(
+ lists:reverse("expand_test1:a")),
+ ?line {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = edlin_expand:expand(
+ lists:reverse("expand_test1:a_")),
+ ?line {yes,[],
+ [{"'#weird-fun-name'",0},
+ {"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
+ lists:reverse("expand_test1:'")),
+ ?line {yes,"uoted_fun_",[]} = edlin_expand:expand(
+ lists:reverse("expand_test1:'Q")),
+ ?line {yes,[],
+ [{"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
+ lists:reverse("expand_test1:'Quoted_fun_")),
+ ?line {yes,"weird-fun-name'(",[]} = edlin_expand:expand(
+ lists:reverse("expand_test1:'#")),
+ ok.
+
+quoted_module(doc) ->
+ [""];
+quoted_module(suite) ->
+ [];
+quoted_module(Config) when is_list(Config) ->
+ ?line {module,'ExpandTestCaps'} = c:l('ExpandTestCaps'),
+ ?line {yes, "Caps':", []} = edlin_expand:expand(lists:reverse("'ExpandTest")),
+ ?line {no,[],
+ [{"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = edlin_expand:expand(lists:reverse("'ExpandTestCaps':")),
+ ?line {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps':a_")),
+ ok.
+
+quoted_both(suite) ->
+ [];
+quoted_both(Config) when is_list(Config) ->
+ ?line {module,'ExpandTestCaps'} = c:l('ExpandTestCaps'),
+ ?line {module,'ExpandTestCaps1'} = c:l('ExpandTestCaps1'),
+ %% should be no colon (or quote) after test this time
+ ?line {yes, "Caps", []} = edlin_expand:expand(lists:reverse("'ExpandTest")),
+ ?line {no,[],[{"'#weird-fun-name'",0},
+ {"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0},
+ {"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':")),
+ ?line {yes,"_",[]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':a")),
+ ?line {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':a_")),
+ ?line {yes,[],
+ [{"'#weird-fun-name'",0},
+ {"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':'")),
+ ?line {yes,"uoted_fun_",[]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':'Q")),
+ ?line {yes,[],
+ [{"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':'Quoted_fun_")),
+ ?line {yes,"weird-fun-name'(",[]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':'#")),
+ ok.
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index 67e20fd2e1..9a3ae0baf5 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(epp_SUITE).
@@ -23,7 +23,7 @@
upcase_mac/1, upcase_mac_1/1, upcase_mac_2/1,
variable/1, variable_1/1, otp_4870/1, otp_4871/1, otp_5362/1,
pmod/1, not_circular/1, skip_header/1, otp_6277/1, otp_7702/1,
- otp_8130/1]).
+ otp_8130/1, overload_mac/1, otp_8388/1]).
-export([epp_parse_erl_form/2]).
@@ -61,8 +61,9 @@ fin_per_testcase(_, Config) ->
all(doc) ->
["Test cases for epp."];
all(suite) ->
- [rec_1, upcase_mac, predef_mac, variable, otp_4870, otp_4871, otp_5362,
- pmod, not_circular, skip_header, otp_6277, otp_7702, otp_8130].
+ [rec_1, upcase_mac, predef_mac, variable, otp_4870, otp_4871, otp_5362,
+ pmod, not_circular, skip_header, otp_6277, otp_7702, otp_8130,
+ overload_mac, otp_8388].
rec_1(doc) ->
["Recursive macros hang or crash epp (OTP-1398)."];
@@ -466,7 +467,7 @@ otp_6277(Config) when is_list(Config) ->
-define(ASSERT, ?MODULE).
?ASSERT().">>,
- [{error,{{4,16},epp,{undefined,'MODULE'}}}]}],
+ [{error,{{4,16},epp,{undefined,'MODULE', none}}}]}],
?line [] = check(Config, Ts),
ok.
@@ -673,7 +674,7 @@ otp_8130(Config) when is_list(Config) ->
{otp_8130_c7,
<<"\nt() -> ?A.\n">>,
- {errors,[{{2,9},epp,{undefined,'A'}}],[]}},
+ {errors,[{{2,9},epp,{undefined,'A', none}}],[]}},
{otp_8130_c8,
<<"\n-include_lib(\"$apa/foo.hrl\").\n">>,
@@ -683,7 +684,7 @@ otp_8130(Config) when is_list(Config) ->
{otp_8130_c9,
<<"-define(S, ?S).\n"
"t() -> ?S.\n">>,
- {errors,[{{2,9},epp,{circular,'S'}}],[]}},
+ {errors,[{{2,9},epp,{circular,'S', none}}],[]}},
{otp_8130_c10,
<<"\n-file.">>,
@@ -718,22 +719,22 @@ otp_8130(Config) when is_list(Config) ->
{otp_8130_c17,
<<"\n-define(A(B), B).\n"
"-define(A, 1).\n">>,
- {errors,[{{3,9},epp,{redefine,'A'}}],[]}},
+ []},
{otp_8130_c18,
<<"\n-define(A, 1).\n"
"-define(A(B), B).\n">>,
- {errors,[{{3,9},epp,{redefine,'A'}}],[]}},
+ []},
{otp_8130_c19,
<<"\n-define(a(B), B).\n"
"-define(a, 1).\n">>,
- {errors,[{{3,9},epp,{redefine,a}}],[]}},
+ []},
{otp_8130_c20,
<<"\n-define(a, 1).\n"
"-define(a(B), B).\n">>,
- {errors,[{{3,9},epp,{redefine,a}}],[]}},
+ []},
{otp_8130_c21,
<<"\n-define(A(B, B), B).\n">>,
@@ -745,7 +746,7 @@ otp_8130(Config) when is_list(Config) ->
{otp_8130_c23,
<<"\n-file(?b, 3).\n">>,
- {errors,[{{2,8},epp,{undefined,b}}],[]}},
+ {errors,[{{2,8},epp,{undefined,b, none}}],[]}},
{otp_8130_c24,
<<"\n-include(\"no such file.erl\").\n">>,
@@ -821,7 +822,8 @@ macs(Epp) ->
macro(Epp, N) ->
case lists:keyfind({atom,N}, 1, epp:macro_defs(Epp)) of
false -> false;
- {{atom,N},{_,V}} -> V
+ {{atom,N},{_,V}} -> V;
+ {{atom,N},Defs} -> lists:append([V || {_,{_,V}} <- Defs])
end.
ifdef(Config) ->
@@ -1030,6 +1032,113 @@ ifdef(Config) ->
],
?line [] = run(Config, Ts).
+
+
+overload_mac(doc) ->
+ ["Advanced test on overloading macros."];
+overload_mac(suite) ->
+ [];
+overload_mac(Config) when is_list(Config) ->
+ Cs = [
+ %% '-undef' removes all definitions of a macro
+ {overload_mac_c1,
+ <<"-define(A, a).\n"
+ "-define(A(X), X).\n"
+ "-undef(A).\n"
+ "t1() -> ?A.\n",
+ "t2() -> ?A(1).">>,
+ {errors,[{{4,9},epp,{undefined,'A', none}},
+ {{5,9},epp,{undefined,'A', 1}}],[]}},
+
+ %% cannot overload predefined macros
+ {overload_mac_c2,
+ <<"-define(MODULE(X), X).">>,
+ {errors,[{{1,9},epp,{redefine_predef,'MODULE'}}],[]}},
+
+ %% cannot overload macros with same arity
+ {overload_mac_c3,
+ <<"-define(A(X), X).\n"
+ "-define(A(Y), Y).">>,
+ {errors,[{{2,9},epp,{redefine,'A'}}],[]}},
+
+ {overload_mac_c4,
+ <<"-define(A, a).\n"
+ "-define(A(X,Y), {X,Y}).\n"
+ "a(X) -> X.\n"
+ "t() -> ?A(1).">>,
+ {errors,[{{4,9},epp,{mismatch,'A'}}],[]}}
+ ],
+ ?line [] = compile(Config, Cs),
+
+ Ts = [
+ {overload_mac_r1,
+ <<"-define(A, 1).\n"
+ "-define(A(X), X).\n"
+ "-define(A(X, Y), {X, Y}).\n"
+ "t() -> {?A, ?A(2), ?A(3, 4)}.">>,
+ {1, 2, {3, 4}}},
+
+ {overload_mac_r2,
+ <<"-define(A, 1).\n"
+ "-define(A(X), X).\n"
+ "t() -> ?A(?A).">>,
+ 1},
+
+ {overload_mac_r3,
+ <<"-define(A, ?B).\n"
+ "-define(B, a).\n"
+ "-define(B(X), {b,X}).\n"
+ "a(X) -> X.\n"
+ "t() -> ?A(1).">>,
+ 1}
+ ],
+ ?line [] = run(Config, Ts).
+
+
+otp_8388(doc) ->
+ ["OTP-8388. More tests on overloaded macros."];
+otp_8388(suite) ->
+ [];
+otp_8388(Config) when is_list(Config) ->
+ Dir = ?config(priv_dir, Config),
+ ?line File = filename:join(Dir, "otp_8388.erl"),
+ ?line ok = file:write_file(File, <<"-module(otp_8388)."
+ "-define(LINE, a).">>),
+ fun() ->
+ PreDefMacros = [{'LINE', a}],
+ ?line {error,{redefine_predef,'LINE'}} =
+ epp:open(File, [], PreDefMacros)
+ end(),
+
+ fun() ->
+ PreDefMacros = ['LINE'],
+ ?line {error,{redefine_predef,'LINE'}} =
+ epp:open(File, [], PreDefMacros)
+ end(),
+
+ Ts = [
+ {macro_1,
+ <<"-define(m(A), A).\n"
+ "t() -> ?m(,).\n">>,
+ {errors,[{{2,11},epp,{arg_error,m}}],[]}},
+ {macro_2,
+ <<"-define(m(A), A).\n"
+ "t() -> ?m(a,).\n">>,
+ {errors,[{{2,12},epp,{arg_error,m}}],[]}},
+ {macro_3,
+ <<"-define(LINE, a).\n">>,
+ {errors,[{{1,9},epp,{redefine_predef,'LINE'}}],[]}},
+ {macro_4,
+ <<"-define(A(B, C, D), {B,C,D}).\n"
+ "t() -> ?A(a,,3).\n">>,
+ {errors,[{{2,8},epp,{mismatch,'A'}}],[]}},
+ {macro_5,
+ <<"-define(Q, {?F0(), ?F1(,,4)}).\n">>,
+ {errors,[{{1,24},epp,{arg_error,'F1'}}],[]}}
+ ],
+ ?line [] = compile(Config, Ts),
+ ok.
+
check(Config, Tests) ->
eval_tests(Config, fun check_test/2, Tests).
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 6016bc9bdc..13c87ca005 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(ets_SUITE).
@@ -4530,10 +4530,16 @@ meta_wb(Config) when is_list(Config) ->
meta_wb_do(Opts) ->
%% Do random new/delete/rename of colliding named tables
- Names = [pioneer | colliding_names(pioneer)],
+ Names0 = [pioneer | colliding_names(pioneer)],
+
+ %% Remove any names that happen to exist as tables already
+ Names = lists:filter(fun(Name) -> ets:info(Name) == undefined end,
+ Names0),
Len = length(Names),
OpFuns = {fun meta_wb_new/4, fun meta_wb_delete/4, fun meta_wb_rename/4},
+ ?line true = (Len >= 3),
+
io:format("Colliding names = ~p\n",[Names]),
F = fun(0,_,_) -> ok;
(N,Tabs,Me) -> Name1 = lists:nth(random:uniform(Len),Names),
diff --git a/lib/stdlib/test/ets_tough_SUITE.erl b/lib/stdlib/test/ets_tough_SUITE.erl
index e3d44d00b9..4c8d941f13 100644
--- a/lib/stdlib/test/ets_tough_SUITE.erl
+++ b/lib/stdlib/test/ets_tough_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(ets_tough_SUITE).
@@ -40,7 +40,7 @@ fin_per_testcase(_Func, Config) ->
ets:delete(?GLOBAL_PARAMS).
-ex1(Config) when list(Config) ->
+ex1(Config) when is_list(Config) ->
?line ets:new(?GLOBAL_PARAMS,[named_table,public]),
?line ets:insert(?GLOBAL_PARAMS,{a,set}),
?line ets:insert(?GLOBAL_PARAMS,{b,set}),
@@ -269,7 +269,7 @@ show_entries(Fd) ->
start(DbName) ->
case gen_server:start_link(ets_tough_SUITE,{DbName,no_dump_dir},[]) of
- {ok,Pid} when pid(Pid) ->
+ {ok,Pid} when is_pid(Pid) ->
{ok, Pid};
Other ->
Other
@@ -283,7 +283,7 @@ start(DbName) ->
start(DbName,DumpDir) ->
case gen_server:start_link(ets_tough_SUITE,
{DbName,{dump_dir,DumpDir}},[]) of
- {ok,Pid} when pid(Pid) ->
+ {ok,Pid} when is_pid(Pid) ->
{ok, Pid};
Other ->
Other
@@ -1075,7 +1075,7 @@ phys_read_len(Fd) ->
phys_read_entry(Fd,Len) ->
case io:get_chars(Fd,'',Len) of
- L when list(L), length(L) == Len ->
+ L when is_list(L), length(L) == Len ->
{ok,binary_to_term(list_to_binary(L))};
Other ->
{error,{read_term,Other}}
diff --git a/lib/stdlib/test/expand_test.erl b/lib/stdlib/test/expand_test.erl
new file mode 100644
index 0000000000..63e4bc3aa0
--- /dev/null
+++ b/lib/stdlib/test/expand_test.erl
@@ -0,0 +1,32 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(expand_test).
+
+-export([a_fun_name/1,
+ a_less_fun_name/1,
+ b_comes_after_a/1]).
+
+a_fun_name(X) ->
+ X.
+
+a_less_fun_name(X) ->
+ X.
+
+b_comes_after_a(X) ->
+ X.
diff --git a/lib/stdlib/test/expand_test1.erl b/lib/stdlib/test/expand_test1.erl
new file mode 100644
index 0000000000..11b6fec0f3
--- /dev/null
+++ b/lib/stdlib/test/expand_test1.erl
@@ -0,0 +1,44 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(expand_test1).
+
+-export([a_fun_name/1,
+ a_less_fun_name/1,
+ b_comes_after_a/1,
+ 'Quoted_fun_name'/0,
+ 'Quoted_fun_too'/0,
+ '#weird-fun-name'/0]).
+
+a_fun_name(X) ->
+ X.
+
+a_less_fun_name(X) ->
+ X.
+
+b_comes_after_a(X) ->
+ X.
+
+'Quoted_fun_name'() ->
+ whoopee.
+
+'Quoted_fun_too'() ->
+ too.
+
+'#weird-fun-name'() ->
+ weird.
diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl
index c9c6054f7b..d54741051f 100644
--- a/lib/stdlib/test/filelib_SUITE.erl
+++ b/lib/stdlib/test/filelib_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -21,7 +21,7 @@
-export([all/1,init_per_testcase/2,fin_per_testcase/2,
wildcard_one/1,wildcard_two/1,wildcard_errors/1,
- fold_files/1,otp_5960/1]).
+ fold_files/1,otp_5960/1,ensure_dir_eexist/1]).
-import(lists, [foreach/2]).
@@ -38,7 +38,8 @@ fin_per_testcase(_Case, Config) ->
ok.
all(suite) ->
- [wildcard_one,wildcard_two,wildcard_errors,fold_files,otp_5960].
+ [wildcard_one,wildcard_two,wildcard_errors,fold_files,otp_5960,
+ ensure_dir_eexist].
wildcard_one(Config) when is_list(Config) ->
?line {ok,OldCwd} = file:get_cwd(),
@@ -223,7 +224,9 @@ otp_5960(Config) when is_list(Config) ->
?line Name1 = filename:join(Dir, name1),
?line Name2 = filename:join(Dir, name2),
?line ok = filelib:ensure_dir(Name1), % parent is created
+ ?line ok = filelib:ensure_dir(Name1), % repeating it should be OK
?line ok = filelib:ensure_dir(Name2), % parent already exists
+ ?line ok = filelib:ensure_dir(Name2), % repeating it should be OK
?line Name3 = filename:join(Name1, name3),
?line {ok, FileInfo} = file:read_file_info(Dir),
case os:type() of
@@ -239,3 +242,16 @@ otp_5960(Config) when is_list(Config) ->
?line ok = file:write_file_info(Dir, #file_info{mode=Mode}),
ok
end.
+
+ensure_dir_eexist(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Dir = filename:join(PrivDir, ensure_dir_eexist),
+ ?line Name = filename:join(Dir, "same_name_as_file_and_dir"),
+ ?line ok = filelib:ensure_dir(Name),
+ ?line ok = file:write_file(Name, <<"some string\n">>),
+
+ %% There already is a file with the name of the directory
+ %% we want to create.
+ ?line NeedFile = filename:join(Name, "file"),
+ ?line {error, eexist} = filelib:ensure_dir(NeedFile),
+ ok.
diff --git a/lib/stdlib/test/fixtable_SUITE.erl b/lib/stdlib/test/fixtable_SUITE.erl
index 9f21308ad4..1940ee147e 100644
--- a/lib/stdlib/test/fixtable_SUITE.erl
+++ b/lib/stdlib/test/fixtable_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%%----------------------------------------------------------------------
@@ -83,7 +83,7 @@ fixbag(doc) ->
"incorrect lookups"];
fixbag(suite) ->
[];
-fixbag(Config) when list(Config) ->
+fixbag(Config) when is_list(Config) ->
?line T = ets:new(x,[bag]),
?line ets:insert(T,{a,1}),
?line ets:insert(T,{a,2}),
@@ -101,7 +101,7 @@ insert_same_key(doc) ->
["Check correct behaviour if a key is deleted and reinserted during fixation."];
insert_same_key(suite) ->
[];
-insert_same_key(Config) when list(Config) ->
+insert_same_key(Config) when is_list(Config) ->
?line {ok,Dets1} = dets:open_file(?DETS_TMP1,
[{file, dets_filename(?DETS_TMP1,Config)}]),
?line Ets1 = ets:new(ets,[]),
@@ -180,7 +180,7 @@ owner_dies(doc) ->
["Check correct behaviour if the table owner dies."];
owner_dies(suite) ->
[];
-owner_dies(Config) when list(Config) ->
+owner_dies(Config) when is_list(Config) ->
?line P1 = start_commander(),
?line Ets1 = command(P1,{ets,new,[ets,[]]}),
?line command(P1,{ets,safe_fixtable,[Ets1,true]}),
@@ -236,7 +236,7 @@ other_process_closes(doc) ->
other_process_closes(suite) ->
[];
-other_process_closes(Config) when list(Config) ->
+other_process_closes(Config) when is_list(Config) ->
?line {ok,Dets} = dets:open_file(?DETS_TMP1,
[{file, dets_filename(tmp1,Config)}]),
?line P2 = start_commander(),
@@ -265,7 +265,7 @@ other_process_deletes(doc) ->
"deletes an ets table"];
other_process_deletes(suite) ->
[];
-other_process_deletes(Config) when list(Config) ->
+other_process_deletes(Config) when is_list(Config) ->
?line Ets = ets:new(ets,[public]),
?line P = start_commander(),
?line ets:safe_fixtable(Ets,true),
@@ -282,7 +282,7 @@ multiple_fixes(doc) ->
["Check that multiple safe_fixtable keeps the reference counter."];
multiple_fixes(suite) ->
[];
-multiple_fixes(Config) when list(Config) ->
+multiple_fixes(Config) when is_list(Config) ->
?line {ok,Dets} = dets:open_file(?DETS_TMP1,
[{file, dets_filename(?DETS_TMP1,Config)}]),
?line Ets = ets:new(ets,[]),
@@ -317,7 +317,7 @@ multiple_processes(doc) ->
"counted OK"];
multiple_processes(suite) ->
[];
-multiple_processes(Config) when list(Config) ->
+multiple_processes(Config) when is_list(Config) ->
?line {ok,Dets} = dets:open_file(?DETS_TMP1,[{file,
dets_filename(?DETS_TMP1,
Config)}]),
@@ -370,7 +370,7 @@ multiple_processes(Tab, Mod) ->
%%% Helpers
-dets_filename(Base, Config) when atom(Base) ->
+dets_filename(Base, Config) when is_atom(Base) ->
dets_filename(atom_to_list(Base) ++ ".dat", Config);
dets_filename(Basename, Config) ->
PrivDir = ?config(priv_dir,Config),
diff --git a/lib/stdlib/test/format_SUITE.erl b/lib/stdlib/test/format_SUITE.erl
index 2c415894f4..1c9e953003 100644
--- a/lib/stdlib/test/format_SUITE.erl
+++ b/lib/stdlib/test/format_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(format_SUITE).
@@ -45,7 +45,7 @@ hang_1(doc) ->
["Bad args can hang (OTP-2400)"];
hang_1(suite) ->
[];
-hang_1(Config) when list(Config) ->
+hang_1(Config) when is_list(Config) ->
?line _ = (catch io:format(a, "", [])),
?line _ = (catch io:format({}, "", [])),
ok.
diff --git a/lib/stdlib/test/gen_event_SUITE.erl b/lib/stdlib/test/gen_event_SUITE.erl
index dc5ddebf53..8cbffaca56 100644
--- a/lib/stdlib/test/gen_event_SUITE.erl
+++ b/lib/stdlib/test/gen_event_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(gen_event_SUITE).
@@ -33,7 +33,7 @@ all(suite) -> {req, [stdlib], [start, test_all, hibernate]}.
start(doc) -> [];
start(suite) -> [];
-start(Config) when list(Config) ->
+start(Config) when is_list(Config) ->
OldFl = process_flag(trap_exit, true),
?line {ok, Pid0} = gen_event:start(), %anonymous
@@ -175,7 +175,7 @@ test_all(suite) -> [add_handler, add_sup_handler, delete_handler,
add_handler(doc) -> [];
add_handler(suite) -> [];
-add_handler(Config) when list(Config) ->
+add_handler(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line {error, my_error} =
gen_event:add_handler(my_dummy_handler, dummy_h, make_error),
@@ -196,7 +196,7 @@ add_handler(Config) when list(Config) ->
add_sup_handler(doc) -> [];
add_sup_handler(suite) -> [];
-add_sup_handler(Config) when list(Config) ->
+add_sup_handler(Config) when is_list(Config) ->
?line {ok,Pid} = gen_event:start({local, my_dummy_handler}),
?line {error, my_error} =
gen_event:add_sup_handler(my_dummy_handler, dummy_h, make_error),
@@ -238,7 +238,7 @@ add_sup_handler(Config) when list(Config) ->
delete_handler(doc) -> [];
delete_handler(suite) -> [];
-delete_handler(Config) when list(Config) ->
+delete_handler(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
?line {error, module_not_found} =
@@ -270,7 +270,7 @@ delete_handler(Config) when list(Config) ->
swap_handler(doc) -> [];
swap_handler(suite) -> [];
-swap_handler(Config) when list(Config) ->
+swap_handler(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
?line {error, non_existing} =
@@ -299,7 +299,7 @@ swap_handler(Config) when list(Config) ->
swap_sup_handler(doc) -> [];
swap_sup_handler(suite) -> [];
-swap_sup_handler(Config) when list(Config) ->
+swap_sup_handler(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_sup_handler(my_dummy_handler, dummy_h, [self()]),
?line {error, non_existing} =
@@ -341,7 +341,7 @@ swap_sup_handler(Config) when list(Config) ->
notify(doc) -> [];
notify(suite) -> [];
-notify(Config) when list(Config) ->
+notify(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
Event = {event, self()},
@@ -457,7 +457,7 @@ notify(Config) when list(Config) ->
sync_notify(doc) -> [];
sync_notify(suite) -> [];
-sync_notify(Config) when list(Config) ->
+sync_notify(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
Event = {event, self()},
@@ -576,7 +576,7 @@ sync_notify(Config) when list(Config) ->
call(doc) -> [];
call(suite) -> [];
-call(Config) when list(Config) ->
+call(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
?line ok = gen_event:add_handler(my_dummy_handler, {dummy_h, 1}, [self()]),
@@ -718,7 +718,7 @@ flush() ->
info(doc) -> [];
info(suite) -> [];
-info(Config) when list(Config) ->
+info(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
Info = {info, self()},
diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl
index 46407193d7..59aa175c73 100644
--- a/lib/stdlib/test/io_proto_SUITE.erl
+++ b/lib/stdlib/test/io_proto_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(io_proto_SUITE).
@@ -48,9 +48,12 @@
-ifdef(debug).
-define(format(S, A), io:format(S, A)).
-define(dbg(Data),io:format(standard_error, "DBG: ~p\r\n",[Data])).
+-define(RM_RF(Dir),begin io:format(standard_error, "Not Removed: ~p\r\n",[Dir]),
+ ok end).
-else.
-define(format(S, A), ok).
-define(dbg(Data),noop).
+-define(RM_RF(Dir),rm_rf(Dir)).
-endif.
@@ -197,6 +200,15 @@ setopts_getopts(Config) when is_list(Config) ->
{getline_re, ".*<<\"hej\\\\n\">>"}
],[],[],"-oldshell"),
ok.
+
+
+get_lc_ctype() ->
+ case {os:type(),os:version()} of
+ {{unix,sunos},{5,N,_}} when N =< 8 ->
+ "iso_8859_1";
+ _ ->
+ "ISO-8859-1"
+ end.
unicode_options(suite) ->
[];
@@ -369,7 +381,7 @@ unicode_options(Config) when is_list(Config) ->
{getline,
binary_to_list(unicode:characters_to_binary(
[1024],unicode,utf8))}
- ],[],"LC_CTYPE=\"ISO-8859-1\"; export LC_CTYPE; "),
+ ],[],"LC_CTYPE=\""++get_lc_ctype()++"\"; export LC_CTYPE; "),
?line rtnode([{putline,""},
{putline, "2."},
{getline_re, ".*2."},
@@ -384,7 +396,7 @@ unicode_options(Config) when is_list(Config) ->
{getline_re,
".*"++binary_to_list(unicode:characters_to_binary(
[1024],unicode,utf8))}
- ],[],"LC_CTYPE=\"ISO-8859-1\"; export LC_CTYPE; ",
+ ],[],"LC_CTYPE=\""++get_lc_ctype()++"\"; export LC_CTYPE; ",
" -oldshell "),
ok.
@@ -974,7 +986,7 @@ answering_machine1(OthNode,OthReg,Me) ->
{putline, TestDataUtf},
{getline_re, ".*Okej"}
- ],Me,"LC_CTYPE=\"ISO-8859-1\"; export LC_CTYPE; "),
+ ],Me,"LC_CTYPE=\""++get_lc_ctype()++"\"; export LC_CTYPE; "),
O = list_to_atom(OthReg),
O ! {self(),done},
ok.
@@ -1045,7 +1057,7 @@ answering_machine2(OthNode,OthReg,Me) ->
{putline, TestDataUtf},
{getline_re, ".*Okej"}
- ],Me,"LC_CTYPE=\"ISO-8859-1\"; export LC_CTYPE; "," -oldshell "),
+ ],Me,"LC_CTYPE=\""++get_lc_ctype()++"\"; export LC_CTYPE; "," -oldshell "),
O = list_to_atom(OthReg),
O ! {self(),done},
ok.
@@ -1087,7 +1099,9 @@ read_modes_gl_1(_Config,Machine) ->
[MyNodeList, "io_proto_suite", N2List]),
?line GL = receive X when is_pid(X) -> X end,
+ ?dbg({group_leader,X}),
%% get_line
+ ?line receive after 500 -> ok end, % Dont clash with the new shell...
?line "Hej\n" = io:get_line(GL,"Prompt\n"),
?line io:setopts(GL,[binary]),
?line io:format(GL,"Okej~n",[]),
@@ -1287,7 +1301,7 @@ rtnode(Commands,Nodename,ErlPrefix,Extra) ->
?line ok
end,
?line wait_for_runerl_server(SPid),
- ?line ok = rm_rf(Tempdir),
+ ?line ok = ?RM_RF(Tempdir),
?line ok = Res
end
end.
@@ -1308,7 +1322,7 @@ timeout(normal) ->
%% stop_noshell_node(Node) ->
%% test_server:stop_node(Node).
-
+-ifndef(debug).
rm_rf(Dir) ->
try
{ok,List} = file:list_dir(Dir),
@@ -1324,7 +1338,7 @@ rm_rf(Dir) ->
catch
_:Exception -> {error, {Exception,Dir}}
end.
-
+-endif.
get_and_put(_CPid,[],_) ->
ok;
@@ -1527,6 +1541,8 @@ start_runerl_node(RunErl,Erl,Tempdir,Nodename,Extra) ->
" "++Extra
end,
spawn(fun() ->
+ ?dbg(RunErl++" "++Tempdir++"/ "++Tempdir++" \""++
+ Erl++XArg++XXArg++"\""),
os:cmd(RunErl++" "++Tempdir++"/ "++Tempdir++" \""++
Erl++XArg++XXArg++"\"")
end).
diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl
index cf0926b7fa..79a0a9af89 100644
--- a/lib/stdlib/test/ms_transform_SUITE.erl
+++ b/lib/stdlib/test/ms_transform_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(ms_transform_SUITE).
@@ -56,7 +56,7 @@ andalso_orelse(suite) ->
[];
andalso_orelse(doc) ->
["Tests that andalso and orelse are allowed in guards."];
-andalso_orelse(Config) when list(Config) ->
+andalso_orelse(Config) when is_list(Config) ->
?line setup(Config),
?line [{{'$1','$2'},
[{'and',{is_integer,'$1'},{'>',{'+','$1',5},'$2'}}],
@@ -93,7 +93,7 @@ bitsyntax(suite) ->
[];
bitsyntax(doc) ->
["Tests that bitsyntax works and does not work where appropriate"];
-bitsyntax(Config) when list(Config) ->
+bitsyntax(Config) when is_list(Config) ->
?line setup(Config),
?line [{'_',[],
[<<0,27,0,27>>]}] =
@@ -131,7 +131,7 @@ record_defaults(suite) ->
[];
record_defaults(doc) ->
["Tests that record defaults works"];
-record_defaults(Config) when list(Config) ->
+record_defaults(Config) when is_list(Config) ->
?line setup(Config),
?line [{{<<27>>,{a,5,'$1',hej,hej}},
[],
@@ -146,7 +146,7 @@ basic_ets(suite) ->
[];
basic_ets(doc) ->
["Tests basic ets:fun2ms"];
-basic_ets(Config) when list(Config) ->
+basic_ets(Config) when is_list(Config) ->
?line setup(Config),
?line [{{a,b},[],[true]}] = compile_and_run(
<<"ets:fun2ms(fun({a,b}) -> true end)">>),
@@ -167,7 +167,7 @@ basic_dbg(suite) ->
[];
basic_dbg(doc) ->
["Tests basic ets:fun2ms"];
-basic_dbg(Config) when list(Config) ->
+basic_dbg(Config) when is_list(Config) ->
?line setup(Config),
?line [{[a,b],[],[{message,banan},{return_trace}]}] =
compile_and_run(<<"dbg:fun2ms(fun([a,b]) -> message(banan), ",
@@ -186,7 +186,7 @@ from_shell(suite) ->
[];
from_shell(doc) ->
["Test calling of ets/dbg:fun2ms from the shell"];
-from_shell(Config) when list(Config) ->
+from_shell(Config) when is_list(Config) ->
?line setup(Config),
?line Fun = do_eval("fun({a,b}) -> true end"),
?line [{{a,b},[],[true]}] = apply(ets,fun2ms,[Fun]),
@@ -203,7 +203,7 @@ records(suite) ->
[];
records(doc) ->
["Tests expansion of records in fun2ms"];
-records(Config) when list(Config) ->
+records(Config) when is_list(Config) ->
?line setup(Config),
?line RD = <<"-record(t, {"
"t1 = [],"
@@ -253,7 +253,7 @@ record_index(suite) ->
[];
record_index(doc) ->
["Tests expansion of records in fun2ms, part 2"];
-record_index(Config) when list(Config) ->
+record_index(Config) when is_list(Config) ->
?line setup(Config),
?line RD = <<"-record(a,{a,b}).">>,
?line [{{2},[],[true]}] = compile_and_run(RD,
@@ -268,7 +268,7 @@ top_match(suite) ->
[];
top_match(doc) ->
["Tests matching on top level in head to give alias for object()"];
-top_match(Config) when list(Config) ->
+top_match(Config) when is_list(Config) ->
?line setup(Config),
?line RD = <<"-record(a,{a,b}).">>,
?line [{{a,3,'_'},[],['$_']}] =
@@ -295,7 +295,7 @@ multipass(suite) ->
[];
multipass(doc) ->
["Tests that multi-defined fields in records give errors."];
-multipass(Config) when list(Config) ->
+multipass(Config) when is_list(Config) ->
?line setup(Config),
?line RD = <<"-record(a,{a,b}).">>,
?line expect_failure(RD,<<"ets:fun2ms(fun(A) -> #a{a=2,a=3} end)">>),
@@ -319,7 +319,7 @@ old_guards(suite) ->
[];
old_guards(doc) ->
["Tests that old type tests in guards are translated"];
-old_guards(Config) when list(Config) ->
+old_guards(Config) when is_list(Config) ->
?line setup(Config),
Tests = [
{atom,is_atom},
@@ -382,7 +382,7 @@ autoimported(suite) ->
autoimported(doc) ->
["Tests use of autoimported bif's used like erlang:'+'(A,B) in guards"
" and body."];
-autoimported(Config) when list(Config) ->
+autoimported(Config) when is_list(Config) ->
?line setup(Config),
Allowed = [
{abs,1},
@@ -582,7 +582,7 @@ float_1_function(suite) ->
[];
float_1_function(doc) ->
["OTP-5297. The function float/1."];
-float_1_function(Config) when list(Config) ->
+float_1_function(Config) when is_list(Config) ->
?line setup(Config),
RunMS = fun(L, MS) ->
ets:match_spec_run(L, ets:match_spec_compile(MS))
diff --git a/lib/stdlib/test/queue_SUITE.erl b/lib/stdlib/test/queue_SUITE.erl
index ec3080baa0..2cd6b52311 100644
--- a/lib/stdlib/test/queue_SUITE.erl
+++ b/lib/stdlib/test/queue_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(queue_SUITE).
@@ -45,7 +45,7 @@ do(doc) ->
[""];
do(suite) ->
[];
-do(Config) when list(Config) ->
+do(Config) when is_list(Config) ->
?line L = [{in, 1},
{in, 2},
{out, {value, 1}},
@@ -66,7 +66,7 @@ to_list(doc) ->
["OTP-2701"];
to_list(suite) ->
[];
-to_list(Config) when list(Config) ->
+to_list(Config) when is_list(Config) ->
?line E = queue:new(),
?line Q = do_queue(E, [{in, 1},
{in, 2},
@@ -104,7 +104,7 @@ io_test(doc) ->
"Test input and output";
io_test(suite) ->
[];
-io_test(Config) when list(Config) ->
+io_test(Config) when is_list(Config) ->
E = queue:new(),
do_io_test(E),
ok.
@@ -284,7 +284,7 @@ op_test(doc) ->
"Test operations on whole queues";
op_test(suite) ->
[];
-op_test(Config) when list(Config) ->
+op_test(Config) when is_list(Config) ->
do_op_test(fun id/1),
ok.
@@ -382,7 +382,7 @@ error(doc) ->
"Test queue errors";
error(suite) ->
[];
-error(Config) when list(Config) ->
+error(Config) when is_list(Config) ->
do_error(fun id/1, illegal_queue),
do_error(fun id/1, {[],illegal_queue}),
do_error(fun id/1, {illegal_queue,[17]}),
@@ -449,7 +449,7 @@ oops(doc) ->
"Test queue errors";
oops(suite) ->
[];
-oops(Config) when list(Config) ->
+oops(Config) when is_list(Config) ->
?line N = 3142,
?line Optab = optab(),
?line Seed0 = random:seed0(),
diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl
index 98eb66d1fb..fa50ba3b7a 100644
--- a/lib/stdlib/test/re_SUITE.erl
+++ b/lib/stdlib/test/re_SUITE.erl
@@ -1,29 +1,29 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(re_SUITE).
--export([all/1, pcre/1,compile_options/1,run_options/1,combined_options/1,replace_autogen/1,global_capture/1,replace_return/1,split_autogen/1,split_options/1,split_specials/1,error_handling/1]).
+-export([all/1, pcre/1,compile_options/1,run_options/1,combined_options/1,replace_autogen/1,global_capture/1,replace_input_types/1,replace_return/1,split_autogen/1,split_options/1,split_specials/1,error_handling/1]).
-include("test_server.hrl").
-include_lib("kernel/include/file.hrl").
-all(suite) -> [pcre,compile_options,run_options,combined_options,replace_autogen,global_capture,replace_return,split_autogen,split_options,split_specials,error_handling].
+all(suite) -> [pcre,compile_options,run_options,combined_options,replace_autogen,global_capture,replace_input_types,replace_return,split_autogen,split_options,split_specials,error_handling].
pcre(doc) ->
["Run all applicable tests from the PCRE testsuites."];
@@ -268,7 +268,17 @@ global_capture(Config) when is_list(Config) ->
?line {match,[[{3,5},{5,3}],[{11,4},{12,3}]]} = re:run("ABC�bcdABCabcdA",".(?<FOO>bcd)",[global,{capture,all,index},unicode]),
?t:timetrap_cancel(Dog),
ok.
-
+
+replace_input_types(doc) ->
+ ["Tests replace with different input types"];
+replace_input_types(Config) when is_list(Config) ->
+ Dog = ?t:timetrap(?t:minutes(3)),
+ ?line <<"abcd">> = re:replace("abcd","Z","X",[{return,binary},unicode]),
+ ?line <<"abcd">> = re:replace("abcd","\x{400}","X",[{return,binary},unicode]),
+ ?line <<"a",208,128,"cd">> = re:replace(<<"abcd">>,"b","\x{400}",[{return,binary},unicode]),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
replace_return(doc) ->
["Tests return options of replace together with global searching"];
replace_return(Config) when is_list(Config) ->
@@ -289,6 +299,10 @@ replace_return(Config) when is_list(Config) ->
?line <<"iXk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\9X",[{return,binary}]),
?line <<"jXk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\10X",[{return,binary}]),
?line <<"Xk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\11X",[{return,binary}]),
+ ?line "a\x{400}bcX" = re:replace("a\x{400}bcd","d","X",[global,{return,list},unicode]),
+ ?line <<"a",208,128,"bcX">> = re:replace("a\x{400}bcd","d","X",[global,{return,binary},unicode]),
+ ?line "a\x{400}bcd" = re:replace("a\x{400}bcd","Z","X",[global,{return,list},unicode]),
+ ?line <<"a",208,128,"bcd">> = re:replace("a\x{400}bcd","Z","X",[global,{return,binary},unicode]),
?t:timetrap_cancel(Dog),
ok.
diff --git a/lib/stdlib/test/re_SUITE_data/mod_testoutput8 b/lib/stdlib/test/re_SUITE_data/mod_testoutput8
new file mode 100644
index 0000000000..b7e7b02d6c
--- /dev/null
+++ b/lib/stdlib/test/re_SUITE_data/mod_testoutput8
@@ -0,0 +1,877 @@
+/-- Do not use the \x{} construct except with patterns that have the --/
+/-- /8 option set, because PCRE doesn't recognize them as UTF-8 unless --/
+No match
+/-- that option is set. However, the latest Perls recognize them always. --/
+No match
+
+\x{100}ab/8
+ \x{100}ab
+ 0: \x{100}ab
+
+/a\x{100}*b/8
+ ab
+ 0: ab
+ a\x{100}b
+ 0: a\x{100}b
+ a\x{100}\x{100}b
+ 0: a\x{100}\x{100}b
+
+/a\x{100}+b/8
+ a\x{100}b
+ 0: a\x{100}b
+ a\x{100}\x{100}b
+ 0: a\x{100}\x{100}b
+ *** Failers
+No match
+ ab
+No match
+
+/\bX/8
+ Xoanon
+ 0: X
+ +Xoanon
+ 0: X
+ \x{300}Xoanon
+ 0: X
+ *** Failers
+No match
+ YXoanon
+No match
+
+/\BX/8
+ YXoanon
+ 0: X
+ *** Failers
+No match
+ Xoanon
+No match
+ +Xoanon
+No match
+ \x{300}Xoanon
+No match
+
+/X\b/8
+ X+oanon
+ 0: X
+ ZX\x{300}oanon
+ 0: X
+ FAX
+ 0: X
+ *** Failers
+No match
+ Xoanon
+No match
+
+/X\B/8
+ Xoanon
+ 0: X
+ *** Failers
+No match
+ X+oanon
+No match
+ ZX\x{300}oanon
+No match
+ FAX
+No match
+
+/[^a]/8
+ abcd
+ 0: b
+ a\x{100}
+ 0: \x{100}
+
+/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8
+ ab99
+ 0: ab9
+ \x{123}\x{123}45
+ 0: \x{123}\x{123}4
+ \x{400}\x{401}\x{402}6
+ 0: \x{400}\x{401}\x{402}6
+ *** Failers
+No match
+ d99
+No match
+ \x{123}\x{122}4
+No match
+ \x{400}\x{403}6
+No match
+ \x{400}\x{401}\x{402}\x{402}6
+No match
+
+/abc/8
+ �]
+Error -10
+ �
+Error -10
+ ���
+Error -10
+ ���\?
+No match
+
+/a.b/8
+ acb
+ 0: acb
+ a\x7fb
+ 0: a\x{7f}b
+ a\x{100}b
+ 0: a\x{100}b
+ *** Failers
+No match
+ a\nb
+No match
+
+/^[a\x{c0}]/8
+ *** Failers
+No match
+ \x{100}
+No match
+
+/(?<=aXb)cd/8
+ aXbcd
+ 0: cd
+
+/(?<=a\x{100}b)cd/8
+ a\x{100}bcd
+ 0: cd
+
+/(?<=a\x{100000}b)cd/8
+ a\x{100000}bcd
+ 0: cd
+
+/(?:\x{100}){3}b/8
+ \x{100}\x{100}\x{100}b
+ 0: \x{100}\x{100}\x{100}b
+ *** Failers
+No match
+ \x{100}\x{100}b
+No match
+
+/\x{ab}/8
+ \x{ab}
+ 0: \x{ab}
+ \xc2\xab
+ 0: \x{ab}
+ *** Failers
+No match
+ \x00{ab}
+No match
+
+/^[^a]{2}/8
+ \x{100}bc
+ 0: \x{100}b
+
+/^[^a]{2,}/8
+ \x{100}bcAa
+ 0: \x{100}bcA
+
+/^[^a]{2,}?/8
+ \x{100}bca
+ 0: \x{100}b
+
+/^[^a]{2}/8i
+ \x{100}bc
+ 0: \x{100}b
+
+/^[^a]{2,}/8i
+ \x{100}bcAa
+ 0: \x{100}bc
+
+/^[^a]{2,}?/8iU
+ \x{100}bca
+ 0: \x{100}bc
+
+/\x{100}{0,0}/8
+ abcd
+ 0:
+
+/\x{100}?/8
+ abcd
+ 0:
+ \x{100}\x{100}
+ 0: \x{100}
+
+/\x{100}{0,3}/8
+ \x{100}\x{100}
+ 0: \x{100}\x{100}
+ \x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}
+
+/\x{100}*/8
+ abce
+ 0:
+ \x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}\x{100}
+
+/\x{100}{1,1}/8
+ abcd\x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}
+
+/\x{100}{1,3}/8
+ abcd\x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}
+
+/\x{100}+/8
+ abcd\x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}\x{100}
+
+/\x{100}{3}/8
+ abcd\x{100}\x{100}\x{100}XX
+ 0: \x{100}\x{100}\x{100}
+
+/\x{100}{3,5}/8
+ abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX
+ 0: \x{100}\x{100}\x{100}\x{100}\x{100}
+
+/\x{100}{3,}/8
+ abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX
+ 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
+
+/(?<=a\x{100}{2}b)X/8
+ Xyyya\x{100}\x{100}bXzzz
+ 0: X
+
+/\D*/8
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+/\D*/8
+ \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
+
+/\D/8
+ 1X2
+ 0: X
+ 1\x{100}2
+ 0: \x{100}
+
+/>\S/8
+ > >X Y
+ 0: >X
+ > >\x{100} Y
+ 0: >\x{100}
+
+/\d/8
+ \x{100}3
+ 0: 3
+
+/\s/8
+ \x{100} X
+ 0:
+
+/\D+/8
+ 12abcd34
+ 0: abcd
+ *** Failers
+ 0: *** Failers
+ 1234
+No match
+
+/\d+/8
+ 12abcd34
+ 0: 12
+ *** Failers
+No match
+
+/\d{2,3}/8
+ 12abcd34
+ 0: 12
+ 1234abcd
+ 0: 123
+ *** Failers
+No match
+ 1.4
+No match
+
+/\S+/8
+ 12abcd34
+ 0: 12abcd34
+ *** Failers
+ 0: ***
+ \ \
+No match
+
+/>\s+</8
+ 12> <34
+ 0: > <
+ *** Failers
+No match
+
+/>\s{2,3}</8
+ ab> <cd
+ 0: > <
+ ab> <ce
+ 0: > <
+ *** Failers
+No match
+ ab> <cd
+No match
+
+/>\s{2,3}?</8
+ ab> <cd
+ 0: > <
+ ab> <ce
+ 0: > <
+ *** Failers
+No match
+ ab> <cd
+No match
+
+/\w+/8
+ 12 34
+ 0: 12
+ *** Failers
+ 0: Failers
+ +++=*!
+No match
+
+/\w{2,3}/8
+ ab cd
+ 0: ab
+ abcd ce
+ 0: abc
+ *** Failers
+ 0: Fai
+ a.b.c
+No match
+
+/\W+/8
+ 12====34
+ 0: ====
+ *** Failers
+ 0: ***
+ abcd
+No match
+
+/\W{2,3}/8
+ ab====cd
+ 0: ===
+ ab==cd
+ 0: ==
+ *** Failers
+ 0: ***
+ a.b.c
+No match
+
+/\W{2,3}?/8U
+ ab====cd
+ 0: ===
+ ab==cd
+ 0: ==
+ *** Failers
+ 0: ***
+ a.b.c
+No match
+
+/[\x{100}]/8
+ \x{100}
+ 0: \x{100}
+ Z\x{100}
+ 0: \x{100}
+ \x{100}Z
+ 0: \x{100}
+ *** Failers
+No match
+
+/[Z\x{100}]/8
+ Z\x{100}
+ 0: Z
+ \x{100}
+ 0: \x{100}
+ \x{100}Z
+ 0: \x{100}
+ *** Failers
+No match
+
+/[\x{100}\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ *** Failers
+No match
+
+/[\x{100}-\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{111}cd
+ 0: \x{111}
+ *** Failers
+No match
+
+/[z-\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{111}cd
+ 0: \x{111}
+ abzcd
+ 0: z
+ ab|cd
+ 0: |
+ *** Failers
+No match
+
+/[Q\x{100}\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ Q?
+ 0: Q
+ *** Failers
+No match
+
+/[Q\x{100}-\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{111}cd
+ 0: \x{111}
+ Q?
+ 0: Q
+ *** Failers
+No match
+
+/[Qz-\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{111}cd
+ 0: \x{111}
+ abzcd
+ 0: z
+ ab|cd
+ 0: |
+ Q?
+ 0: Q
+ *** Failers
+No match
+
+/[\x{100}\x{200}]{1,3}/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{200}\x{100}\x{200}\x{100}cd
+ 0: \x{200}\x{100}\x{200}
+ *** Failers
+No match
+
+/[\x{100}\x{200}]{1,3}?/8U
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{200}\x{100}\x{200}\x{100}cd
+ 0: \x{200}\x{100}\x{200}
+ *** Failers
+No match
+
+/[Q\x{100}\x{200}]{1,3}/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{200}\x{100}\x{200}\x{100}cd
+ 0: \x{200}\x{100}\x{200}
+ *** Failers
+No match
+
+/[Q\x{100}\x{200}]{1,3}?/8U
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{200}\x{100}\x{200}\x{100}cd
+ 0: \x{200}\x{100}\x{200}
+ *** Failers
+No match
+
+/(?<=[\x{100}\x{200}])X/8
+ abc\x{200}X
+ 0: X
+ abc\x{100}X
+ 0: X
+ *** Failers
+No match
+ X
+No match
+
+/(?<=[Q\x{100}\x{200}])X/8
+ abc\x{200}X
+ 0: X
+ abc\x{100}X
+ 0: X
+ abQX
+ 0: X
+ *** Failers
+No match
+ X
+No match
+
+/(?<=[\x{100}\x{200}]{3})X/8
+ abc\x{100}\x{200}\x{100}X
+ 0: X
+ *** Failers
+No match
+ abc\x{200}X
+No match
+ X
+No match
+
+/[^\x{100}\x{200}]X/8
+ AX
+ 0: AX
+ \x{150}X
+ 0: \x{150}X
+ \x{500}X
+ 0: \x{500}X
+ *** Failers
+No match
+ \x{100}X
+No match
+ \x{200}X
+No match
+
+/[^Q\x{100}\x{200}]X/8
+ AX
+ 0: AX
+ \x{150}X
+ 0: \x{150}X
+ \x{500}X
+ 0: \x{500}X
+ *** Failers
+No match
+ \x{100}X
+No match
+ \x{200}X
+No match
+ QX
+No match
+
+/[^\x{100}-\x{200}]X/8
+ AX
+ 0: AX
+ \x{500}X
+ 0: \x{500}X
+ *** Failers
+No match
+ \x{100}X
+No match
+ \x{150}X
+No match
+ \x{200}X
+No match
+
+/[z-\x{100}]/8i
+ z
+ 0: z
+ Z
+ 0: Z
+ \x{100}
+ 0: \x{100}
+ *** Failers
+No match
+ \x{102}
+No match
+ y
+No match
+
+/[\xFF]/
+ >\xff<
+ 0: \xff
+
+/[\xff]/8
+ >\x{ff}<
+ 0: \x{ff}
+
+/[^\xFF]/
+ XYZ
+ 0: X
+
+/[^\xff]/8
+ XYZ
+ 0: X
+ \x{123}
+ 0: \x{123}
+
+/^[ac]*b/8
+ xb
+No match
+
+/^[ac\x{100}]*b/8
+ xb
+No match
+
+/^[^x]*b/8i
+ xb
+No match
+
+/^[^x]*b/8
+ xb
+No match
+
+/^\d*b/8
+ xb
+No match
+
+/^\x{85}$/8i
+ \x{85}
+ 0: \x{85}
+
+/^abc./mgx8<any>
+ abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK
+ 0: abc1
+ 0: abc2
+ 0: abc3
+ 0: abc4
+ 0: abc5
+ 0: abc6
+ 0: abc7
+ 0: abc8
+ 0: abc9
+
+/abc.$/mgx8<any>
+ abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9
+ 0: abc1
+ 0: abc2
+ 0: abc3
+ 0: abc4
+ 0: abc5
+ 0: abc6
+ 0: abc7
+ 0: abc8
+ 0: abc9
+
+/^a\Rb/8<bsr_unicode>
+ a\nb
+ 0: a\x{0a}b
+ a\rb
+ 0: a\x{0d}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ a\x0bb
+ 0: a\x{0b}b
+ a\x0cb
+ 0: a\x{0c}b
+ a\x{85}b
+ 0: a\x{85}b
+ a\x{2028}b
+ 0: a\x{2028}b
+ a\x{2029}b
+ 0: a\x{2029}b
+ ** Failers
+No match
+ a\n\rb
+No match
+
+/^a\R*b/8<bsr_unicode>
+ ab
+ 0: ab
+ a\nb
+ 0: a\x{0a}b
+ a\rb
+ 0: a\x{0d}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ a\x0bb
+ 0: a\x{0b}b
+ a\x0c\x{2028}\x{2029}b
+ 0: a\x{0c}\x{2028}\x{2029}b
+ a\x{85}b
+ 0: a\x{85}b
+ a\n\rb
+ 0: a\x{0a}\x{0d}b
+ a\n\r\x{85}\x0cb
+ 0: a\x{0a}\x{0d}\x{85}\x{0c}b
+
+/^a\R+b/8<bsr_unicode>
+ a\nb
+ 0: a\x{0a}b
+ a\rb
+ 0: a\x{0d}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ a\x0bb
+ 0: a\x{0b}b
+ a\x0c\x{2028}\x{2029}b
+ 0: a\x{0c}\x{2028}\x{2029}b
+ a\x{85}b
+ 0: a\x{85}b
+ a\n\rb
+ 0: a\x{0a}\x{0d}b
+ a\n\r\x{85}\x0cb
+ 0: a\x{0a}\x{0d}\x{85}\x{0c}b
+ ** Failers
+No match
+ ab
+No match
+
+/^a\R{1,3}b/8<bsr_unicode>
+ a\nb
+ 0: a\x{0a}b
+ a\n\rb
+ 0: a\x{0a}\x{0d}b
+ a\n\r\x{85}b
+ 0: a\x{0a}\x{0d}\x{85}b
+ a\r\n\r\nb
+ 0: a\x{0d}\x{0a}\x{0d}\x{0a}b
+ a\r\n\r\n\r\nb
+ 0: a\x{0d}\x{0a}\x{0d}\x{0a}\x{0d}\x{0a}b
+ a\n\r\n\rb
+ 0: a\x{0a}\x{0d}\x{0a}\x{0d}b
+ a\n\n\r\nb
+ 0: a\x{0a}\x{0a}\x{0d}\x{0a}b
+ ** Failers
+No match
+ a\n\n\n\rb
+No match
+ a\r
+No match
+
+/\h+\V?\v{3,4}/8
+ \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
+ 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d}
+
+/\V?\v{3,4}/8
+ \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
+ 0: X\x{0a}\x{0b}\x{0c}\x{0d}
+
+/\h+\V?\v{3,4}/8
+ >\x09\x20\x{a0}X\x0a\x0a\x0a<
+ 0: \x{09} \x{a0}X\x{0a}\x{0a}\x{0a}
+
+/\V?\v{3,4}/8
+ >\x09\x20\x{a0}X\x0a\x0a\x0a<
+ 0: X\x{0a}\x{0a}\x{0a}
+
+/\H\h\V\v/8
+ X X\x0a
+ 0: X X\x{0a}
+ X\x09X\x0b
+ 0: X\x{09}X\x{0b}
+ ** Failers
+No match
+ \x{a0} X\x0a
+No match
+
+/\H*\h+\V?\v{3,4}/8
+ \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
+ 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d}
+ \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a
+ 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}\x{0d}
+ \x09\x20\x{a0}\x0a\x0b\x0c
+ 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}
+ ** Failers
+No match
+ \x09\x20\x{a0}\x0a\x0b
+No match
+
+/\H\h\V\v/8
+ \x{3001}\x{3000}\x{2030}\x{2028}
+ 0: \x{3001}\x{3000}\x{2030}\x{2028}
+ X\x{180e}X\x{85}
+ 0: X\x{180e}X\x{85}
+ ** Failers
+No match
+ \x{2009} X\x0a
+No match
+
+/\H*\h+\V?\v{3,4}/8
+ \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a
+ 0: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}\x{0d}
+ \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a
+ 0: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c}\x{2028}
+ \x09\x20\x{202f}\x0a\x0b\x0c
+ 0: \x{09} \x{202f}\x{0a}\x{0b}\x{0c}
+ ** Failers
+No match
+ \x09\x{200a}\x{a0}\x{2028}\x0b
+No match
+
+/a\Rb/I8<bsr_anycrlf>
+Capturing subpattern count = 0
+Options: bsr_anycrlf utf8
+First char = 'a'
+Need char = 'b'
+ a\rb
+ 0: a\x{0d}b
+ a\nb
+ 0: a\x{0a}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ ** Failers
+No match
+ a\x{85}b
+No match
+ a\x0bb
+No match
+
+/a\Rb/I8<bsr_unicode>
+Capturing subpattern count = 0
+Options: bsr_unicode utf8
+First char = 'a'
+Need char = 'b'
+ a\rb
+ 0: a\x{0d}b
+ a\nb
+ 0: a\x{0a}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ a\x{85}b
+ 0: a\x{85}b
+ a\x0bb
+ 0: a\x{0b}b
+ ** Failers
+No match
+ a\x{85}b\<bsr_anycrlf>
+No match
+ a\x0bb\<bsr_anycrlf>
+No match
+
+/a\R?b/I8<bsr_anycrlf>
+Capturing subpattern count = 0
+Options: bsr_anycrlf utf8
+First char = 'a'
+Need char = 'b'
+ a\rb
+ 0: a\x{0d}b
+ a\nb
+ 0: a\x{0a}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ ** Failers
+No match
+ a\x{85}b
+No match
+ a\x0bb
+No match
+
+/a\R?b/I8<bsr_unicode>
+Capturing subpattern count = 0
+Options: bsr_unicode utf8
+First char = 'a'
+Need char = 'b'
+ a\rb
+ 0: a\x{0d}b
+ a\nb
+ 0: a\x{0a}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ a\x{85}b
+ 0: a\x{85}b
+ a\x0bb
+ 0: a\x{0b}b
+ ** Failers
+No match
+ a\x{85}b\<bsr_anycrlf>
+No match
+ a\x0bb\<bsr_anycrlf>
+No match
+
+/ End of testinput 8 /
diff --git a/lib/stdlib/test/re_testoutput1_replacement_test.erl b/lib/stdlib/test/re_testoutput1_replacement_test.erl
index b20db3f9c3..69cb140e0d 100644
--- a/lib/stdlib/test/re_testoutput1_replacement_test.erl
+++ b/lib/stdlib/test/re_testoutput1_replacement_test.erl
@@ -1,23 +1,24 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(re_testoutput1_replacement_test).
-compile(export_all).
+-compile(no_native).
-include("test_server.hrl").
%% This file is generated by running run_pcre_tests:gen_repl_test("re_SUITE_data/testoutput1")
run() ->
diff --git a/lib/stdlib/test/re_testoutput1_split_test.erl b/lib/stdlib/test/re_testoutput1_split_test.erl
index 7e2d3f79ec..e86a04b008 100644
--- a/lib/stdlib/test/re_testoutput1_split_test.erl
+++ b/lib/stdlib/test/re_testoutput1_split_test.erl
@@ -1,23 +1,24 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(re_testoutput1_split_test).
-compile(export_all).
+-compile(no_native).
-include("test_server.hrl").
%% This file is generated by running run_pcre_tests:gen_split_test("re_SUITE_data/testoutput1")
join([]) -> [];
diff --git a/lib/stdlib/test/run_pcre_tests.erl b/lib/stdlib/test/run_pcre_tests.erl
index 0ef3986918..78b4803fc8 100644
--- a/lib/stdlib/test/run_pcre_tests.erl
+++ b/lib/stdlib/test/run_pcre_tests.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(run_pcre_tests).
@@ -25,7 +25,7 @@ test(RootDir) ->
erts_debug:set_internal_state(available_internal_state,true),
io:format("oldlimit: ~p~n",[ erts_debug:set_internal_state(re_loop_limit,10)]),
Testfiles0 = ["testoutput1", "testoutput2", "testoutput3", "testoutput4",
- "testoutput5", "testoutput6", "testoutput10"],
+ "testoutput5", "testoutput6","mod_testoutput8","testoutput10"],
Testfiles = [ filename:join([RootDir,FN]) || FN <- Testfiles0 ],
Res = [ begin io:format("~s~n",[X]), t(X) end || X <- Testfiles ],
io:format("limit was: ~p~n",[ erts_debug:set_internal_state(re_loop_limit,default)]),
@@ -42,12 +42,14 @@ t(OneFile,Num) ->
put(error_limit,Num),
put(skipped,0),
Res =
- [test(Structured,true,index),
- test(Structured,false,index),
- test(Structured,true,binary),
- test(Structured,false,binary),
- test(Structured,true,list),
- test(Structured,false,list)],
+ [test(Structured,true,index,false),
+ test(Structured,false,index,false),
+ test(Structured,true,index,true),
+ test(Structured,false,index,true),
+ test(Structured,true,binary,false),
+ test(Structured,false,binary,false),
+ test(Structured,true,list,false),
+ test(Structured,false,list,false)],
{lists:sum(Res),length(Structured)*6,get(skipped)}.
@@ -63,11 +65,21 @@ pick_exec_options([Opt|T]) ->
pick_exec_options([]) ->
{[],[]}.
-test([],_,_) ->
+test([],_,_,_) ->
0;
-test([{RE,Line,Options0,Tests}|T],PreCompile,XMode) ->
+test([{RE0,Line,Options0,Tests}|T],PreCompile,XMode,REAsList) ->
%io:format("."),
%case RE of <<>> -> io:format("Empty re:~w~n",[Line]); _ -> ok end,
+ Unicode = lists:member(unicode,Options0),
+ RE = case REAsList of
+ true ->
+ if
+ Unicode -> unicode:characters_to_list(RE0);
+ true -> binary_to_list(RE0)
+ end;
+ false ->
+ RE0
+ end,
{Options,ExecOptions} = pick_exec_options(Options0),
{Cres, Xopt} = case PreCompile of
true ->
@@ -80,7 +92,7 @@ test([{RE,Line,Options0,Tests}|T],PreCompile,XMode) ->
%erlang:display({testrun,RE,P,Tests,ExecOptions,Xopt,XMode}),
case (catch testrun(RE,P,Tests,ExecOptions,Xopt,XMode)) of
N when is_integer(N) ->
- N + test(T,PreCompile,XMode);
+ N + test(T,PreCompile,XMode,REAsList);
limit ->
io:format("Error limit reached.~n"),
1;
@@ -91,12 +103,12 @@ test([{RE,Line,Options0,Tests}|T],PreCompile,XMode) ->
_ ->
put(skipped,1)
end,
- test(T,PreCompile,XMode)
+ test(T,PreCompile,XMode,REAsList)
end;
{error,Err} ->
io:format("Compile error(~w): ~w~n",[Line,Err]),
case get(error_limit) of
- infinite -> 1 + test(T,PreCompile,XMode);
+ infinite -> 1 + test(T,PreCompile,XMode,REAsList);
X ->
case X-1 of
Y when Y =< 0 ->
@@ -104,7 +116,7 @@ test([{RE,Line,Options0,Tests}|T],PreCompile,XMode) ->
1;
Y ->
put(error_limit,Y),
- 1 + test(T,PreCompile,XMode)
+ 1 + test(T,PreCompile,XMode,REAsList)
end
end
end.
@@ -549,6 +561,8 @@ tr_option($N) ->
[no_auto_capture];
tr_option($8) ->
[unicode];
+tr_option($U) ->
+ [ungreedy];
tr_option($g) ->
[{exec_option,g}];
tr_option(_) ->
@@ -973,6 +987,7 @@ gen_split_test(OneFile) ->
{ok,F}= file:open(ErlFileName,[write]),
io:format(F,"-module(~s).~n",[ErlModule]),
io:format(F,"-compile(export_all).~n",[]),
+ io:format(F,"-compile(no_native).~n",[]),
io:format(F,"-include(\"test_server.hrl\").~n",[]),
%io:format(F,"-define(line,erlang:display(?LINE),).~n",[]),
io:format(F,"%% This file is generated by running ~w:gen_split_test(~p)~n",
@@ -1054,6 +1069,7 @@ gen_repl_test(OneFile) ->
{ok,F}= file:open(ErlFileName,[write]),
io:format(F,"-module(~s).~n",[ErlModule]),
io:format(F,"-compile(export_all).~n",[]),
+ io:format(F,"-compile(no_native).~n",[]),
io:format(F,"-include(\"test_server.hrl\").~n",[]),
io:format(F,"%% This file is generated by running ~w:gen_repl_test(~p)~n",
[?MODULE,OneFile]),
diff --git a/lib/stdlib/test/select_SUITE.erl b/lib/stdlib/test/select_SUITE.erl
index 54664fbb00..6900f1a8f5 100644
--- a/lib/stdlib/test/select_SUITE.erl
+++ b/lib/stdlib/test/select_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -79,14 +79,14 @@ select_test(suite) ->
[];
select_test(doc) ->
["Tests select in numerous ways"];
-select_test(Config) when list(Config) ->
+select_test(Config) when is_list(Config) ->
do_test(Config).
return_values(suite) ->
[];
return_values(doc) ->
["Tests return values in specific situations for select/3 and select/1"];
-return_values(Config) when list(Config) ->
+return_values(Config) when is_list(Config) ->
do_return_values().
-endif.
@@ -279,7 +279,7 @@ cmp_ms_to_fun({Mod,Tab}, MS, Fun1, Fun2, ChunkSize) ->
MSRes = lists:sort(chunked_select(Mod,Tab,MS,ChunkSize)),
FunRes0 = table_foldl(Fun1,[],{Mod,Tab}),
FunRes = case Fun2 of
- F when function(F) ->
+ F when is_function(F) ->
FunRes1 = table_foldl(F,[],{Mod,Tab}),
lists:merge(FunRes0,FunRes1);
[] ->
diff --git a/lib/stdlib/test/slave_SUITE.erl b/lib/stdlib/test/slave_SUITE.erl
index 3b737af64d..5c1282fe9b 100644
--- a/lib/stdlib/test/slave_SUITE.erl
+++ b/lib/stdlib/test/slave_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(slave_SUITE).
@@ -31,7 +31,7 @@ all(suite) ->
[t_start_link, start_link_nodedown, t_start, errors].
t_start_link(suite) -> [];
-t_start_link(Config) when list(Config) ->
+t_start_link(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(20)),
%% Define useful variables.
@@ -81,7 +81,7 @@ t_start_link(Config) when list(Config) ->
%% Test that slave:start_link() works when the master exits.
start_link_nodedown(suite) -> [];
-start_link_nodedown(Config) when list(Config) ->
+start_link_nodedown(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(20)),
%% Define useful variables.
@@ -109,7 +109,7 @@ start_a_slave(ReplyTo, Host, Name) ->
%% Test slave:start().
t_start(suite) -> [];
-t_start(Config) when list(Config) ->
+t_start(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(20)),
%% Define useful variables.
@@ -160,7 +160,7 @@ t_start(Config) when list(Config) ->
%% in slave is 32 seconds).
errors(suite) -> [];
-errors(Config) when list(Config) ->
+errors(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(50)),
?line process_flag(trap_exit, true),
diff --git a/lib/stdlib/test/sofs_SUITE.erl b/lib/stdlib/test/sofs_SUITE.erl
index 0849e0f59c..d60cfc6895 100644
--- a/lib/stdlib/test/sofs_SUITE.erl
+++ b/lib/stdlib/test/sofs_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(sofs_SUITE).
@@ -115,7 +115,7 @@ sofs(suite) ->
from_term_1(suite) -> [];
from_term_1(doc) -> [""];
-from_term_1(Conf) when list(Conf) ->
+from_term_1(Conf) when is_list(Conf) ->
%% would go wrong: projection(1,from_term([{2,b},{1,a,b}])),
?line {'EXIT', {badarg, _}} = (catch from_term([], {atom,'_',atom})),
@@ -203,7 +203,7 @@ from_term_1(Conf) when list(Conf) ->
set_1(suite) -> [];
set_1(doc) -> [""];
-set_1(Conf) when list(Conf) ->
+set_1(Conf) when is_list(Conf) ->
%% set/1
?line {'EXIT', {badarg, _}} = (catch set(a)),
?line {'EXIT', {badarg, _}} = (catch set({a})),
@@ -235,7 +235,7 @@ set_1(Conf) when list(Conf) ->
from_sets_1(suite) -> [];
from_sets_1(doc) -> [""];
-from_sets_1(Conf) when list(Conf) ->
+from_sets_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
%% unordered
@@ -272,7 +272,7 @@ from_sets_1(Conf) when list(Conf) ->
relation_1(suite) -> [];
relation_1(doc) -> [""];
-relation_1(Conf) when list(Conf) ->
+relation_1(Conf) when is_list(Conf) ->
%% relation/1
?line eval(relation([]), from_term([], [{atom,atom}])),
?line eval(from_term([{a}]), relation([{a}])),
@@ -305,7 +305,7 @@ relation_1(Conf) when list(Conf) ->
a_function_1(suite) -> [];
a_function_1(doc) -> [""];
-a_function_1(Conf) when list(Conf) ->
+a_function_1(Conf) when is_list(Conf) ->
%% a_function/1
?line eval(a_function([]), from_term([], [{atom,atom}])),
?line eval(a_function([{a,b},{a,b},{b,c}]), from_term([{a,b},{b,c}])),
@@ -352,7 +352,7 @@ a_function_1(Conf) when list(Conf) ->
family_1(suite) -> [];
family_1(doc) -> [""];
-family_1(Conf) when list(Conf) ->
+family_1(Conf) when is_list(Conf) ->
%% family/1
?line eval(family([]), from_term([],[{atom,[atom]}])),
?line {'EXIT', {badarg, _}} = (catch family(a)),
@@ -413,7 +413,7 @@ family_1(Conf) when list(Conf) ->
projection(suite) -> [];
projection(doc) -> [""];
-projection(Conf) when list(Conf) ->
+projection(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
@@ -535,7 +535,7 @@ projection(Conf) when list(Conf) ->
substitution(suite) -> [];
substitution(doc) -> [""];
-substitution(Conf) when list(Conf) ->
+substitution(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
@@ -633,7 +633,7 @@ substitution(Conf) when list(Conf) ->
restriction(suite) -> [];
restriction(doc) -> [""];
-restriction(Conf) when list(Conf) ->
+restriction(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
@@ -752,7 +752,7 @@ restriction(Conf) when list(Conf) ->
drestriction(suite) -> [];
drestriction(doc) -> [""];
-drestriction(Conf) when list(Conf) ->
+drestriction(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
@@ -869,7 +869,7 @@ drestriction(Conf) when list(Conf) ->
strict_relation_1(suite) -> [];
strict_relation_1(doc) -> [""];
-strict_relation_1(Conf) when list(Conf) ->
+strict_relation_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
?line eval(strict_relation(E), E),
@@ -890,7 +890,7 @@ strict_relation_1(Conf) when list(Conf) ->
extension(suite) -> [];
extension(doc) -> [""];
-extension(Conf) when list(Conf) ->
+extension(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
?line EF = family([]),
@@ -933,7 +933,7 @@ lextension(R, S, C) ->
weak_relation_1(suite) -> [];
weak_relation_1(doc) -> [""];
-weak_relation_1(Conf) when list(Conf) ->
+weak_relation_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
?line eval(weak_relation(E), E),
@@ -966,7 +966,7 @@ weak_relation_1(Conf) when list(Conf) ->
to_sets_1(suite) -> [];
to_sets_1(doc) -> [""];
-to_sets_1(Conf) when list(Conf) ->
+to_sets_1(Conf) when is_list(Conf) ->
?line {'EXIT', {badarg, _}} = (catch to_sets(from_term(a))),
?line {'EXIT', {function_clause, _}} = (catch to_sets(a)),
%% unordered
@@ -988,8 +988,8 @@ to_sets_1(Conf) when list(Conf) ->
specification(suite) -> [];
specification(doc) -> [""];
-specification(Conf) when list(Conf) ->
- Fun = {external, fun(I) when integer(I) -> true; (_) -> false end},
+specification(Conf) when is_list(Conf) ->
+ Fun = {external, fun(I) when is_integer(I) -> true; (_) -> false end},
?line [1,2,3] = to_external(specification(Fun, set([a,1,b,2,c,3]))),
Fun2 = fun(S) -> is_subset(S, set([1,3,5,7,9])) end,
@@ -1014,7 +1014,7 @@ specification(Conf) when list(Conf) ->
union_1(suite) -> [];
union_1(doc) -> [""];
-union_1(Conf) when list(Conf) ->
+union_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
?line {'EXIT', {badarg, _}} = (catch union(ER)),
@@ -1044,7 +1044,7 @@ union_1(Conf) when list(Conf) ->
intersection_1(suite) -> [];
intersection_1(doc) -> [""];
-intersection_1(Conf) when list(Conf) ->
+intersection_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {badarg, _}} = (catch intersection(from_term([a,b]))),
?line {'EXIT', {badarg, _}} = (catch intersection(E)),
@@ -1068,7 +1068,7 @@ intersection_1(Conf) when list(Conf) ->
difference(suite) -> [];
difference(doc) -> [""];
-difference(Conf) when list(Conf) ->
+difference(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {type_mismatch, _}} =
(catch difference(relation([{a,b}]), relation([{a,b,c}]))),
@@ -1089,7 +1089,7 @@ difference(Conf) when list(Conf) ->
symdiff(suite) -> [];
symdiff(doc) -> [""];
-symdiff(Conf) when list(Conf) ->
+symdiff(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {type_mismatch, _}} =
(catch symdiff(relation([{a,b}]), relation([{a,b,c}]))),
@@ -1114,7 +1114,7 @@ symdiff(Conf) when list(Conf) ->
symmetric_partition(suite) -> [];
symmetric_partition(doc) -> [""];
-symmetric_partition(Conf) when list(Conf) ->
+symmetric_partition(Conf) when is_list(Conf) ->
?line E = set([]),
?line S1 = set([1,2,3,4]),
?line S2 = set([3,4,5,6]),
@@ -1148,7 +1148,7 @@ symmetric_partition(Conf) when list(Conf) ->
is_sofs_set_1(suite) -> [];
is_sofs_set_1(doc) -> [""];
-is_sofs_set_1(Conf) when list(Conf) ->
+is_sofs_set_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line true = is_sofs_set(E),
?line true = is_sofs_set(from_term([a])),
@@ -1159,7 +1159,7 @@ is_sofs_set_1(Conf) when list(Conf) ->
is_set_1(suite) -> [];
is_set_1(doc) -> [""];
-is_set_1(Conf) when list(Conf) ->
+is_set_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line true = is_set(E),
?line true = is_set(from_term([a])),
@@ -1177,7 +1177,7 @@ is_set_1(Conf) when list(Conf) ->
is_equal(suite) -> [];
is_equal(doc) -> [""];
-is_equal(Conf) when list(Conf) ->
+is_equal(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line true = is_equal(E, E),
?line false = is_equal(from_term([a]), E),
@@ -1212,7 +1212,7 @@ is_equal(Conf) when list(Conf) ->
is_subset(suite) -> [];
is_subset(doc) -> [""];
-is_subset(Conf) when list(Conf) ->
+is_subset(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line true = is_subset(E, E),
?line true = is_subset(set([a,c,e]), set([a,b,c,d,e])),
@@ -1230,7 +1230,7 @@ is_subset(Conf) when list(Conf) ->
is_a_function_1(suite) -> [];
is_a_function_1(doc) -> [""];
-is_a_function_1(Conf) when list(Conf) ->
+is_a_function_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
?line {'EXIT', {badarg, _}} = (catch is_a_function(set([a,b]))),
@@ -1254,7 +1254,7 @@ is_a_function_1(Conf) when list(Conf) ->
is_disjoint(suite) -> [];
is_disjoint(doc) -> [""];
-is_disjoint(Conf) when list(Conf) ->
+is_disjoint(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {type_mismatch, _}} =
(catch is_disjoint(relation([{a,1}]), set([a,b]))),
@@ -1268,7 +1268,7 @@ is_disjoint(Conf) when list(Conf) ->
join(suite) -> [];
join(doc) -> [""];
-join(Conf) when list(Conf) ->
+join(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {badarg, _}} = (catch join(relation([{a,1}]), 3, E, 5)),
@@ -1306,7 +1306,7 @@ join(Conf) when list(Conf) ->
canonical(suite) -> [];
canonical(doc) -> [""];
-canonical(Conf) when list(Conf) ->
+canonical(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {badarg, _}} =
(catch canonical_relation(set([a,b]))),
@@ -1318,7 +1318,7 @@ canonical(Conf) when list(Conf) ->
relation_to_family_1(suite) -> [];
relation_to_family_1(doc) -> [""];
-relation_to_family_1(Conf) when list(Conf) ->
+relation_to_family_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line eval(relation_to_family(E), E),
@@ -1333,7 +1333,7 @@ relation_to_family_1(Conf) when list(Conf) ->
domain_1(suite) -> [];
domain_1(doc) -> [""];
-domain_1(Conf) when list(Conf) ->
+domain_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line {'EXIT', {badarg, _}} = (catch domain(relation([],3))),
@@ -1355,7 +1355,7 @@ domain_1(Conf) when list(Conf) ->
range_1(suite) -> [];
range_1(doc) -> [""];
-range_1(Conf) when list(Conf) ->
+range_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line {'EXIT', {badarg, _}} = (catch range(relation([],3))),
@@ -1367,7 +1367,7 @@ range_1(Conf) when list(Conf) ->
inverse_1(suite) -> [];
inverse_1(doc) -> [""];
-inverse_1(Conf) when list(Conf) ->
+inverse_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line {'EXIT', {badarg, _}} = (catch inverse(relation([],3))),
@@ -1391,7 +1391,7 @@ inverse_1(Conf) when list(Conf) ->
converse_1(suite) -> [];
converse_1(doc) -> [""];
-converse_1(Conf) when list(Conf) ->
+converse_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line {'EXIT', {badarg, _}} = (catch converse(relation([],3))),
@@ -1407,7 +1407,7 @@ converse_1(Conf) when list(Conf) ->
no_elements_1(suite) -> [];
no_elements_1(doc) -> [""];
-no_elements_1(Conf) when list(Conf) ->
+no_elements_1(Conf) when is_list(Conf) ->
?line 0 = no_elements(empty_set()),
?line 0 = no_elements(set([])),
?line 1 = no_elements(from_term([a])),
@@ -1419,7 +1419,7 @@ no_elements_1(Conf) when list(Conf) ->
image(suite) -> [];
image(doc) -> [""];
-image(Conf) when list(Conf) ->
+image(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line eval(image(E, E), E),
@@ -1441,7 +1441,7 @@ image(Conf) when list(Conf) ->
inverse_image(suite) -> [];
inverse_image(doc) -> [""];
-inverse_image(Conf) when list(Conf) ->
+inverse_image(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line eval(inverse_image(E, E), E),
@@ -1468,7 +1468,7 @@ inverse_image(Conf) when list(Conf) ->
composite_1(suite) -> [];
composite_1(doc) -> [""];
-composite_1(Conf) when list(Conf) ->
+composite_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = a_function([]),
?line eval(composite(E, E), E),
@@ -1520,7 +1520,7 @@ composite_1(Conf) when list(Conf) ->
relative_product_1(suite) -> [];
relative_product_1(doc) -> [""];
-relative_product_1(Conf) when list(Conf) ->
+relative_product_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line eval(relative_product1(E, E), E),
@@ -1548,7 +1548,7 @@ relative_product_1(Conf) when list(Conf) ->
relative_product_2(suite) -> [];
relative_product_2(doc) -> [""];
-relative_product_2(Conf) when list(Conf) ->
+relative_product_2(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
@@ -1597,7 +1597,7 @@ relative_product_2(Conf) when list(Conf) ->
product_1(suite) -> [];
product_1(doc) -> [""];
-product_1(Conf) when list(Conf) ->
+product_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line eval(product(E, E), E),
?line eval(product(relation([]), E), E),
@@ -1625,7 +1625,7 @@ product_1(Conf) when list(Conf) ->
partition_1(suite) -> [];
partition_1(doc) -> [""];
-partition_1(Conf) when list(Conf) ->
+partition_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line Id = fun(A) -> A end,
@@ -1671,7 +1671,7 @@ partition_1(Conf) when list(Conf) ->
partition_3(suite) -> [];
partition_3(doc) -> [""];
-partition_3(Conf) when list(Conf) ->
+partition_3(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
@@ -1818,7 +1818,7 @@ lpartition(F, S1, S2) ->
multiple_relative_product(suite) -> [];
multiple_relative_product(doc) -> [""];
-multiple_relative_product(Conf) when list(Conf) ->
+multiple_relative_product(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line T = relation([{a,1},{a,11},{b,2},{c,3},{c,33},{d,4}]),
@@ -1842,7 +1842,7 @@ multiple_relative_product(Conf) when list(Conf) ->
digraph(suite) -> [];
digraph(doc) -> [""];
-digraph(Conf) when list(Conf) ->
+digraph(Conf) when is_list(Conf) ->
?line T0 = ets:all(),
?line E = empty_set(),
?line R = relation([{a,b},{b,c},{c,d},{d,a}]),
@@ -1901,7 +1901,7 @@ digraph(Conf) when list(Conf) ->
constant_function(suite) -> [];
constant_function(doc) -> [""];
-constant_function(Conf) when list(Conf) ->
+constant_function(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line C = from_term(3),
?line eval(constant_function(E, C), E),
@@ -1913,7 +1913,7 @@ constant_function(Conf) when list(Conf) ->
misc(suite) -> [];
misc(doc) -> [""];
-misc(Conf) when list(Conf) ->
+misc(Conf) when is_list(Conf) ->
% find "relational" part of relation:
?line S = relation([{a,b},{b,c},{b,d},{c,d}]),
Id = fun(A) -> A end,
@@ -1943,7 +1943,7 @@ sofs_family(suite) ->
family_specification(suite) -> [];
family_specification(doc) -> [""];
-family_specification(Conf) when list(Conf) ->
+family_specification(Conf) when is_list(Conf) ->
E = empty_set(),
%% internal
?line eval(family_specification({sofs, is_set}, E), E),
@@ -1963,7 +1963,7 @@ family_specification(Conf) when list(Conf) ->
(catch family_specification(Fun3, F3)),
%% external
- IsList = {external, fun(L) when list(L) -> true; (_) -> false end},
+ IsList = {external, fun(L) when is_list(L) -> true; (_) -> false end},
?line eval(family_specification(IsList, E), E),
?line eval(family_specification(IsList, F1), F1),
MF = {external, fun(L) -> lists:member(3, L) end},
@@ -1975,7 +1975,7 @@ family_specification(Conf) when list(Conf) ->
family_domain_1(suite) -> [];
family_domain_1(doc) -> [""];
-family_domain_1(Conf) when list(Conf) ->
+family_domain_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = from_term([{a,[]},{b,[]}],[{atom,[{atom,atom}]}]),
?line EF = from_term([{a,[]},{b,[]}],[{atom,[atom]}]),
@@ -2001,7 +2001,7 @@ family_domain_1(Conf) when list(Conf) ->
family_range_1(suite) -> [];
family_range_1(doc) -> [""];
-family_range_1(Conf) when list(Conf) ->
+family_range_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = from_term([{a,[]},{b,[]}],[{atom,[{atom,atom}]}]),
?line EF = from_term([{a,[]},{b,[]}],[{atom,[atom]}]),
@@ -2023,7 +2023,7 @@ family_range_1(Conf) when list(Conf) ->
family_to_relation_1(suite) -> [];
family_to_relation_1(doc) -> [""];
-family_to_relation_1(Conf) when list(Conf) ->
+family_to_relation_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line EF = family([]),
@@ -2037,7 +2037,7 @@ family_to_relation_1(Conf) when list(Conf) ->
union_of_family_1(suite) -> [];
union_of_family_1(doc) -> [""];
-union_of_family_1(Conf) when list(Conf) ->
+union_of_family_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = from_term([{a,[]},{b,[]}],[{atom,[atom]}]),
?line eval(union_of_family(E), E),
@@ -2052,7 +2052,7 @@ union_of_family_1(Conf) when list(Conf) ->
intersection_of_family_1(suite) -> [];
intersection_of_family_1(doc) -> [""];
-intersection_of_family_1(Conf) when list(Conf) ->
+intersection_of_family_1(Conf) when is_list(Conf) ->
?line EF = from_term([{a,[]},{b,[]}],[{atom,[atom]}]),
?line eval(intersection_of_family(EF), set([])),
?line FR = from_term([{a,[1,2,3]},{b,[2,3]},{c,[3,4,5]}]),
@@ -2066,7 +2066,7 @@ intersection_of_family_1(Conf) when list(Conf) ->
family_projection(suite) -> [];
family_projection(doc) -> [""];
-family_projection(Conf) when list(Conf) ->
+family_projection(Conf) when is_list(Conf) ->
SSType = [{atom,[[atom]]}],
SRType = [{atom,[{atom,atom}]}],
?line E = empty_set(),
@@ -2127,7 +2127,7 @@ family_projection(Conf) when list(Conf) ->
family_difference(suite) -> [];
family_difference(doc) -> [""];
-family_difference(Conf) when list(Conf) ->
+family_difference(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line F9 = from_term([{b,[b,c]}]),
@@ -2164,7 +2164,7 @@ family_difference(Conf) when list(Conf) ->
family_intersection_1(suite) -> [];
family_intersection_1(doc) -> [""];
-family_intersection_1(Conf) when list(Conf) ->
+family_intersection_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line ES = from_term([], [{atom,[[atom]]}]),
@@ -2184,7 +2184,7 @@ family_intersection_1(Conf) when list(Conf) ->
family_intersection_2(suite) -> [];
family_intersection_2(doc) -> [""];
-family_intersection_2(Conf) when list(Conf) ->
+family_intersection_2(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line F1 = from_term([{a,[1,2]},{b,[4,5]},{c,[7,8]},{d,[10,11]}]),
@@ -2215,7 +2215,7 @@ family_intersection_2(Conf) when list(Conf) ->
family_union_1(suite) -> [];
family_union_1(doc) -> [""];
-family_union_1(Conf) when list(Conf) ->
+family_union_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line ES = from_term([], [{atom,[[atom]]}]),
@@ -2230,7 +2230,7 @@ family_union_1(Conf) when list(Conf) ->
family_union_2(suite) -> [];
family_union_2(doc) -> [""];
-family_union_2(Conf) when list(Conf) ->
+family_union_2(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line F1 = from_term([{a,[1,2]},{b,[4,5]},{c,[7,8]},{d,[10,11]}]),
@@ -2259,7 +2259,7 @@ family_union_2(Conf) when list(Conf) ->
partition_family(suite) -> [];
partition_family(doc) -> [""];
-partition_family(Conf) when list(Conf) ->
+partition_family(Conf) when is_list(Conf) ->
?line E = empty_set(),
%% set of ordered sets
diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl
index b5d9ca44bf..f25e877289 100644
--- a/lib/stdlib/test/supervisor_SUITE.erl
+++ b/lib/stdlib/test/supervisor_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Description: Tests supervisor.erl
@@ -89,7 +89,7 @@ sup_start_normal(doc) ->
["Tests that the supervisor process starts correctly and that it "
"can be terminated gracefully."];
sup_start_normal(suite) -> [];
-sup_start_normal(Config) when list(Config) ->
+sup_start_normal(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
?line exit(Pid, shutdown),
@@ -107,7 +107,7 @@ sup_start_normal(Config) when list(Config) ->
sup_start_ignore_init(doc) ->
["Tests what happens if init-callback returns ignore"];
sup_start_ignore_init(suite) -> [];
-sup_start_ignore_init(Config) when list(Config) ->
+sup_start_ignore_init(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line ignore = start(ignore),
@@ -127,7 +127,7 @@ sup_start_ignore_init(Config) when list(Config) ->
sup_start_ignore_child(doc) ->
["Tests what happens if init-callback returns ignore"];
sup_start_ignore_child(suite) -> [];
-sup_start_ignore_child(Config) when list(Config) ->
+sup_start_ignore_child(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, _Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, [ignore]},
@@ -146,7 +146,7 @@ sup_start_ignore_child(Config) when list(Config) ->
sup_start_error_return(doc) ->
["Tests what happens if init-callback returns a invalid value"];
sup_start_error_return(suite) -> [];
-sup_start_error_return(Config) when list(Config) ->
+sup_start_error_return(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {error, Term} = start(invalid),
@@ -165,7 +165,7 @@ sup_start_error_return(Config) when list(Config) ->
sup_start_fail(doc) ->
["Tests what happens if init-callback fails"];
sup_start_fail(suite) -> [];
-sup_start_fail(Config) when list(Config) ->
+sup_start_fail(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {error, Term} = start(fail),
@@ -192,7 +192,7 @@ sup_stop_infinity(doc) ->
"for children of type supervisor"];
sup_stop_infinity(suite) -> [];
-sup_stop_infinity(Config) when list(Config) ->
+sup_stop_infinity(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []},
@@ -230,7 +230,7 @@ sup_stop_timeout(doc) ->
["See sup_stop/1 when Shutdown = 1000"];
sup_stop_timeout(suite) -> [];
-sup_stop_timeout(Config) when list(Config) ->
+sup_stop_timeout(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []},
@@ -278,7 +278,7 @@ sup_stop_brutal_kill(doc) ->
["See sup_stop/1 when Shutdown = brutal_kill"];
sup_stop_brutal_kill(suite) -> [];
-sup_stop_brutal_kill(Config) when list(Config) ->
+sup_stop_brutal_kill(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []},
@@ -327,7 +327,7 @@ extra_return(doc) ->
"and restart_child/2"];
extra_return(suite) -> [];
-extra_return(Config) when list(Config) ->
+extra_return(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child1, {supervisor_1, start_child, [extra_return]},
permanent, 1000,
@@ -367,7 +367,7 @@ child_adm(doc)->
"restart_child/2, which_children/1. Only correct childspecs are used, "
"handling of incorrect childspecs is tested in child_specs/1"];
child_adm(suite) -> [];
-child_adm(Config) when list(Config) ->
+child_adm(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -430,7 +430,7 @@ child_adm_simple(doc) ->
"restart_child/2 are not valid for a simple_one_for_one supervisor "
"check that the correct error message is returned."];
child_adm_simple(suite) -> [];
-child_adm_simple(Config) when list(Config) ->
+child_adm_simple(Config) when is_list(Config) ->
Child = {child, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
?line {ok, _Pid} = start({ok, {{simple_one_for_one, 2, 3600}, [Child]}}),
@@ -467,7 +467,7 @@ child_adm_simple(Config) when list(Config) ->
child_specs(doc) ->
["Tests child specs, invalid formats should be rejected."];
child_specs(suite) -> [];
-child_specs(Config) when list(Config) ->
+child_specs(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, _Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
?line {error, _} = supervisor:start_child(sup_test, hej),
@@ -526,7 +526,7 @@ normal_termination(suite) ->
permanent_normal(doc) ->
["A permanent child should always be restarted"];
permanent_normal(suite) -> [];
-permanent_normal(Config) when list(Config) ->
+permanent_normal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -548,7 +548,7 @@ transient_normal(doc) ->
["A transient child should not be restarted if it exits with "
"reason normal"];
transient_normal(suite) -> [];
-transient_normal(Config) when list(Config) ->
+transient_normal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, transient, 1000,
worker, []},
@@ -564,7 +564,7 @@ transient_normal(Config) when list(Config) ->
temporary_normal(doc) ->
["A temporary process should never be restarted"];
temporary_normal(suite) -> [];
-temporary_normal(Config) when list(Config) ->
+temporary_normal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, temporary, 1000,
worker, []},
@@ -586,7 +586,7 @@ abnormal_termination(suite) ->
permanent_abnormal(doc) ->
["A permanent child should always be restarted"];
permanent_abnormal(suite) -> [];
-permanent_abnormal(Config) when list(Config) ->
+permanent_abnormal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -608,7 +608,7 @@ transient_abnormal(doc) ->
["A transient child should be restarted if it exits with "
"reason abnormal"];
transient_abnormal(suite) -> [];
-transient_abnormal(Config) when list(Config) ->
+transient_abnormal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, transient, 1000,
worker, []},
@@ -631,7 +631,7 @@ transient_abnormal(Config) when list(Config) ->
temporary_abnormal(doc) ->
["A temporary process should never be restarted"];
temporary_abnormal(suite) -> [];
-temporary_abnormal(Config) when list(Config) ->
+temporary_abnormal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, temporary, 1000,
worker, []},
@@ -653,7 +653,7 @@ restart_one_for_one(suite) -> [one_for_one, one_for_one_escalation].
one_for_one(doc) ->
["Test the one_for_one base case."];
one_for_one(suite) -> [];
-one_for_one(Config) when list(Config) ->
+one_for_one(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -697,7 +697,7 @@ one_for_one(Config) when list(Config) ->
one_for_one_escalation(doc) ->
["Test restart escalation on a one_for_one supervisor."];
one_for_one_escalation(suite) -> [];
-one_for_one_escalation(Config) when list(Config) ->
+one_for_one_escalation(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, [error]},
permanent, 1000,
@@ -737,7 +737,7 @@ restart_one_for_all(suite) ->
one_for_all(doc) ->
["Test the one_for_all base case."];
one_for_all(suite) -> [];
-one_for_all(Config) when list(Config) ->
+one_for_all(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -788,7 +788,7 @@ one_for_all(Config) when list(Config) ->
one_for_all_escalation(doc) ->
["Test restart escalation on a one_for_all supervisor."];
one_for_all_escalation(suite) -> [];
-one_for_all_escalation(Config) when list(Config) ->
+one_for_all_escalation(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -830,7 +830,7 @@ restart_simple_one_for_one(suite) ->
simple_one_for_one(doc) ->
["Test the simple_one_for_one base case."];
simple_one_for_one(suite) -> [];
-simple_one_for_one(Config) when list(Config) ->
+simple_one_for_one(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -872,7 +872,7 @@ simple_one_for_one_extra(doc) ->
["Tests automatic restart of children "
"who's start function return extra info."];
simple_one_for_one_extra(suite) -> [];
-simple_one_for_one_extra(Config) when list(Config) ->
+simple_one_for_one_extra(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child, {supervisor_1, start_child, [extra_info]},
permanent, 1000, worker, []},
@@ -912,7 +912,7 @@ simple_one_for_one_extra(Config) when list(Config) ->
simple_one_for_one_escalation(doc) ->
["Test restart escalation on a simple_one_for_one supervisor."];
simple_one_for_one_escalation(suite) -> [];
-simple_one_for_one_escalation(Config) when list(Config) ->
+simple_one_for_one_escalation(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -947,7 +947,7 @@ restart_rest_for_one(suite) -> [rest_for_one, rest_for_one_escalation].
rest_for_one(doc) ->
["Test the rest_for_one base case."];
rest_for_one(suite) -> [];
-rest_for_one(Config) when list(Config) ->
+rest_for_one(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -1018,7 +1018,7 @@ rest_for_one(Config) when list(Config) ->
rest_for_one_escalation(doc) ->
["Test restart escalation on a rest_for_one supervisor."];
rest_for_one_escalation(suite) -> [];
-rest_for_one_escalation(Config) when list(Config) ->
+rest_for_one_escalation(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -1052,7 +1052,7 @@ rest_for_one_escalation(Config) when list(Config) ->
child_unlink(doc)-> ["Test that the supervisor does not hang forever if "
"the child unliks and then is terminated by the supervisor."];
child_unlink(suite) -> [];
-child_unlink(Config) when list(Config) ->
+child_unlink(Config) when is_list(Config) ->
?line {ok, SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
@@ -1081,7 +1081,7 @@ tree(doc) ->
["Test a basic supervison tree."];
tree(suite) ->
[];
-tree(Config) when list(Config) ->
+tree(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []},
diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl
index af687ed2e1..7646f4c249 100644
--- a/lib/stdlib/test/tar_SUITE.erl
+++ b/lib/stdlib/test/tar_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(tar_SUITE).
@@ -183,7 +183,7 @@ atomic(doc) ->
"and uncompressed archives."
"Also test the 'cooked' option."];
atomic(suite) -> [];
-atomic(Config) when list(Config) ->
+atomic(Config) when is_list(Config) ->
?line ok = file:set_cwd(?config(priv_dir, Config)),
?line DataFiles = data_files(),
?line Names = [Name || {Name,_,_} <- DataFiles],
@@ -369,7 +369,7 @@ try_bad(Name0, Reason, Config) ->
case catch erl_tar:format_error(Reason) of
{'EXIT', CrashReason} ->
test_server:fail({format_error, crashed, CrashReason});
- String when list(String) ->
+ String when is_list(String) ->
io:format("format_error(~p) -> ~s", [Reason, String]);
Other ->
test_server:fail({format_error, returned, Other})
@@ -413,7 +413,7 @@ try_error(M, F, A, Error) ->
case catch erl_tar:format_error(Error) of
{'EXIT', FReason} ->
test_server:fail({format_error, crashed, FReason});
- String when list(String) ->
+ String when is_list(String) ->
io:format("format_error(~p) -> ~s", [Error, String]);
Other ->
test_server:fail({format_error, returned, Other})
@@ -431,7 +431,7 @@ remove_prefix(_, Result) ->
extract_from_binary(doc) ->
"Test extracting a tar archive from a binary.";
-extract_from_binary(Config) when list(Config) ->
+extract_from_binary(Config) when is_list(Config) ->
?line DataDir = ?config(data_dir, Config),
?line PrivDir = ?config(priv_dir, Config),
?line Long = filename:join(DataDir, "no_fancy_stuff.tar"),
diff --git a/lib/stdlib/test/timer_SUITE.erl b/lib/stdlib/test/timer_SUITE.erl
index 86d8612b56..5f38c91c64 100644
--- a/lib/stdlib/test/timer_SUITE.erl
+++ b/lib/stdlib/test/timer_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(timer_SUITE).
@@ -271,7 +271,7 @@ collect(N, {E,A,B}, I) ->
print_report ->
print_report({E,A,B,I}),
collect(N,{E,A,B}, I);
- {Pid, get_report} when pid(Pid) ->
+ {Pid, get_report} when is_pid(Pid) ->
Pid ! {report, {E, A, B, I}},
collect(N,{E,A,B}, I);
reset ->
diff --git a/lib/stdlib/test/unicode_SUITE.erl b/lib/stdlib/test/unicode_SUITE.erl
index 706445005c..141ac64606 100644
--- a/lib/stdlib/test/unicode_SUITE.erl
+++ b/lib/stdlib/test/unicode_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(unicode_SUITE).
@@ -276,7 +276,7 @@ ex_latin1(Config) when is_list(Config) ->
unicode:characters_to_list(make_unaligned(MissingLastByte),unicode),
?line DoubleSize16 = byte_size(DoubleUtf16),
- ?line DoubleUtf16_2 = erlang:concat_binary([DoubleUtf16,<<16#FFFFF/utf16-big>>]),
+ ?line DoubleUtf16_2 = list_to_binary([DoubleUtf16,<<16#FFFFF/utf16-big>>]),
?line DoubleSize16_2 = byte_size(DoubleUtf16_2),
?line AllBut1_16 = DoubleSize16 - 1,
?line AllBut2_16_2 = DoubleSize16_2 - 2,
@@ -884,15 +884,15 @@ utf8_to_list_bsyntax(<<C/utf8,R/binary>>) ->
list_to_utf8_bsyntax(List,unicode) ->
FList = flatx(List),
- erlang:concat_binary([ if
- is_binary(E) ->
- E;
- true ->
- <<E/utf8>>
- end || E <- FList ]);
+ list_to_binary([ if
+ is_binary(E) ->
+ E;
+ true ->
+ <<E/utf8>>
+ end || E <- FList ]);
list_to_utf8_bsyntax(List,latin1) ->
FList = flatb(List),
- erlang:concat_binary([ <<E/utf8>> || E <- FList ]).
+ list_to_binary([ <<E/utf8>> || E <- FList ]).
@@ -954,15 +954,15 @@ utf16_big_to_list_bsyntax(<<C/utf16-big,R/binary>>) ->
list_to_utf16_big_bsyntax(List,{utf16,big}) ->
FList = flatx(List),
- erlang:concat_binary([ if
- is_binary(E) ->
- E;
- true ->
- <<E/utf16-big>>
- end || E <- FList ]);
+ list_to_binary([ if
+ is_binary(E) ->
+ E;
+ true ->
+ <<E/utf16-big>>
+ end || E <- FList ]);
list_to_utf16_big_bsyntax(List,latin1) ->
FList = flatb(List),
- erlang:concat_binary([ <<E/utf16-big>> || E <- FList ]).
+ list_to_binary([ <<E/utf16-big>> || E <- FList ]).
utf16_little_to_list_bsyntax(<<>>) ->
@@ -972,15 +972,15 @@ utf16_little_to_list_bsyntax(<<C/utf16-little,R/binary>>) ->
list_to_utf16_little_bsyntax(List,{utf16,little}) ->
FList = flatx(List),
- erlang:concat_binary([ if
- is_binary(E) ->
- E;
- true ->
- <<E/utf16-little>>
- end || E <- FList ]);
+ list_to_binary([ if
+ is_binary(E) ->
+ E;
+ true ->
+ <<E/utf16-little>>
+ end || E <- FList ]);
list_to_utf16_little_bsyntax(List,latin1) ->
FList = flatb(List),
- erlang:concat_binary([ <<E/utf16-little>> || E <- FList ]).
+ list_to_binary([ <<E/utf16-little>> || E <- FList ]).
@@ -991,15 +991,15 @@ utf32_big_to_list_bsyntax(<<C/utf32-big,R/binary>>) ->
list_to_utf32_big_bsyntax(List,{utf32,big}) ->
FList = flatx(List),
- erlang:concat_binary([ if
- is_binary(E) ->
- E;
- true ->
- <<E/utf32-big>>
- end || E <- FList ]);
+ list_to_binary([ if
+ is_binary(E) ->
+ E;
+ true ->
+ <<E/utf32-big>>
+ end || E <- FList ]);
list_to_utf32_big_bsyntax(List,latin1) ->
FList = flatb(List),
- erlang:concat_binary([ <<E/utf32-big>> || E <- FList ]).
+ list_to_binary([ <<E/utf32-big>> || E <- FList ]).
utf32_little_to_list_bsyntax(<<>>) ->
@@ -1009,15 +1009,15 @@ utf32_little_to_list_bsyntax(<<C/utf32-little,R/binary>>) ->
list_to_utf32_little_bsyntax(List,{utf32,little}) ->
FList = flatx(List),
- erlang:concat_binary([ if
- is_binary(E) ->
- E;
- true ->
- <<E/utf32-little>>
- end || E <- FList ]);
+ list_to_binary([ if
+ is_binary(E) ->
+ E;
+ true ->
+ <<E/utf32-little>>
+ end || E <- FList ]);
list_to_utf32_little_bsyntax(List,latin1) ->
FList = flatb(List),
- erlang:concat_binary([ <<E/utf32-little>> || E <- FList ]).
+ list_to_binary([ <<E/utf32-little>> || E <- FList ]).
diff --git a/lib/stdlib/test/win32reg_SUITE.erl b/lib/stdlib/test/win32reg_SUITE.erl
index 3ad58eba03..c8cc82f61e 100644
--- a/lib/stdlib/test/win32reg_SUITE.erl
+++ b/lib/stdlib/test/win32reg_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(win32reg_SUITE).
@@ -37,7 +37,7 @@ fini(Config) when is_list(Config) ->
Config.
long(doc) -> "Test long keys and entries (OTP-3446).";
-long(Config) when list(Config) ->
+long(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(10)),
?line LongKey = "software\\" ++
@@ -61,7 +61,7 @@ long(Config) when list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
-evil_write(Config) when list(Config) ->
+evil_write(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(10)),
?line Key = "Software\\Ericsson\\Erlang",
diff --git a/lib/stdlib/test/zip_SUITE.erl b/lib/stdlib/test/zip_SUITE.erl
index 55cbd277ef..12ca655000 100644
--- a/lib/stdlib/test/zip_SUITE.erl
+++ b/lib/stdlib/test/zip_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(zip_SUITE).
@@ -181,7 +181,7 @@ atomic(doc) ->
["Test the 'atomic' operations: zip/unzip/list_dir, on archives."
"Also test the 'cooked' option."];
atomic(suite) -> [];
-atomic(Config) when list(Config) ->
+atomic(Config) when is_list(Config) ->
ok = file:set_cwd(?config(priv_dir, Config)),
DataFiles = data_files(),
Names = [Name || {Name,_,_} <- DataFiles],
@@ -209,7 +209,7 @@ openzip_api(doc) ->
["Test the openzip_open/2, openzip_get/1, openzip_get/2, openzip_close/1 "
"and openzip_list_dir/1 functions."];
openzip_api(suite) -> [];
-openzip_api(Config) when list(Config) ->
+openzip_api(Config) when is_list(Config) ->
ok = file:set_cwd(?config(priv_dir, Config)),
DataFiles = data_files(),
Names = [Name || {Name, _, _} <- DataFiles],
@@ -248,7 +248,7 @@ zip_api(doc) ->
["Test the zip_open/2, zip_get/1, zip_get/2, zip_close/1 "
"and zip_list_dir/1 functions."];
zip_api(suite) -> [];
-zip_api(Config) when list(Config) ->
+zip_api(Config) when is_list(Config) ->
ok = file:set_cwd(?config(priv_dir, Config)),
DataFiles = data_files(),
Names = [Name || {Name, _, _} <- DataFiles],
@@ -550,7 +550,7 @@ aliases(Config) when is_list(Config) ->
unzip_from_binary(doc) ->
["Test extracting a zip archive from a binary."];
-unzip_from_binary(Config) when list(Config) ->
+unzip_from_binary(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
ExtractDir = filename:join(PrivDir, "extract_from_binary"),
@@ -626,7 +626,7 @@ delete_all_in(Dir) ->
compress_control(doc) ->
["Test control of which files that should be compressed"];
compress_control(suite) -> [];
-compress_control(Config) when list(Config) ->
+compress_control(Config) when is_list(Config) ->
ok = file:set_cwd(?config(priv_dir, Config)),
Dir = "compress_control",
Files = [
diff --git a/lib/syntax_tools/Makefile b/lib/syntax_tools/Makefile
index 08ede67209..37e84a80a5 100644
--- a/lib/syntax_tools/Makefile
+++ b/lib/syntax_tools/Makefile
@@ -58,10 +58,10 @@ include $(ERL_TOP)/make/otp_subdir.mk
version:
@echo "$(VSN)"
-docs:
- erl -noshell -pa "$(BINDIR)" -run edoc_run application "'$(APPNAME)'" '"."' '$(DOC_OPTS)' -s init stop
+# The overriding "docs" target have been removed so the default make rules work properly.
-edocs: docs
+edocs:
+ erl -noshell -pa "$(BINDIR)" -run edoc_run application "'$(APPNAME)'" '"."' '$(DOC_OPTS)' -s init stop
app_release: tar
diff --git a/lib/syntax_tools/doc/src/Makefile b/lib/syntax_tools/doc/src/Makefile
index 2065614251..291b3e3047 100644
--- a/lib/syntax_tools/doc/src/Makefile
+++ b/lib/syntax_tools/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2006-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2006-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
@@ -101,10 +101,10 @@ html: gifs $(HTML_REF_MAN_FILE)
man: $(MAN3_FILES)
$(XML_REF3_FILES):
- docb_gen $(SRC_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(SRC_DIR)/$(@:%.xml=%.erl)
$(XML_CHAPTER_FILES):
- docb_gen -chapter -def vsn $(VSN) ../overview.edoc
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -chapter ../overview.edoc
gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
diff --git a/lib/syntax_tools/src/Makefile b/lib/syntax_tools/src/Makefile
index 5ffe85c975..62a24d98c0 100644
--- a/lib/syntax_tools/src/Makefile
+++ b/lib/syntax_tools/src/Makefile
@@ -34,15 +34,15 @@ OBJECTS=$(SOURCES:%.erl=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
APP_FILE= syntax_tools.app
APP_SRC= $(APP_FILE).src
APP_TARGET= $(EBIN)/$(APP_FILE)
-
+
APPUP_FILE= syntax_tools.appup
APPUP_SRC= $(APPUP_FILE).src
APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
-
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
-
+
debug opt: $(OBJECTS)
all: $(OBJECTS)
@@ -52,6 +52,8 @@ clean:
rm -f $(OBJECTS)
rm -f core *~
+docs:
+
distclean: clean
realclean: clean
@@ -62,10 +64,10 @@ $(EBIN)/%.$(EMULATOR):%.erl
# ----------------------------------------------------
# Special Build Targets
# ----------------------------------------------------
-
+
$(APP_TARGET): $(APP_SRC) ../vsn.mk
sed -e 's;%VSN%;$(VSN);' $< > $@
-
+
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
sed -e 's;%VSN%;$(VSN);' $< > $@
diff --git a/lib/test_server/doc/src/Makefile b/lib/test_server/doc/src/Makefile
index e3c1b8ce92..c7ba415e5b 100644
--- a/lib/test_server/doc/src/Makefile
+++ b/lib/test_server/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -60,6 +60,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES =
# ----------------------------------------------------
diff --git a/lib/test_server/src/Makefile b/lib/test_server/src/Makefile
index 2d7e5b28bc..d55a3a597d 100644
--- a/lib/test_server/src/Makefile
+++ b/lib/test_server/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -104,7 +104,7 @@ clean:
rm -f $(TARGET_FILES) $(TS_TARGET_FILES)
rm -f core
-doc:
+docs:
configure: configure.in
autoconf configure.in > configure
diff --git a/lib/tools/test/Makefile b/lib/tools/test/Makefile
new file mode 100644
index 0000000000..a846a3a6f4
--- /dev/null
+++ b/lib/tools/test/Makefile
@@ -0,0 +1,90 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+MODULES = \
+ cover_SUITE \
+ eprof_SUITE \
+ emem_SUITE \
+ fprof_SUITE \
+ cprof_SUITE \
+ instrument_SUITE \
+ make_SUITE \
+ tools_SUITE \
+ xref_SUITE \
+ ignore_cores
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+INSTALL_PROGS= $(TARGET_FILES)
+
+EMAKEFILE=Emakefile
+
+SPEC_FILES= tools.spec tools.spec.win
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/tools_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+.PHONY: make_emakefile
+
+make_emakefile:
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\
+ > $(EMAKEFILE)
+
+tests debug opt: make_emakefile
+ erl $(ERL_MAKE_FLAGS) -make
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: make_emakefile
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SPEC_FILES) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
+
+
diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl
new file mode 100644
index 0000000000..b9ccd62d0b
--- /dev/null
+++ b/lib/tools/test/cover_SUITE.erl
@@ -0,0 +1,1198 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(cover_SUITE).
+
+-export([all/1]).
+-export([start/1, compile/1, analyse/1, misc/1, stop/1,
+ distribution/1, export_import/1,
+ otp_5031/1, eif/1, otp_5305/1, otp_5418/1, otp_6115/1, otp_7095/1,
+ otp_8188/1, otp_8270/1, otp_8273/1, otp_8340/1]).
+
+-include("test_server.hrl").
+
+%%----------------------------------------------------------------------
+%% The following directory structure is assumed:
+%% cwd __________________________________________
+%% | \ \ \ \ \ \ \
+%% a b cc d f d1 compile_beam_____ otp_6115
+%% | \ \ \ \ \ \ \
+%% e crypt v w x d f1 f2
+%% |
+%% y
+%%----------------------------------------------------------------------
+
+all(suite) ->
+ case whereis(cover_server) of
+ undefined ->
+ [start, compile, analyse, misc, stop, distribution,
+ export_import,
+ otp_5031, eif, otp_5305, otp_5418, otp_6115, otp_7095,
+ otp_8188, otp_8270, otp_8273, otp_8340];
+ _pid ->
+ {skip,"It looks like the test server is running cover. "
+ "Can't run cover test."}
+ end.
+
+start(suite) -> [];
+start(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(data_dir, Config)),
+
+ ?line Files = lsfiles(),
+ ?line remove(files(Files, ".out")),
+
+ ?line {ok, Pid} = cover:start(),
+ ?line {error, {already_started, Pid}} = cover:start().
+
+compile(suite) -> [];
+compile(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(data_dir, Config)),
+
+ ?line Result1 = cover:compile_directory(),
+ ?line SortedResult = lists:sort(Result1),
+ ?line {ok, CWD} = file:get_cwd(),
+ ?line Result2 = cover:compile_directory(CWD),
+ ?line SortedResult = lists:sort(Result2),
+ ?line [{error,_DFile},{ok,a},{ok,b},{ok,cc},{ok,f}] = SortedResult,
+ ?line [{ok,e}] = cover:compile_directory("d1"),
+ ?line {error,enoent} = cover:compile_directory("d2"),
+
+ ?line {ok,a} = cover:compile(a),
+ ?line {ok,b} = compile:file(b),
+ ?line code:purge(b),
+ ?line {module,b} = code:load_file(b),
+ ?line {ok,d} = cover:compile("d.erl", [{d,'AGE',42}]),
+ ?line {error,_BBFile} = cover:compile(bb),
+
+ ?line StdlibDir = code:lib_dir(stdlib),
+ ?line Lists = filename:join([StdlibDir, "src", "lists.erl"]),
+ ?line {error, Lists} = cover:compile(Lists),
+
+ %% For compiling beam: using dummy files v,w,x,y and z
+ ?line file:set_cwd("compile_beam"),
+ ?line {ok,_} = compile:file(v,[debug_info,report]),
+ ?line {ok,_} = compile:file(w,[debug_info,report]),
+ ?line {ok,_} = compile:file(x),
+ ?line {ok,_} = compile:file("d/y",[debug_info,{outdir,"d"},report]),
+ ?line Key = "A Krypto Key",
+ ?line {ok,_} = compile:file(crypt, [debug_info,{debug_info_key,Key},report]),
+ ?line {ok,v} = cover:compile_beam(v),
+ ?line {ok,w} = cover:compile_beam("w.beam"),
+ ?line {error,{encrypted_abstract_code,_}} =
+ cover:compile_beam("crypt.beam"),
+ ?line ok = beam_lib:crypto_key_fun(simple_crypto_fun(Key)),
+ ?line {ok,crypt} = cover:compile_beam("crypt.beam"),
+ ?line {error,{no_abstract_code,"./x.beam"}} = cover:compile_beam(x),
+ ?line {error,{already_cover_compiled,no_beam_found,a}}=cover:compile_beam(a),
+ ?line {error,non_existing} = cover:compile_beam(z),
+ ?line [{ok,y}] = cover:compile_beam_directory("d"),
+ ?line Result3 = lists:sort(cover:compile_beam_directory()),
+ ?line [{error,{no_abstract_code,_XBeam}},{ok,crypt},{ok,v},{ok,w}] = Result3,
+ ?line {error,enoent} = cover:compile_beam_directory("d2"),
+ ?line decompile([v,w,y]),
+ ?line Files = lsfiles(),
+ ?line remove(files(Files, ".beam")).
+
+simple_crypto_fun(Key) ->
+ fun(init) -> ok;
+ ({debug_info, des3_cbc, crypt, _}) -> Key
+ end.
+
+analyse(suite) -> [];
+analyse(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(data_dir, Config)),
+
+ ?line done = a:start(5),
+
+ ?line {ok, {a,{17,2}}} = cover:analyse(a, coverage, module),
+ ?line {ok, [{{a,start,1},{6,0}},
+ {{a,stop,1},{0,1}},
+ {{a,pong,1},{1,0}},
+ {{a,loop,3},{5,1}},
+ {{a,trycatch,1},{4,0}},
+ {{a,exit_kalle,0},{1,0}}]} = cover:analyse(a, coverage, function),
+ ?line {ok, [{{a,start,1,1},{6,0}},
+ {{a,stop,1,1},{0,1}},
+ {{a,pong,1,1},{1,0}},
+ {{a,loop,3,1},{3,1}},
+ {{a,loop,3,2},{2,0}},
+ {{a,trycatch,1,1},{4,0}},
+ {{a,exit_kalle,0,1},{1,0}}]} = cover:analyse(a, coverage, clause),
+ ?line {ok, [{{a,9},{1,0}},
+ {{a,10},{1,0}},
+ {{a,11},{1,0}},
+ {{a,13},{1,0}},
+ {{a,14},{1,0}},
+ {{a,15},{1,0}},
+ {{a,21},{0,1}},
+ {{a,26},{1,0}},
+ {{a,31},{1,0}},
+ {{a,32},{1,0}},
+ {{a,34},{1,0}},
+ {{a,36},{0,1}},
+ {{a,39},{1,0}},
+ {{a,40},{1,0}},
+ {{a,44},{1,0}},
+ {{a,47},{1,0}},
+ {{a,49},{1,0}},
+ {{a,51},{1,0}},
+ {{a,55},{1,0}}]} = cover:analyse(a, coverage, line),
+
+ ?line {ok, {a,15}} = cover:analyse(a, calls, module),
+ ?line {ok, [{{a,start,1},1},
+ {{a,stop,1},0},
+ {{a,pong,1},5},
+ {{a,loop,3},6},
+ {{a,trycatch,1},2},
+ {{a,exit_kalle,0},1}]} = cover:analyse(a, calls, function),
+ ?line {ok, [{{a,start,1,1},1},
+ {{a,stop,1,1},0},
+ {{a,pong,1,1},5},
+ {{a,loop,3,1},5},
+ {{a,loop,3,2},1},
+ {{a,trycatch,1,1},2},
+ {{a,exit_kalle,0,1},1}]} = cover:analyse(a, calls, clause),
+ ?line {ok, [{{a,9},1},
+ {{a,10},1},
+ {{a,11},1},
+ {{a,13},1},
+ {{a,14},1},
+ {{a,15},1},
+ {{a,21},0},
+ {{a,26},5},
+ {{a,31},5},
+ {{a,32},5},
+ {{a,34},5},
+ {{a,36},0},
+ {{a,39},1},
+ {{a,40},1},
+ {{a,44},2},
+ {{a,47},1},
+ {{a,49},1},
+ {{a,51},2},
+ {{a,55},1}]} = cover:analyse(a, calls, line),
+
+ ?line {ok, [{{a,start,1},{6,0}},
+ {{a,stop,1},{0,1}},
+ {{a,pong,1},{1,0}},
+ {{a,loop,3},{5,1}},
+ {{a,trycatch,1},{4,0}},
+ {{a,exit_kalle,0},{1,0}}]} = cover:analyse(a),
+ ?line {ok, {a,{17,2}}} = cover:analyse(a, module),
+ ?line {ok, [{{a,start,1},1},
+ {{a,stop,1},0},
+ {{a,pong,1},5},
+ {{a,loop,3},6},
+ {{a,trycatch,1},2},
+ {{a,exit_kalle,0},1}]} = cover:analyse(a, calls),
+
+ ?line {ok, "a.COVER.out"} = cover:analyse_to_file(a),
+ ?line {ok, "e.COVER.out"} = cover:analyse_to_file(e),
+ ?line {ok, "a.COVER.html"} = cover:analyse_to_file(a,[html]),
+ ?line {ok, "e.COVER.html"} = cover:analyse_to_file(e,[html]),
+
+ %% analyse_to_file of file which is compiled from beam
+ ?line {ok,f} = compile:file(f,[debug_info]),
+ ?line code:purge(f),
+ ?line {module,f} = code:load_file(f),
+ ?line {ok,f} = cover:compile_beam(f),
+ ?line f:f2(),
+ ?line {ok, "f.COVER.out"} = cover:analyse_to_file(f),
+
+ %% Source code cannot be found by analyse_to_file
+ ?line {ok,v} = compile:file("compile_beam/v",[debug_info]),
+ ?line code:purge(v),
+ ?line {module,v} = code:load_file(v),
+ ?line {ok,v} = cover:compile_beam(v),
+ ?line {error,no_source_code_found} = cover:analyse_to_file(v),
+
+ ?line {error,{not_cover_compiled,b}} = cover:analyse(b),
+ ?line {error,{not_cover_compiled,g}} = cover:analyse(g),
+ ?line {error,{not_cover_compiled,b}} = cover:analyse_to_file(b),
+ ?line {error,{not_cover_compiled,g}} = cover:analyse_to_file(g).
+
+misc(suite) -> [];
+misc(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(data_dir, Config)),
+
+ ?line [a,cc,crypt,d,e,f,v] = lists:sort(cover:modules()),
+
+ ?line {ok,cc} = compile:file(cc),
+ ?line code:purge(cc),
+ ?line {module,cc} = code:load_file(cc),
+ ?line [a,crypt,d,e,f,v] = lists:sort(cover:modules()),
+
+ ?line {file, _File} = cover:is_compiled(a),
+ ?line false = cover:is_compiled(b),
+ ?line false = cover:is_compiled(g),
+
+ ?line ok = cover:reset(a),
+ ?line {ok, {a,{0,19}}} = cover:analyse(a, module),
+ ?line ok = cover:reset().
+
+stop(suite) -> [];
+stop(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(data_dir, Config)),
+
+ ?line cover_compiled = code:which(a),
+ ?line {ok,d} = compile:file(d, [{d,'AGE',42}]),
+ ?line code:purge(d),
+ ?line {module,d} = code:load_file(d),
+ ?line ok = cover:stop(),
+ ?line Beam = code:which(a),
+ ?line true = is_unloaded(Beam),
+
+ ?line Files = lsfiles(),
+ ?line remove(files(Files, ".out")),
+ ?line remove(files(Files, ".html")),
+ ?line remove(files(Files, ".beam")).
+
+distribution(suite) -> [];
+distribution(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line ok = file:set_cwd(DataDir),
+
+ ?line {ok,N1} = ?t:start_node(cover_SUITE_distribution1,slave,[]),
+ ?line {ok,N2} = ?t:start_node(cover_SUITE_distribution2,slave,[]),
+ ?line {ok,N3} = ?t:start_node(cover_SUITE_distribution3,slave,[]),
+
+ %% Check that an already compiled module is loaded on new nodes
+ ?line {ok,f} = cover:compile(f),
+ ?line {ok,[_,_,_]} = cover:start(nodes()),
+ ?line cover_compiled = code:which(f),
+ ?line cover_compiled = rpc:call(N1,code,which,[f]),
+ ?line cover_compiled = rpc:call(N2,code,which,[f]),
+ ?line cover_compiled = rpc:call(N3,code,which,[f]),
+
+ %% Check that a node cannot be started twice
+ ?line {ok,[]} = cover:start(N2),
+
+ %% Check that the current node (i.e. the main node) is not started with
+ %% start/1 and not stopped with stop/1
+ ?line {ok,[]} = cover:start(node()),
+ ?line ok = cover:stop(node()),
+ ?line true = is_pid(whereis(cover_server)),
+
+ %% Check that a new compiled module is loaded on all existing nodes
+ ?line compile:file("compile_beam/v",[debug_info]),
+ ?line {ok,v} = cover:compile_beam(v),
+ ?line cover_compiled = code:which(v),
+ ?line cover_compiled = rpc:call(N1,code,which,[v]),
+ ?line cover_compiled = rpc:call(N2,code,which,[v]),
+ ?line cover_compiled = rpc:call(N3,code,which,[v]),
+
+ %% this is lost when the node is killed
+ ?line rpc:call(N3,f,f2,[]),
+ ?line rpc:call(N3,erlang,halt,[]),
+
+ %% this should be visible in analyse
+ ?line rpc:call(N1,f,f1,[]),
+
+ %% Check that data is collected from remote node when stopped
+ ?line ok = cover:stop(N1),
+ ?line N1Beam = rpc:call(N1,code,which,[f]),
+ ?line true = is_unloaded(N1Beam),
+ ?line check_f_calls(1,0),
+
+ %% Call f:f1() again on another node and check that number of calls is
+ %% accumulated.
+ ?line f:f1(),
+ ?line check_f_calls(2,0),
+
+ %% Check that reset works on all nodes
+ ?line f:f1(),
+ ?line rpc:call(N2,f,f1,[]),
+ ?line ok = cover:reset(f),
+ ?line check_f_calls(0,0),
+
+ %% Check that data is collected from all nodes
+ ?line rpc:call(N2,f,f1,[]),
+ ?line f:f2(),
+ ?line check_f_calls(1,1),
+
+ %% Check that same data is not fetched again (i.e. that analyse does
+ %% reset on the remote node(s))
+ ?line check_f_calls(1,1),
+
+ %% Check that stop() unloads on all nodes
+ ?line ok = cover:stop(),
+ ?line LocalBeam = code:which(f),
+ ?line N2Beam = rpc:call(N2,code,which,[f]),
+ ?line true = is_unloaded(LocalBeam),
+ ?line true = is_unloaded(N2Beam),
+
+ %% Check that cover_server on remote node dies if main node dies
+ ?line {ok,[N1]} = cover:start(N1),
+ ?line true = is_pid(rpc:call(N1,erlang,whereis,[cover_server])),
+ ?line exit(whereis(cover_server),kill),
+ ?line timer:sleep(10),
+ ?line undefined = rpc:call(N1,erlang,whereis,[cover_server]),
+
+ %% Cleanup
+ ?line Files = lsfiles(),
+ ?line remove(files(Files, ".beam")),
+ ?line ?t:stop_node(N1),
+ ?line ?t:stop_node(N2).
+
+
+export_import(suite) -> [];
+export_import(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line ok = file:set_cwd(DataDir),
+
+ %% Export one module
+ ?line {ok,f} = cover:compile(f),
+ ?line f:f1(),
+ %% check that no info is written about where data comes from when no
+ %% files are imported
+ ?line ?t:capture_start(),
+ ?line check_f_calls(1,0),
+ ?line [] = ?t:capture_get(),
+ ?line ?t:capture_stop(),
+ ?line ok = cover:export("f_exported",f),
+ ?line check_f_calls(1,0),
+ ?line ok = cover:stop(),
+
+ %% Check that same data exists after import and that info is written about
+ %% data comming from imported file
+ ?line ok = cover:import("f_exported"),
+ ?line ?t:capture_start(),
+ ?line check_f_calls(1,0),
+ ?line [Text1] = ?t:capture_get(),
+ ?line "Analysis includes data from imported files"++_ = lists:flatten(Text1),
+ ?line ?t:capture_stop(),
+
+ %% Export all modules
+ ?line {ok,a} = cover:compile(a),
+ ?line ?t:capture_start(),
+ ?line ok = cover:export("all_exported"),
+ ?line [Text2] = ?t:capture_get(),
+ ?line "Export includes data from imported files"++_ = lists:flatten(Text2),
+ ?line ?t:capture_stop(),
+ ?line ok = cover:stop(),
+ ?line ok = cover:import("all_exported"),
+ ?line check_f_calls(1,0),
+
+ %% Check that data is reset when module is compiled again, and that
+ %% warning is written when data is deleted for imported module.
+ ?line ?t:capture_start(),
+ ?line {ok,f} = cover:compile(f),
+ ?line timer:sleep(10), % capture needs some time
+ ?line [Text3] = ?t:capture_get(),
+ ?line "WARNING: Deleting data for module f imported from" ++ _ =
+ lists:flatten(Text3),
+ ?line ?t:capture_stop(),
+ ?line check_f_calls(0,0),
+
+ %% Check that data is summed up when first compiled and then imported
+ %% The module which has been compiled (f) is loaded from the file
+ %% all_exported again (since it has been reset during cover compiling),
+ %% but the other module (a) is not loaded since it is already loaded
+ ?line f:f1(),
+ ?line f:f2(),
+ ?line ok = cover:import("f_exported"),
+ ?line ?t:capture_start(),
+ ?line ok = cover:import("all_exported"),
+ ?line [Text4] = ?t:capture_get(), % a is not loaded again
+ ?line "WARNING: Module a already imported from " ++ _ = lists:flatten(Text4),
+ ?line ?t:capture_stop(),
+ ?line check_f_calls(3,1),
+
+ %% Check that warning is written when same file is imported twice,
+ %% and that data is not imported again
+ ?line ?t:capture_start(),
+ ?line ok = cover:import("all_exported"),
+ ?line [Text5,Text6] = ?t:capture_get(),
+ ?line "WARNING: Module f already imported from " ++ _ = lists:flatten(Text5),
+ ?line "WARNING: Module a already imported from " ++ _ = lists:flatten(Text6),
+ ?line ?t:capture_stop(),
+ ?line check_f_calls(3,1),
+
+ %% Check that reset removes all data and that the file which has been
+ %% reset can be imported again with no warning
+ ?line cover:reset(f),
+ ?line check_f_calls(0,0),
+ ?line ?t:capture_start(),
+ ?line ok = cover:import("all_exported"),
+ ?line [Text7] = ?t:capture_get(), % warning only on mod a
+ ?line "WARNING: Module a already imported from " ++ _ = lists:flatten(Text7),
+ ?line ?t:capture_stop(),
+ ?line check_f_calls(1,0),
+
+ %% same as above - only reset all
+ ?line cover:reset(),
+ ?line check_f_calls(0,0),
+ ?line ?t:capture_start(),
+ ?line ok = cover:import("all_exported"),
+ ?line [] = ?t:capture_get(), % no warnings
+ ?line ?t:capture_stop(),
+ ?line check_f_calls(1,0),
+
+ %% Cleanup
+ ?line ok = cover:stop(),
+ ?line Files = lsfiles(),
+ ?line remove(["f_exported","all_exported"|files(Files, ".beam")]).
+
+
+otp_5031(suite) -> [];
+otp_5031(Config) when is_list(Config) ->
+
+ Dog = ?t:timetrap(?t:seconds(10)),
+
+ ?line {ok,N1} = ?t:start_node(cover_SUITE_distribution1,slave,[]),
+ ?line {ok,[N1]} = cover:start(N1),
+ ?line {error,not_main_node} = rpc:call(N1,cover,modules,[]),
+ ?line cover:stop(),
+
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+eif(doc) ->
+ ["Test the \'Exclude Included Functions\' functionality"];
+eif(suite) ->
+ [];
+eif(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(filename:join(?config(data_dir, Config),
+ "included_functions")),
+ ?line {ok, cover_inc} = compile:file(cover_inc,[debug_info]),
+ ?line {ok, cover_inc} = cover:compile_beam(cover_inc),
+
+ %% This function will cause an included function to be executed.
+ %% The analysis should only show the lines that actually exist
+ %% in cover_inc.beam - not the ones from the included file.
+ ?line cover_inc:func(),
+ ?line {ok, [_, _]} = cover:analyse(cover_inc, line),
+ ?line cover:stop(),
+ ok.
+
+otp_5305(suite) -> [];
+otp_5305(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(priv_dir, Config)),
+
+ File = "t.erl",
+ Test = <<"-module(t).
+ -export([t/0]).
+ -include_lib(\"stdlib/include/ms_transform.hrl\").
+ t() ->
+ ets:fun2ms(fun(X) -> X end).
+ ">>,
+ ?line ok = file:write_file(File, Test),
+ ?line {ok, t} = cover:compile(File),
+ ?line cover:stop(),
+ ?line ok = file:delete(File),
+
+ ok.
+
+otp_5418(suite) -> [];
+otp_5418(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(priv_dir, Config)),
+
+ File = "t.erl",
+ Test = <<"-module(t).
+ ">>,
+ ?line ok = file:write_file(File, Test),
+ ?line {ok, t} = cover:compile(File),
+ ?line {ok,{t,{0,0}}} = cover:analyse(t, module),
+ ?line cover:stop(),
+ ?line ok = file:delete(File),
+
+ ok.
+
+otp_6115(suite) -> [];
+otp_6115(Config) when is_list(Config) ->
+ case erlang:system_info(heap_type) of
+ hybrid -> {skip,"Hybrid-heap emulator doesn't keep track of funs"};
+ _ -> otp_6115_1(Config)
+ end.
+
+otp_6115_1(Config) ->
+ ?line {ok, CWD} = file:get_cwd(),
+ ?line Dir = filename:join(?config(data_dir, Config), otp_6115),
+ ?line ok = file:set_cwd(Dir),
+ ?line {ok, f1} = compile:file(f1, [debug_info]),
+ ?line {ok, f2} = compile:file(f2, [debug_info]),
+
+ %% Cover compile f1, but not f2
+ ?line {ok, f1} = cover:compile(f1),
+
+ %% If f1 is cover compiled, a process P is started with a
+ %% reference to the fun created in start_fail/0, and cover:stop() is
+ %% called, then P should be killed.
+ %% This is because (the fun held by P) references the cover
+ %% compiled code which should be *unloaded* when cover:stop() is
+ %% called -- running cover compiled code when there is no cover
+ %% server and thus no ets tables to bump counters in, makes no
+ %% sense.
+ ?line Pid1 = f1:start_fail(),
+
+ %% If f1 is cover compiled, a process P is started with a
+ %% reference to the fun created in start_ok/0, and
+ %% cover:stop() is called, then P should survive.
+ %% This is because (the fun held by) P always references the current
+ %% version of the module, and is thus not affected by the cover
+ %% compiled version being unloaded.
+ ?line Pid2 = f1:start_ok(),
+
+ %% Now stop cover
+ ?line cover:stop(),
+
+ %% Ensure that f1 is loaded (and not cover compiled), that Pid1
+ %% is dead and Pid2 is alive, but with no reference to old code
+ case code:which(f1) of
+ Beam when is_list(Beam) ->
+ ok;
+ Other ->
+ ?line ?t:fail({"f1 is not reloaded", Other})
+ end,
+ case process_info(Pid1) of
+ undefined ->
+ ok;
+ _PI1 ->
+ RefToOldP = erlang:check_process_code(Pid1, f1),
+ ?line ?t:fail({"Pid1 still alive", RefToOldP})
+ end,
+ case process_info(Pid2) of
+ PI2 when is_list(PI2) ->
+ case erlang:check_process_code(Pid2, f2) of
+ false ->
+ ok;
+ true ->
+ ?line ?t:fail("Pid2 has ref to old code")
+ end;
+ undefined ->
+ ?line ?t:fail("Pid2 has died")
+ end,
+
+ ?line file:set_cwd(CWD),
+ ok.
+
+otp_7095(doc) ->
+ ["andalso/orelse"];
+otp_7095(suite) -> [];
+otp_7095(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(priv_dir, Config)),
+
+ File = "t.erl",
+ Test = <<"-module(t).
+ -export([t/0]).
+ t() ->
+ t1(),
+ t2(),
+ t3(),
+ t4(),
+ t5(),
+ put(t6, 0),
+ 0 = t6(),
+ 1 = erase(t6),
+ t7(),
+ put(t8, 0),
+ {'EXIT',{{badarg,0},_}} = (catch t8()),
+ 1 = erase(t8),
+ t9(),
+ ok.
+
+ t1() ->
+ false % 20
+ andalso
+ true. % 22
+
+ t2() ->
+ true % 25
+ andalso
+ true. % 27
+
+ t3() ->
+ false % 30
+ orelse
+ true. % 32
+
+ t4() ->
+ true % 35
+ orelse
+ true. % 37
+
+ t5() ->
+ true % 40
+ andalso
+ true % 42
+ andalso
+ false. % 44
+
+ t6() ->
+ true andalso % 47
+ add_one(t6). % 48
+
+ t7() ->
+ true % 51
+ andalso
+ false % 53
+ andalso
+ not_ok. % 55
+
+ t8() ->
+ true % 58
+ andalso
+ true % 60
+ andalso
+ add_one(t8) % 62
+ andalso
+ false. % 64
+
+ t9() ->
+ if % 67
+ true ->
+ true % 69
+ andalso
+ false % 71
+ end
+ orelse
+ case ok of % 74
+ true ->
+ a; % 76
+ _ ->
+ true % 78
+ end.
+
+ add_one(T) ->
+ put(T, get(T) + 1). % 82
+ ">>,
+ ?line ok = file:write_file(File, Test),
+ ?line {ok, t} = cover:compile(File),
+ ?line ok = t:t(),
+ ?line {ok,[{{t,4},1},{{t,5},1},{{t,6},1},{{t,7},1},{{t,8},1},{{t,9},1},
+ {{t,10},1},{{t,11},1},{{t,12},1},{{t,13},1},{{t,14},1},
+ {{t,15},1},{{t,16},1},{{t,17},1},
+ {{t,20},1},{{t,22},0},
+ {{t,25},1},{{t,27},1},
+ {{t,30},1},{{t,32},1},
+ {{t,35},1},{{t,37},0},
+ {{t,40},1},{{t,42},1},{{t,44},1},
+ {{t,47},1},{{t,48},1},
+ {{t,51},1},{{t,53},1},{{t,55},0},
+ {{t,58},1},{{t,60},1},{{t,62},1},{{t,64},0},
+ {{t,67},1},{{t,69},1},{{t,71},1},{{t,74},1},
+ {{t,76},0},{{t,78},1},
+ {{t,82},2}]} = cover:analyse(t, calls, line),
+ ?line cover:stop(),
+ ?line ok = file:delete(File),
+
+ ok.
+
+otp_8270(doc) ->
+ ["OTP-8270. Bug."];
+otp_8270(suite) -> [];
+otp_8270(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line ok = file:set_cwd(DataDir),
+
+ ?line PrivDir = ?config(priv_dir, Config),
+
+ As = [{args," -pa " ++ PrivDir}],
+ ?line {ok,N1} = ?t:start_node(cover_n1,slave,As),
+ ?line {ok,N2} = ?t:start_node(cover_n2,slave,As),
+ ?line {ok,N3} = ?t:start_node(cover_n3,slave,As),
+
+ timer:sleep(500),
+ cover:start(nodes()),
+
+ Test = <<
+ "-module(m).\n"
+ "-compile(export_all).\n"
+ "t() -> t(0).\n"
+ "l() ->\n"
+ " catch ets:tab2list(cover_internal_data_table).\n"
+ "t(Sz) ->\n"
+ " case ets:info(cover_internal_data_table, size) of\n"
+ " Sz ->\n"
+ " m:t(Sz); % Not a local call! Newly loaded code is entered.\n"
+ " NSz ->\n"
+ " % error_logger:info_msg(\"~p: ~p ~p change~n L1 ~p~n\", \n"
+ " % [node(), Sz, NSz, l()]),\n"
+ " m:t(NSz)\n"
+ " end.\n">>,
+ ?line _File = c_mod(m, Test, Config),
+ Fun = fun m:t/0,
+ ?line Pid1 = spawn(Fun),
+ ?line Pid2 = spawn(N1, Fun),
+ ?line Pid3 = spawn(N2, Fun),
+ ?line Pid4 = spawn(N3, Fun),
+
+ ?line {ok, m} = cover:compile_beam(m),
+
+ timer:sleep(1000),
+
+ ?line Info = erlang:process_info(Pid1),
+ ?line N1_info = rpc:call(N1, erlang, process_info, [Pid2]),
+ ?line N2_info = rpc:call(N2, erlang, process_info, [Pid3]),
+ ?line N3_info = rpc:call(N3, erlang, process_info, [Pid4]),
+
+ ?line true = is_list(Info),
+ ?line {N1,true} = {N1,is_list(N1_info)},
+ ?line {N2,true} = {N2,is_list(N2_info)},
+ ?line {N3,true} = {N3,is_list(N3_info)},
+
+ ?line ?t:stop_node(N1),
+ ?line ?t:stop_node(N2),
+ ?line ?t:stop_node(N3),
+ ok.
+
+otp_8273(doc) ->
+ ["OTP-8270. Bug."];
+otp_8273(suite) -> [];
+otp_8273(Config) when is_list(Config) ->
+ Test = <<"-module(t).
+ -export([t/0]).
+ t() ->
+ foo = true andalso foo,
+ bar = false orelse bar,
+ ok.
+ ">>,
+ ?line File = cc_mod(t, Test, Config),
+ ?line ok = t:t(),
+ ?line cover:stop(),
+ ?line ok = file:delete(File),
+
+ ok.
+
+otp_8340(doc) ->
+ ["OTP-8340. Bug."];
+otp_8340(suite) -> [];
+otp_8340(Config) when is_list(Config) ->
+ ?line [{{t,1},1},{{t,2},1},{{t,4},1}] =
+ analyse_expr(<<"<< \n"
+ " <<3:2, \n"
+ " SeqId:62>> \n"
+ " || SeqId <- [64] >>">>, Config),
+
+ ok.
+
+otp_8188(doc) ->
+ ["Clauses on the same line."];
+otp_8188(suite) -> [];
+otp_8188(Config) when is_list(Config) ->
+ %% This example covers the bug report:
+ Test = <<"-module(t).
+ -export([test/1]).
+
+ -define(FOOBAR(X),
+ case X of
+ ok -> true;
+ _ -> false
+ end).
+
+ test(X)->
+ _Res =
+ ?FOOBAR(X).
+ ">>,
+ ?line File = cc_mod(t, Test, Config),
+ ?line false = t:test(nok),
+ ?line {ok,[{{t,11},1},{{t,12},1}]} = cover:analyse(t, calls, line),
+ ?line cover:stop(),
+ ?line ok = file:delete(File),
+
+ %% Bit string comprehensions are now traversed;
+ %% the handling of list comprehensions has been improved:
+ comprehension_8188(Config),
+
+ %% Variants of the reported bug:
+ bug_8188(Config),
+ ok.
+
+bug_8188(Cf) ->
+ ?line [{{t,1},1},{{t,2},1},{{t,3},1}] =
+ analyse_expr(<<"A = 3,\n" % 1
+ " case A of\n" % 1
+ " 2 -> two; 3 -> three end, A + 2">>, % 1
+ Cf),
+
+ ?line [{{t,1},1},
+ {{t,2},0},
+ {{t,3},1},
+ {{t,4},1},
+ {{t,5},1},
+ {{t,6},0},
+ {{t,7},1},
+ {{t,9},2}] =
+ analyse_expr(<<"case two() of\n" % 1
+ " 1 -> 2;\n" % 0
+ " _ -> begin 3 end\n" % 1
+ " +\n" % 1
+ " begin 4 end end, case two() of\n" % 1
+ " 1 -> a;\n" % 0
+ " 2 -> b; 3 -> c\n" % 1
+ " end.\n"
+ "two() -> 2">>, Cf), % 2
+
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},1},
+ {{t,4},1}, {{t,5},1}, {{t,6},0}] =
+ analyse_expr(<<" self() ! 1,\n"
+ " receive \n"
+ " X=1 -> a;\n"
+ " X=2 -> b end, case X of \n"
+ " 1 -> a;\n"
+ " 2 -> b\n"
+ " end">>, Cf),
+
+ T0 = <<"t1(X) ->\n "
+ "case X of\n"
+ " 1 -> A=a,B=A,B; % bump Li\n"
+ " 2 -> b; 3 -> case X of % 2 -> b shall bump Li\n"
+ " 3 -> a; % bump Li\n"
+ " 2 -> b end; 4 -> d end, case X of % Li\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c;\n"
+ " 4 -> d\n"
+ " end">>,
+
+ T1 = [<<"a = t1(1). ">>,T0],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},1}, {{t,4},0},
+ {{t,5},0}, {{t,6},1}, {{t,7},1}, {{t,8},0}, {{t,9},0}] =
+ analyse_expr(T1, Cf),
+
+ T2 = [<<"b = t1(2). ">>,T0],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},1}, {{t,9},0}] =
+ analyse_expr(T2, Cf),
+
+ T3 = [<<"c = t1(3). ">>,T0],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},1}, {{t,6},1}, {{t,7},0}, {{t,8},1}, {{t,9},0}] =
+ analyse_expr(T3, Cf),
+
+ T4 = [<<"d = t1(4). ">>,T0],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},0},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},0}, {{t,9},1}] =
+ analyse_expr(T4, Cf),
+
+ ?line [{{t,1},1},{{t,2},1},{{t,3},1},{{t,4},1},{{t,5},1}] =
+ analyse_expr(
+ <<"2 = x3(1). "
+ "x3(X) ->\n"
+ " case X of \n"
+ " 1 -> case X of\n"
+ " 1 -> a, Y = 2;\n"
+ " 2 -> b, Y = 3 end, Y; 2 -> Y = 4 end, Y">>, Cf),
+
+ ?line [{{t,1},1},{{t,2},1},{{t,3},1},{{t,4},1}] =
+ analyse_expr(
+ <<"1 = x4(1). "
+ "x4(X) ->\n"
+ " case X of\n"
+ " 1 -> case X of\n"
+ " 1 -> Y = 1 end, case X of 1 -> Y = 1 end, Y end">>,
+ Cf),
+
+ T10 = <<"t1(X) ->\n"
+ "if\n"
+ " X =:= 1 -> a;\n"
+ " X =:= 2 -> b; X =:= 3 -> c end, case X of \n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c end, case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c\n"
+ " end">>,
+ T11 = [<<"a = t1(1). ">>,T10],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},1}, {{t,4},1},
+ {{t,5},1}, {{t,6},1}, {{t,7},1}, {{t,8},0}] =
+ analyse_expr(T11, Cf),
+
+ T12 = [<<"b = t1(2). ">>,T10],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},1}] =
+ analyse_expr(T12, Cf),
+
+ T13 = [<<"c = t1(3). ">>,T10],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},1}] =
+ analyse_expr(T13, Cf),
+
+ T20 = <<"t1(X) ->\n"
+ "case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c end end, case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c\n"
+ " end">>,
+
+ T21 = [<<"a = t1(1). ">>,T20],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},1}, {{t,4},0},
+ {{t,5},0}, {{t,6},1}, {{t,7},1}, {{t,8},0}] =
+ analyse_expr(T21, Cf),
+
+ T22 = [<<"b = t1(2). ">>,T20],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},1}] =
+ analyse_expr(T22, Cf),
+
+ T23 = [<<"c = t1(3). ">>,T20],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},1}] =
+ analyse_expr(T23, Cf),
+
+ T30 = <<
+ "t1(X) ->\n"
+ "case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> case X of 1 -> a; 2 -> b; 3 -> c end end, case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c\n"
+ " end\n">>,
+
+ T31 = [<<"a = t1(1). ">>,T30],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},1},
+ {{t,4},1}, {{t,5},1}, {{t,6},0}] =
+ analyse_expr(T31, Cf),
+
+ T32 = [<<"b = t1(2). ">>,T30],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0},
+ {{t,4},1}, {{t,5},0}, {{t,6},1}] =
+ analyse_expr(T32, Cf),
+
+ T33 = [<<"c = t1(3). ">>,T30],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0},
+ {{t,4},1}, {{t,5},0}, {{t,6},1}] =
+ analyse_expr(T33, Cf),
+
+ %% 'try' now traverses the body as a body...
+ ?line [{{t,1},1},{{t,2},1},{{t,3},1},{{t,4},0},{{t,6},1}] =
+ analyse_expr(<<"try \n"
+ " B = 2, \n"
+ " C = erlang:error(foo), \n"
+ " {B,C} \n"
+ "catch _:_ -> \n"
+ " foo \n"
+ "end">>, Cf),
+
+ %% receive after:
+ ?line [{{t,1},1},{{t,2},0},{{t,3},1}] =
+ analyse_expr(<<"receive \n"
+ " X=1 -> a; \n"
+ " X=2 -> b after begin 10 end -> X=3 end">>, Cf),
+ ?line [{{t,1},1},{{t,2},0},{{t,3},1}] =
+ analyse_expr(<<"receive \n"
+ " X=1 -> a; \n"
+ " X=2 -> b after 10 -> begin X=3 end end">>, Cf),
+ ok.
+
+comprehension_8188(Cf) ->
+ ?line [{{t,1},1}] =
+ analyse_expr(<<"[begin X end || X <- [1,2,3], X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,2},1}] =
+ analyse_expr(<<"[begin X end || \n"
+ " X <- [1,2,3], X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,2},1},{{t,3},3}] =
+ analyse_expr(<<"[begin X end || \n "
+ " X <- [1,2,3], \n "
+ " X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,3},1},{{t,4},3}] =
+ analyse_expr(<<"[begin X end || \n "
+ " X <- \n "
+ " [1,2,3], \n "
+ " X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,2},2}] =
+ analyse_expr(<<"[ \n "
+ " X || X <- [1,2,3], X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,2},2},{{t,3},3}] =
+ analyse_expr(<<"[ \n"
+ " X || X <- [1,2,3], \n"
+ " X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,2},1},{{t,3},2}] =
+ analyse_expr(<<"[ \n "
+ " X || X <- [1,2,3], X > 1, \n"
+ " X > 2]">>, Cf),
+
+ ?line [{{t,1},1},
+ {{t,3},2},
+ {{t,5},1},
+ {{t,7},1},
+ {{t,8},0},
+ {{t,12},3},
+ {{t,15},2},
+ {{t,17},2},
+ {{t,18},1}] =
+ analyse_expr(<<"[ \n" % 1
+ " begin\n"
+ " X * 2\n" % 2
+ " end ||\n"
+ " X <- [1,\n" % 1
+ " case two() of\n"
+ " 2 -> 2;\n" % 1
+ " _ -> two\n" % 0
+ " end,\n"
+ " 3],\n"
+ " begin\n"
+ " math:sqrt(X) > 1.0\n" % 3
+ " end,\n"
+ " begin\n"
+ " true\n" % 2
+ " end,\n"
+ " true]. \n" % 2
+ " two() -> 2">>, Cf), % 1
+
+ ?line [{{t,1},1},
+ {{t,2},2},
+ {{t,3},1},
+ {{t,5},1},
+ {{t,6},0},
+ {{t,9},3},
+ {{t,10},2},
+ {{t,11},2},
+ {{t,12},1}] =
+ analyse_expr(<<"[ \n"
+ " X * 2 || \n" % 2
+ " X <- [1,\n" % 1
+ " case two() of\n"
+ " 2 -> 2;\n" % 1
+ " _ -> two\n" % 0
+ " end,\n"
+ " 3],\n"
+ " math:sqrt(X) > 1.0,\n" % 3
+ " true,\n" % 2
+ " true]. \n" % 2
+ " two() -> 2">>, Cf), % 1
+
+ ?line [{{t,1},1},
+ {{t,2},2},
+ {{t,3},1},
+ {{t,4},1},
+ {{t,5},0},
+ {{t,8},1},
+ {{t,9},0},
+ {{t,12},3},
+ {{t,13},2},
+ {{t,14},2}] =
+ analyse_expr(<<"<< \n" % 1
+ " << (X*2) >> || \n" % 2
+ " <<X>> <= << (case two() of\n"
+ " 2 -> 1;\n" % 1
+ " _ -> 2\n" % 0
+ " end)/integer,\n"
+ " (case two() of \n"
+ " 2 -> 2;\n" % 1
+ " _ -> two\n" % 0
+ " end)/integer,\n"
+ " 3 >>, \n"
+ " math:sqrt(X) > 1.0,\n" % 3
+ " true >>.\n" % 2
+ "two() -> 2">>, Cf),
+
+ ?line [{{t,1},1},
+ {{t,2},4},
+ {{t,4},1},
+ {{t,6},1},
+ {{t,7},0},
+ {{t,10},3},
+ {{t,11},2},
+ {{t,12},4},
+ {{t,13},1}] =
+ analyse_expr(<<"<< \n" % 1
+ " << (2)\n" % 4
+ " :(8) >> || \n"
+ " <<X>> <= << 1,\n" % 1
+ " (case two() of \n"
+ " 2 -> 2;\n" % 1
+ " _ -> two\n" % 0
+ " end)/integer,\n"
+ " 3 >>, \n"
+ " math:sqrt(X) > 1.0,\n" % 3
+ " <<_>> <= << 1, 2 >>,\n" % 2
+ " true >>.\n" % 4
+ "two() -> 2">>, Cf), % 1
+
+ ok.
+
+%%--Auxiliary------------------------------------------------------------
+
+analyse_expr(Expr, Config) ->
+ Binary = [<<"-module(t). "
+ "-export([t/0]). "
+ "t() -> ">>, Expr, <<".\n">>],
+ File = cc_mod(t, Binary, Config),
+ t:t(),
+ {ok, Result} = cover:analyse(t, calls, line),
+ ok = file:delete(File),
+ Result.
+
+cc_mod(M, Binary, Config) ->
+ {ok, Dir} = file:get_cwd(),
+ PrivDir = ?config(priv_dir, Config),
+ ok = file:set_cwd(PrivDir),
+ File = atom_to_list(M) ++ ".erl",
+ try
+ ok = file:write_file(File, Binary),
+ {ok, M} = cover:compile(File),
+ filename:join(PrivDir, File)
+ after file:set_cwd(Dir)
+ end.
+
+c_mod(M, Binary, Config) ->
+ {ok, Dir} = file:get_cwd(),
+ PrivDir = ?config(priv_dir, Config),
+ ok = file:set_cwd(PrivDir),
+ File = atom_to_list(M) ++ ".erl",
+ try
+ ok = file:write_file(File, Binary),
+ {ok, M} = compile:file(File, [debug_info]),
+ code:purge(M),
+ AbsFile = filename:rootname(File, ".erl"),
+ code:load_abs(AbsFile, M),
+ filename:join(PrivDir, File)
+ after file:set_cwd(Dir)
+ end.
+
+lsfiles() ->
+ {ok, CWD} = file:get_cwd(),
+ lsfiles(CWD).
+
+lsfiles(Dir) ->
+ {ok, Files} = file:list_dir(Dir),
+ Files.
+
+files(Files, Ext) ->
+ lists:filter(fun(File) ->
+ case filename:extension(File) of
+ Ext -> true;
+ _ -> false
+ end
+ end,
+ Files).
+
+remove([File|Files]) ->
+ ok = file:delete(File),
+ remove(Files);
+remove([]) ->
+ ok.
+
+decompile([Mod|Mods]) ->
+ code:purge(Mod),
+ code:delete(Mod),
+ decompile(Mods);
+decompile([]) ->
+ ok.
+
+is_unloaded(What) ->
+ if
+ is_list(What) -> true;
+ What==non_existing -> true;
+ true -> false
+ end.
+
+check_f_calls(F1,F2) ->
+ {ok,[{{f,f1,0},F1},{{f,f2,0},F2}]} = cover:analyse(f,calls,function).
diff --git a/lib/tools/test/cover_SUITE_data/a.erl b/lib/tools/test/cover_SUITE_data/a.erl
new file mode 100644
index 0000000000..31119821cd
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/a.erl
@@ -0,0 +1,55 @@
+-module(a).
+-export([start/1, stop/1]).
+-export([pong/1]).
+-export([loop/3,exit_kalle/0]).
+
+%% start(N) -> pid()
+%% N = integer()
+start(N) ->
+ Pong = b:start(),
+ spawn(?MODULE, loop, [self(), N, Pong]),
+ receive
+ done ->
+ {exit,kalle} = trycatch(fun ?MODULE:exit_kalle/0),
+ {throw,kalle} = trycatch(fun() -> throw(kalle) end),
+ done
+ end.
+
+%% stop(Ping) -> stop
+%% Ping = pid()
+stop(Ping) ->
+ Ping ! stop.
+
+%% pong(Ping) -> pong
+%% Ping = pid()
+pong(Ping) ->
+ Ping ! pong.
+
+%%--Internal functions------------------------------------------------
+
+loop(Starter, N, Pong) when N>0 ->
+ Pong ! {ping, self()},
+ receive
+ pong ->
+ loop(Starter, N-1, Pong);
+ stop ->
+ done
+ end;
+loop(Starter, 0, Pong) ->
+ Pong ! stop,
+ Starter ! done.
+
+
+trycatch(Fun) ->
+ try Fun()
+ catch
+ Throw ->
+ {throw,Throw};
+ exit:Reason ->
+ {exit,Reason}
+ after
+ cleanup
+ end.
+
+exit_kalle() ->
+ exit(kalle).
diff --git a/lib/tools/test/cover_SUITE_data/b.erl b/lib/tools/test/cover_SUITE_data/b.erl
new file mode 100644
index 0000000000..13f39b8cb9
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/b.erl
@@ -0,0 +1,14 @@
+-module(b).
+-export([start/0, loop/0]).
+
+start() ->
+ spawn(?MODULE, loop, []).
+
+loop() ->
+ receive
+ {ping, Ping} ->
+ a:pong(Ping),
+ loop();
+ stop ->
+ done
+ end.
diff --git a/lib/tools/test/cover_SUITE_data/cc.erl b/lib/tools/test/cover_SUITE_data/cc.erl
new file mode 100644
index 0000000000..587bdbe493
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/cc.erl
@@ -0,0 +1,88 @@
+-module(cc).
+-export([epp/1, epp/2, dbg/1, dbg/2, cvr/1, cvr/2]).
+-export([p/2, pp/2]).
+
+%% epp(Module) - Creates Module.epp which contains all forms of Module
+%% as obtained by using epp.
+%%
+%% dbg(Module) - Creates Module.dbg which contains all forms of Module
+%% as obtained by using beam_lib:chunks/2.
+%%
+%% cvr(Module) - Creates Module.cvr which contains all forms of Module
+%% as obtained by using cover:transform/3.
+%%
+
+epp(Module) ->
+ epp(Module, p).
+epp(Module, P) ->
+ File = atom_to_list(Module)++".erl",
+ {ok,Cwd} = file:get_cwd(),
+ {ok, Fd1} = epp:open(File, [Cwd], []),
+ {ok, Fd2} = file:open(atom_to_list(Module)++".epp", write),
+
+ epp(Fd1, Fd2, P),
+
+ epp:close(Fd1),
+ file:close(Fd2),
+ ok.
+
+epp(Fd1, Fd2, P) ->
+ case epp:parse_erl_form(Fd1) of
+ {ok, {attribute,Line,Attr,Data}} ->
+ epp(Fd1, Fd2, P);
+ {ok, Form} when P==p ->
+ io:format(Fd2, "~p.~n", [Form]),
+ epp(Fd1, Fd2, P);
+ {ok, Form} when P==pp ->
+ io:format(Fd2, "~p.~n", [erl_pp:form(Form)]),
+ epp(Fd1, Fd2, P);
+ {eof, Line} ->
+ ok
+ end.
+
+cvr(Module) ->
+ cvr(Module, p).
+cvr(Module, P) ->
+ case beam_lib:chunks(Module, [abstract_code]) of
+ {ok, {Module, [{abstract_code, no_abstract_code}]}} ->
+ {error, {no_debug_info,Module}};
+ {ok, {Module, [{abstract_code, {Vsn, Forms}}]}} ->
+ Vars = {vars,Module,Vsn, [],
+ undefined, undefined, undefined, undefined, undefined,
+ undefined,
+ false},
+ {ok, TForms, _Vars2} = cover:transform(Forms, [], Vars),
+ File = atom_to_list(Module)++".cvr",
+ apply(?MODULE, P, [File, TForms]);
+ Error ->
+ Error
+ end.
+
+dbg(Module) ->
+ dbg(Module, p).
+dbg(Module, P) ->
+ case beam_lib:chunks(Module, [abstract_code]) of
+ {ok, {Module, [{abstract_code, no_abstract_code}]}} ->
+ {error, {no_debug_info,Module}};
+ {ok, {Module, [{abstract_code, {Vsn, Forms}}]}} ->
+ File = atom_to_list(Module)++".dbg",
+ apply(?MODULE, P, [File, Forms]);
+ Error ->
+ Error
+ end.
+
+p(File, Forms) ->
+ {ok, Fd} = file:open(File, write),
+ lists:foreach(fun(Form) ->
+ io:format(Fd, "~p.~n", [Form])
+ end,
+ Forms),
+ file:close(Fd).
+
+pp(File, Forms) ->
+ {ok, Fd} = file:open(File, write),
+ lists:foreach(fun(Form) ->
+ io:format(Fd, "~s", [erl_pp:form(Form)])
+ end,
+ Forms),
+ file:close(Fd).
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/crypt.erl b/lib/tools/test/cover_SUITE_data/compile_beam/crypt.erl
new file mode 100644
index 0000000000..1596777edf
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/crypt.erl
@@ -0,0 +1,6 @@
+-module(crypt).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/d/y.erl b/lib/tools/test/cover_SUITE_data/compile_beam/d/y.erl
new file mode 100644
index 0000000000..14b9461410
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/d/y.erl
@@ -0,0 +1,6 @@
+-module(y).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/v.erl b/lib/tools/test/cover_SUITE_data/compile_beam/v.erl
new file mode 100644
index 0000000000..007957297a
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/v.erl
@@ -0,0 +1,6 @@
+-module(v).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/w.erl b/lib/tools/test/cover_SUITE_data/compile_beam/w.erl
new file mode 100644
index 0000000000..88ad606db8
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/w.erl
@@ -0,0 +1,6 @@
+-module(w).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/x.erl b/lib/tools/test/cover_SUITE_data/compile_beam/x.erl
new file mode 100644
index 0000000000..8953f6d05d
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/x.erl
@@ -0,0 +1,6 @@
+-module(x).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/d.erl b/lib/tools/test/cover_SUITE_data/d.erl
new file mode 100644
index 0000000000..696e27e49b
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/d.erl
@@ -0,0 +1,156 @@
+-module(d).
+
+-export([start/0, stop/0]).
+-export([store/2, store/3, move/2,
+ location/1, who_are_at/1, who_are_older/1,
+ size/0]).
+-export([init/0]). % spawn
+
+-record(person, {name, age, location, moved=false}).
+
+%%%----------------------------------------------------------------------
+%%% User interface functions
+%%%----------------------------------------------------------------------
+
+%%% start() -> pid()
+start() ->
+ spawn(?MODULE, init, []).
+
+%%% stop()
+stop() ->
+ arne ! stop.
+
+%%% store(Name, Location) ->
+%%% store(Name, Age, Location) -> ok | {error,Reason}
+%%% Name = Location = atom()
+%%% Age = integer()
+%%% Reason = not_started | no_response | {internal_error,term()}
+store(Name, Location) ->
+ store(Name, ?AGE, Location).
+store(Name, Age, Location) when atom(Name), integer(Age), atom(Location) ->
+ send({store, Name, Age, Location}).
+
+%%% move(OldLocation, NewLocation) -> Names | {error,Reason}
+%%% OldLocation = NewLocation = atom()
+%%% Names = [Name]
+%%% Name = atom()
+%%% Reason = not_started | no_response | {internal_error,term()}
+move(OldLocation, NewLocation) ->
+ send({move, OldLocation, NewLocation}).
+
+%%% location(Name) -> Location | no_such_person | {error,Reason}
+%%% Name = atom()
+%%% Reason = not_started | no_response | {internal_error,term()}
+location(Name) when atom(Name) ->
+ send({location, Name}).
+
+%%% who_are_at(Location) -> Names | {error,Reason}
+%%% Location = atom()
+%%% Names = [Name]
+%%% Name = atom()
+%%% Reason = not_started | no_response | {internal_error,term()}
+who_are_at(Location) when atom(Location) ->
+ send({who_are_at, Location}).
+
+%%% who_are_older(Age) -> Names | {error,Reason}
+%%% Age = integer()
+%%% Names = [Name]
+%%% Name = atom()
+%%% Reason = not_started | no_response | {internal_error,term()}
+who_are_older(Age) when integer(Age) ->
+ send({who_are_older, Age}).
+
+%%% size() -> N | {error,Reason}
+%%% N = integer()
+%%% Reason = not_started | no_response | {internal_error,term()}
+size() ->
+ send(size).
+
+%%%----------------------------------------------------------------------
+%%% Main loop
+%%%----------------------------------------------------------------------
+send(Request) ->
+ Pid = whereis(arne),
+ if
+ Pid==undefined ->
+ {error, not_started};
+ true ->
+ send(Pid, Request)
+ end.
+send(Pid, Request) ->
+ Pid ! {request, self(), Request},
+ receive
+ {reply, Reply} ->
+ Reply
+ after
+ 1000 ->
+ {error, no_response}
+ end.
+
+init() ->
+ register(arne, self()),
+ loop([]).
+
+loop(Db) ->
+ receive
+ stop ->
+ true;
+ {request, From, Request} ->
+ case catch handle(Request, Db) of
+ {reply, Reply, NewDb} ->
+ From ! {reply, Reply},
+ loop(NewDb);
+ {'EXIT', Reason} ->
+ From ! {reply, {error, {internal_error, Reason}}},
+ loop(Db)
+ end
+ end.
+
+%%%----------------------------------------------------------------------
+%%% DB functionality
+%%%----------------------------------------------------------------------
+handle({store, Name, Age, Location}, Db) ->
+ {reply, ok, [#person{name=Name, age=Age, location=Location} | Db]};
+handle({move, OldLocation, NewLocation}, Db) ->
+ {Names, NewDb} = move(OldLocation, NewLocation, Db, [], []),
+ {reply, Names, NewDb};
+handle({location, Name}, Db) ->
+ case lists:keysearch(Name, #person.name, Db) of
+ {value, #person{location=Location}} when atom(Location) ->
+ {reply, Location, Db};
+ false ->
+ {reply, no_such_name, Db}
+ end;
+handle({who_are_at, Location}, Db) ->
+ Result = lists:foldl(fun(Person, Names) ->
+ case Person#person.location of
+ Location ->
+ [Person#person.name | Names];
+ _OtherLocation ->
+ Names
+ end
+ end,
+ [],
+ Db),
+ {reply, Result, Db};
+handle({who_are_older, Old}, Db) ->
+ Result = [Name || {person,Name,Age,Location} <- Db,
+ Age>Old],
+ {reply, Result, Db};
+handle(size, Db) ->
+ Result = count(Db, 0), {reply, Result, Db}.
+
+count([H|T], N) ->
+ count(T, N+1);
+count([], N) ->
+ N.
+
+move(OldLoc, NewLoc, [#person{location=OldLoc} = Person|T], Db, Names) ->
+ NewPerson = Person#person{location=NewLoc,
+ moved=true},
+ NewNames = [Person#person.name|Names],
+ move(OldLoc, NewLoc, T, [NewPerson|Db], NewNames);
+move(OldLoc, NewLoc, [Person|T], Db, Names) ->
+ move(OldLoc, NewLoc, T, [Person|Db], Names);
+move(OldLoc, NewLoc, [], Db, Names) ->
+ {lists:reverse(Names), lists:reverse(Db)}.
diff --git a/lib/tools/test/cover_SUITE_data/d1/e.erl b/lib/tools/test/cover_SUITE_data/d1/e.erl
new file mode 100644
index 0000000000..b4041d48e6
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/d1/e.erl
@@ -0,0 +1,127 @@
+-module(e).
+-behaviour(gen_server).
+
+%% External exports
+-export([start_link/0]).
+-export([hello/0]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
+ code_change/3]).
+
+-record(state, {}).
+
+%%%----------------------------------------------------------------------
+%%% API
+%%%----------------------------------------------------------------------
+start_link() ->
+ gen_server:start_link({local, myserver}, myserver, [], []).
+
+hello() ->
+ gen_server:call(myserver, hello).
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+init([]) ->
+ {ok, #state{}}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+handle_call(Request, From, State) ->
+ Reply = case Request of
+ char ->
+ $B;
+ integer ->
+ 17;
+ float ->
+ 32.76;
+ string ->
+ "hi there";
+ atom ->
+ hello;
+ block ->
+ begin
+ a,
+ b
+ end;
+ binary ->
+ <<1, 2, 3>>
+ end,
+ {reply, Reply, State}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+handle_cast(Msg, State) when atom(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when binary(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when not is_tuple(Msg), not is_list(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when float(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when function(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when integer(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when list(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when number(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when pid(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when port(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when reference(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when tuple(Msg) ->
+ {noreply, State}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+handle_info(Info, State) ->
+ {noreply, State}.
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%----------------------------------------------------------------------
+terminate(Reason, State) ->
+ ok.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Convert process state when code is changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+code_change(OldVsn, State, Extra) ->
+ {ok, State}.
+
+%%%----------------------------------------------------------------------
+%%% Internal functions
+%%%----------------------------------------------------------------------
+
diff --git a/lib/tools/test/cover_SUITE_data/f.erl b/lib/tools/test/cover_SUITE_data/f.erl
new file mode 100644
index 0000000000..1ef8bbdb49
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/f.erl
@@ -0,0 +1,10 @@
+-module(f).
+-export([f1/0,f2/0]).
+
+f1() ->
+ f1_line1,
+ f1_line2.
+
+f2() ->
+ f2_line1,
+ f2_line2.
diff --git a/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.erl b/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.erl
new file mode 100644
index 0000000000..fa8eebfd00
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.erl
@@ -0,0 +1,8 @@
+-module(cover_inc).
+-compile(export_all).
+-include("cover_inc.hrl").
+
+func() ->
+ func1(),
+ ok.
+
diff --git a/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.hrl b/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.hrl
new file mode 100644
index 0000000000..cbdfe601d1
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.hrl
@@ -0,0 +1,7 @@
+func1() ->
+ A = line_2_in_include_file,
+ erlang:display(A),
+ line_4_in_include_file.
+
+
+
diff --git a/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl b/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl
new file mode 100644
index 0000000000..b659e5d818
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl
@@ -0,0 +1,12 @@
+-module(f1).
+-export([start_fail/0, start_ok/0]).
+
+start_fail() ->
+ f2:start(fun() ->
+ io:format("this does not work\n",[])
+ end).
+
+start_ok() ->
+ f2:start(fun fun1/0).
+fun1() ->
+ io:format("this works\n",[]).
diff --git a/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl b/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl
new file mode 100644
index 0000000000..72a6a64c4d
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl
@@ -0,0 +1,13 @@
+-module(f2).
+-export([start/1]).
+
+start(Fun) ->
+ spawn(fun() ->
+ wait(Fun)
+ end).
+
+wait(Fun) ->
+ receive
+ go ->
+ Fun()
+ end.
diff --git a/lib/tools/test/cprof_SUITE.erl b/lib/tools/test/cprof_SUITE.erl
new file mode 100644
index 0000000000..e697cc1571
--- /dev/null
+++ b/lib/tools/test/cprof_SUITE.erl
@@ -0,0 +1,309 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% Define to run outside of test server
+%%%
+%%% -define(STANDALONE,1).
+%%%
+%%%
+%%% Define for debug output
+%%%
+%%% -define(debug,1).
+
+-module(cprof_SUITE).
+
+%% Exported end user tests
+-export([basic_test/0, on_load_test/1, modules_test/1]).
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Test server related stuff
+%%
+
+-ifdef(STANDALONE).
+-define(config(A,B),config(A,B)).
+-export([config/2]).
+-else.
+-include("test_server.hrl").
+-endif.
+
+-ifdef(debug).
+-ifdef(STANDALONE).
+-define(line, erlang:display({?MODULE,?LINE}), ).
+-endif.
+-define(dbgformat(A,B),io:format(A,B)).
+-else.
+-ifdef(STANDALONE).
+-define(line, noop, ).
+-endif.
+-define(dbgformat(A,B),noop).
+-endif.
+
+-ifdef(STANDALONE).
+config(priv_dir, _) ->
+ ".";
+config(data_dir, _) ->
+ "cprof_SUITE_data".
+-else.
+%% When run in test server.
+-export([all/1, init_per_testcase/2, fin_per_testcase/2, not_run/1]).
+-export([basic/1, on_load/1, modules/1]).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(test_server:seconds(30)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ erlang:trace_pattern({'_','_','_'}, false, [local,meta,call_count]),
+ erlang:trace_pattern(on_load, false, [local,meta,call_count]),
+ erlang:trace(all, false, [all]),
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(doc) ->
+ ["Test the cprof profiling tool."];
+all(suite) ->
+ case test_server:is_native(?MODULE) of
+ true -> [not_run];
+ false -> [basic, on_load, modules]
+%, on_and_off, info,
+% pause_and_restart, combo]
+ end.
+
+not_run(Config) when is_list(Config) ->
+ {skipped,"Native code"}.
+
+basic(suite) ->
+ [];
+basic(doc) ->
+ ["Tests basic profiling"];
+basic(Config) when is_list(Config) ->
+ basic_test().
+
+on_load(suite) ->
+ [];
+on_load(doc) ->
+ ["Tests profiling of unloaded module"];
+on_load(Config) when is_list(Config) ->
+ on_load_test(Config).
+
+modules(suite) ->
+ [];
+modules(doc) ->
+ ["Tests profiling of several modules"];
+modules(Config) when is_list(Config) ->
+ modules_test(Config).
+
+-endif. %-ifdef(STANDALONE). ... -else.
+
+%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% The Tests
+%%%
+
+basic_test() ->
+ ?line M = 1000,
+ %%
+ ?line M2 = M*2,
+ ?line M3 = M*3,
+ ?line M2__1 = M2 + 1,
+ ?line M3__1 = M3 + 1,
+ ?line N = cprof:stop(),
+ %%
+ ?line 2 = cprof:start(?MODULE, seq_r),
+ ?line 1 = cprof:start(?MODULE, seq, 3),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ ?line L = lists:reverse(Lr),
+ %%
+ ?line io:format("~p~n~p~n~p~n",
+ [erlang:trace_info({?MODULE,sec_r,3}, all),
+ erlang:trace_info({?MODULE,sec_r,4}, all),
+ erlang:trace_info({?MODULE,sec,3}, all)]),
+ %%
+ ?line ModAna1 = {?MODULE,M2__1,[{{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M},
+ {{?MODULE,seq_r,3},1}]},
+ ?line ModAna1 = cprof:analyse(?MODULE,0),
+ ?line {M2__1, [ModAna1]} = cprof:analyse(),
+ ?line ModAna1 = cprof:analyse(?MODULE, 1),
+ ?line {M2__1, [ModAna1]} = cprof:analyse(1),
+ %%
+ ?line ModAna2 = {?MODULE,M2__1,[{{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M}]},
+ ?line ModAna2 = cprof:analyse(?MODULE, 2),
+ ?line {M2__1, [ModAna2]} = cprof:analyse(2),
+ %%
+ 2 = cprof:pause(?MODULE, seq_r),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ %%
+ ?line ModAna3 = {?MODULE,M3__1,[{{?MODULE,seq,3},M2},
+ {{?MODULE,seq_r,4},M},
+ {{?MODULE,seq_r,3},1}]},
+ ?line ModAna3 = cprof:analyse(?MODULE),
+ %%
+ ?line N = cprof:pause(),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ %%
+ ?line {M3__1, [ModAna3]} = cprof:analyse(),
+ %%
+ ?line N = cprof:restart(),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ %%
+ ?line ModAna1 = cprof:analyse(?MODULE),
+ %%
+ ?line N = cprof:stop(),
+ ?line {?MODULE,0,[]} = cprof:analyse(?MODULE),
+ ?line {0,[]} = cprof:analyse(),
+ ok.
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+on_load_test(Config) ->
+ ?line Priv = ?config(priv_dir, Config),
+ ?line Data = ?config(data_dir, Config),
+ ?line File = filename:join(Data, "cprof_SUITE_test"),
+ ?line Module = cprof_SUITE_test,
+ ?line M = 1000,
+ %%
+ ?line M2 = M*2,
+ ?line M2__1 = M2 + 1,
+ ?line N1 = cprof:start(),
+
+ ?line {ok,Module} = c:c(File, [{outdir,Priv}]),
+
+ %% If this system is hipe-enabled, the loader may have called module_info/1
+ %% when Module was loaded above. Reset the call count to avoid seeing
+ %% the call in the analysis below.
+
+ ?line 1 = cprof:restart(Module, module_info, 1),
+
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line Lr = lists:reverse(L),
+ ?line N2 = cprof:pause(),
+ ?line N3 = cprof:pause(Module),
+ ?line {Module,M2__1,[{{Module,seq_r,4},M},
+ {{Module,seq,3},M},
+ {{Module,seq_r,3},1}]} = cprof:analyse(Module),
+ ?line io:format("~p ~p ~p~n", [N1, N2, N3]),
+ ?line code:purge(Module),
+ ?line code:delete(Module),
+ ?line N4 = N2 - N3,
+ %%
+ ?line N4 = cprof:restart(),
+ ?line {ok,Module} = c:c(File, [{outdir,Priv}]),
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ ?line N2 = cprof:pause(),
+ ?line {Module,0,[]} = cprof:analyse(Module),
+ ?line M_1 = M - 1,
+ ?line M4__4 = M*4 - 4,
+ ?line M10_7 = M*10 - 7,
+ ?line {?MODULE,M10_7,[{{?MODULE,succ,1},M4__4},
+ {{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M},
+ {{?MODULE,'-on_load_test/1-fun-5-',1},M_1},
+ {{?MODULE,'-on_load_test/1-fun-4-',1},M_1},
+ {{?MODULE,'-on_load_test/1-fun-3-',1},M_1},
+ {{?MODULE,'-on_load_test/1-fun-2-',1},M_1},
+ {{?MODULE,seq_r,3},1}]}
+ = cprof:analyse(?MODULE),
+ ?line N2 = cprof:stop(),
+ ok.
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+modules_test(Config) ->
+ ?line Priv = ?config(priv_dir, Config),
+ ?line Data = ?config(data_dir, Config),
+ ?line File = filename:join(Data, "cprof_SUITE_test"),
+ ?line Module = cprof_SUITE_test,
+ ?line {ok,Module} = c:c(File, [{outdir,Priv}]),
+ ?line M = 10,
+ %%
+ ?line M2 = M*2,
+ ?line M2__1 = M2 + 1,
+ ?line erlang:yield(),
+ ?line N = cprof:start(),
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ ?line N = cprof:pause(),
+ ?line Lr = lists:reverse(L),
+ ?line M_1 = M - 1,
+ ?line M4_4 = M*4 - 4,
+ ?line M10_7 = M*10 - 7,
+ ?line M2__1 = M*2 + 1,
+ ?line {Tot,ModList} = cprof:analyse(),
+ ?line {value,{?MODULE,M10_7,[{{?MODULE,succ,1},M4_4},
+ {{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M},
+ {{?MODULE,'-modules_test/1-fun-3-',1},M_1},
+ {{?MODULE,'-modules_test/1-fun-2-',1},M_1},
+ {{?MODULE,'-modules_test/1-fun-1-',1},M_1},
+ {{?MODULE,'-modules_test/1-fun-0-',1},M_1},
+ {{?MODULE,seq_r,3},1}]}} =
+ lists:keysearch(?MODULE, 1, ModList),
+ ?line {value,{Module,M2__1,[{{Module,seq_r,4},M},
+ {{Module,seq,3},M},
+ {{Module,seq_r,3},1}]}} =
+ lists:keysearch(Module, 1, ModList),
+ ?line Tot = lists:foldl(fun ({_,C,_}, A) -> C+A end, 0, ModList),
+ ?line {cprof,_,Prof} = cprof:analyse(cprof),
+ ?line {value,{{cprof,pause,0},1}} =
+ lists:keysearch({cprof,pause,0}, 1, Prof),
+ ?line N = cprof:stop(),
+ ok.
+
+
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Local helpers
+
+
+
+%% Stack recursive seq
+seq(Stop, Stop, Succ) when is_function(Succ) ->
+ [Stop];
+seq(Start, Stop, Succ) when is_function(Succ) ->
+ [Start | seq(Succ(Start), Stop, Succ)].
+
+
+
+%% Tail recursive seq, result list is reversed
+seq_r(Start, Stop, Succ) when is_function(Succ) ->
+ seq_r(Start, Stop, Succ, []).
+
+seq_r(Stop, Stop, _, R) ->
+ [Stop | R];
+seq_r(Start, Stop, Succ, R) ->
+ seq_r(Succ(Start), Stop, Succ, [Start | R]).
+
+
+
+%% Successor
+succ(X) -> X+1.
diff --git a/lib/tools/test/cprof_SUITE_data/cprof_SUITE_test.erl b/lib/tools/test/cprof_SUITE_data/cprof_SUITE_test.erl
new file mode 100644
index 0000000000..02d8b027e5
--- /dev/null
+++ b/lib/tools/test/cprof_SUITE_data/cprof_SUITE_test.erl
@@ -0,0 +1,25 @@
+-module(cprof_SUITE_test).
+
+-export([seq/3, seq_r/3]).
+
+
+
+%% Stack recursive seq
+seq(Stop, Stop, Succ) when function(Succ) ->
+ [Stop];
+seq(Start, Stop, Succ) when function(Succ) ->
+ [Start | seq(Succ(Start), Stop, Succ)].
+
+
+
+%% Tail recursive seq, result list is reversed
+seq_r(Start, Stop, Succ) when function(Succ) ->
+ seq_r(Start, Stop, Succ, []).
+
+seq_r(Stop, Stop, _, R) ->
+ [Stop | R];
+seq_r(Start, Stop, Succ, R) ->
+ seq_r(Succ(Start), Stop, Succ, [Start | R]).
+
+
+
diff --git a/lib/tools/test/emem_SUITE.erl b/lib/tools/test/emem_SUITE.erl
new file mode 100644
index 0000000000..430fa86c6c
--- /dev/null
+++ b/lib/tools/test/emem_SUITE.erl
@@ -0,0 +1,713 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(emem_SUITE).
+
+%%-define(line_trace, 1).
+
+-export([init_per_suite/1, end_per_suite/1,
+ receive_and_save_trace/2, send_trace/2]).
+
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+
+-export([live_node/1,
+ 'sparc_sunos5.8_32b_emt2.0'/1,
+ 'pc_win2000_32b_emt2.0'/1,
+ 'pc.smp_linux2.2.19pre17_32b_emt2.0'/1,
+ 'powerpc_darwin7.7.0_32b_emt2.0'/1,
+ 'alpha_osf1v5.1_64b_emt2.0'/1,
+ 'sparc_sunos5.8_64b_emt2.0'/1,
+ 'sparc_sunos5.8_32b_emt1.0'/1,
+ 'pc_win2000_32b_emt1.0'/1,
+ 'powerpc_darwin7.7.0_32b_emt1.0'/1,
+ 'alpha_osf1v5.1_64b_emt1.0'/1,
+ 'sparc_sunos5.8_64b_emt1.0'/1]).
+
+-include_lib("kernel/include/file.hrl").
+
+-include("test_server.hrl").
+
+-define(DEFAULT_TIMEOUT, ?t:minutes(5)).
+
+-define(EMEM_64_32_COMMENT,
+ "64 bit trace; this build of emem can only handle 32 bit traces").
+
+-record(emem_res, {nodename,
+ hostname,
+ pid,
+ start_time,
+ trace_version,
+ max_word_size,
+ word_size,
+ last_values,
+ maximum,
+ exit_code}).
+
+%%
+%%
+%% Exported suite functions
+%%
+%%
+
+all(doc) -> [];
+all(suite) ->
+ case is_debug_compiled() of
+ true -> {skipped, "Not run when debug compiled"};
+ false -> test_cases()
+ end.
+
+test_cases() ->
+ [live_node,
+ 'sparc_sunos5.8_32b_emt2.0',
+ 'pc_win2000_32b_emt2.0',
+ 'pc.smp_linux2.2.19pre17_32b_emt2.0',
+ 'powerpc_darwin7.7.0_32b_emt2.0',
+ 'alpha_osf1v5.1_64b_emt2.0',
+ 'sparc_sunos5.8_64b_emt2.0',
+ 'sparc_sunos5.8_32b_emt1.0',
+ 'pc_win2000_32b_emt1.0',
+ 'powerpc_darwin7.7.0_32b_emt1.0',
+ 'alpha_osf1v5.1_64b_emt1.0',
+ 'sparc_sunos5.8_64b_emt1.0'].
+
+init_per_testcase(Case, Config) when is_list(Config) ->
+ case maybe_skip(Config) of
+ {skip, _}=Skip -> Skip;
+ ok ->
+ Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
+
+ %% Until emem is completely stable we run these tests in a working
+ %% directory with an ignore_core_files file which will make the
+ %% search for core files ignore cores generated by this suite.
+ ignore_cores:setup(?MODULE,
+ Case,
+ [{watchdog, Dog}, {testcase, Case} | Config])
+ end.
+
+fin_per_testcase(_Case, Config) when is_list(Config) ->
+ ignore_cores:restore(Config),
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+maybe_skip(Config) ->
+ DataDir = ?config(data_dir, Config),
+ case filelib:is_dir(DataDir) of
+ false ->
+ {skip, "No data directory"};
+ true ->
+ case ?config(emem, Config) of
+ undefined ->
+ {skip, "emem not found"};
+ _ ->
+ ok
+ end
+ end.
+
+init_per_suite(Config) when is_list(Config) ->
+ BinDir = filename:join([code:lib_dir(tools), "bin"]),
+ Target = erlang:system_info(system_architecture),
+ Res = (catch begin
+ case check_dir(filename:join([BinDir, Target])) of
+ not_found -> ok;
+ TDir ->
+ check_emem(TDir, purecov),
+ check_emem(TDir, purify),
+ check_emem(TDir, debug),
+ check_emem(TDir, opt)
+ end,
+ check_emem(BinDir, opt),
+ ""
+ end),
+ Res ++ ignore_cores:init(Config).
+
+end_per_suite(Config) when is_list(Config) ->
+ Config1 = lists:keydelete(emem, 1, Config),
+ Config2 = lists:keydelete(emem_comment, 1, Config1),
+ ignore_cores:fini(Config2).
+
+%%
+%%
+%% Test cases
+%%
+%%
+
+live_node(doc) -> [];
+live_node(suite) -> [];
+live_node(Config) when is_list(Config) ->
+ ?line {ok, EmuFlag, Port} = start_emem(Config),
+ ?line Nodename = mk_nodename(Config),
+ ?line {ok, Node} = start_node(Nodename, EmuFlag),
+ ?line NP = spawn(Node,
+ fun () ->
+ receive go -> ok end,
+ I = spawn(fun () -> ignorer end),
+ GC = fun () ->
+ GCP = fun (P) ->
+ garbage_collect(P)
+ end,
+ lists:foreach(GCP, processes())
+ end,
+ Seq = fun () -> I ! lists:seq(1, 1000000) end,
+ spawn_link(Seq),
+ B1 = <<0:10000000>>,
+ spawn_link(Seq),
+ B2 = <<0:10000000>>,
+ spawn_link(Seq),
+ B3 = <<0:10000000>>,
+ I ! {B1, B2, B3},
+ GC(),
+ GC(),
+ GC()
+ end),
+ ?line MRef = erlang:monitor(process, NP),
+ NP ! go,
+ ?line receive
+ {'DOWN', MRef, process, NP, Reason} ->
+ ?line spawn(Node, fun () -> halt(17) end),
+ ?line normal = Reason
+ end,
+ ?line Res = get_emem_result(Port),
+ ?line {ok, Hostname} = inet:gethostname(),
+ ?line ShortHostname = short_hostname(Hostname),
+ ?line {true, _} = has_prefix(Nodename, Res#emem_res.nodename),
+ ?line ShortHostname = short_hostname(Res#emem_res.hostname),
+ ?line Bits = case erlang:system_info(wordsize) of
+ 4 -> ?line "32 bits";
+ 8 -> ?line "64 bits"
+ end,
+ ?line Bits = Res#emem_res.word_size,
+ ?line "17" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'sparc_sunos5.8_32b_emt2.0'(doc) -> [];
+'sparc_sunos5.8_32b_emt2.0'(suite) -> [];
+'sparc_sunos5.8_32b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "gorbag" = Res#emem_res.hostname,
+ ?line "17074" = Res#emem_res.pid,
+ ?line "2005-01-14 17:28:37.881980" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["15",
+ "2665739", "8992", "548986", "16131", "539994",
+ "4334192", "1", "99", "15", "98",
+ "0", "0", "49", "0", "49"] = Res#emem_res.last_values,
+ ?line ["5972061", "9662",
+ "7987824", "5",
+ "2375680", "3"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'pc_win2000_32b_emt2.0'(doc) -> [];
+'pc_win2000_32b_emt2.0'(suite) -> [];
+'pc_win2000_32b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "E-788FCF5191B54" = Res#emem_res.hostname,
+ ?line "504" = Res#emem_res.pid,
+ ?line "2005-01-24 17:27:28.224000" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["11",
+ "2932575", "8615", "641087", "68924", "632472"]
+ = Res#emem_res.last_values,
+ ?line ["5434206", "9285"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'pc.smp_linux2.2.19pre17_32b_emt2.0'(doc) -> [];
+'pc.smp_linux2.2.19pre17_32b_emt2.0'(suite) -> [];
+'pc.smp_linux2.2.19pre17_32b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "four-roses" = Res#emem_res.hostname,
+ ?line "20689" = Res#emem_res.pid,
+ ?line "2005-01-20 13:11:26.143077" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["49",
+ "2901817", "9011", "521610", "10875", "512599",
+ "5392096", "2", "120", "10", "118",
+ "0", "0", "59", "0", "59"] = Res#emem_res.last_values,
+ ?line ["6182918", "9681",
+ "9062112", "6",
+ "2322432", "3"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+
+'powerpc_darwin7.7.0_32b_emt2.0'(doc) -> [];
+'powerpc_darwin7.7.0_32b_emt2.0'(suite) -> [];
+'powerpc_darwin7.7.0_32b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "grima" = Res#emem_res.hostname,
+ ?line "13021" = Res#emem_res.pid,
+ ?line "2005-01-20 15:08:17.568668" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["9",
+ "2784323", "8641", "531105", "15893", "522464"]
+ = Res#emem_res.last_values,
+ ?line ["6150376", "9311"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'alpha_osf1v5.1_64b_emt2.0'(doc) -> [];
+'alpha_osf1v5.1_64b_emt2.0'(suite) -> [];
+'alpha_osf1v5.1_64b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "thorin" = Res#emem_res.hostname,
+ ?line "224630" = Res#emem_res.pid,
+ ?line "2005-01-20 22:38:01.299632" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "64 bits" = Res#emem_res.word_size,
+ ?line case Res#emem_res.max_word_size of
+ "32 bits" ->
+ ?line emem_comment(Config, ?EMEM_64_32_COMMENT);
+ "64 bits" ->
+ ?line ["22",
+ "6591992", "8625", "516785", "14805", "508160",
+ "11429184", "5", "127", "254", "122",
+ "0", "0", "61", "0", "61"] = Res#emem_res.last_values,
+ ?line ["7041775", "9295",
+ "11593024", "7",
+ "2097152", "3"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config)
+ end.
+
+'sparc_sunos5.8_64b_emt2.0'(doc) -> [];
+'sparc_sunos5.8_64b_emt2.0'(suite) -> [];
+'sparc_sunos5.8_64b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "gorbag" = Res#emem_res.hostname,
+ ?line "10907" = Res#emem_res.pid,
+ ?line "2005-01-20 13:48:34.677068" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "64 bits" = Res#emem_res.word_size,
+ ?line case Res#emem_res.max_word_size of
+ "32 bits" ->
+ ?line emem_comment(Config, ?EMEM_64_32_COMMENT);
+ "64 bits" ->
+ ?line ["16",
+ "5032887", "8657", "530635", "14316", "521978",
+ "8627140", "5", "139", "19", "134",
+ "0", "0", "67", "0", "67"] = Res#emem_res.last_values,
+ ?line ["11695070", "9324",
+ "16360388", "10",
+ "4136960", "3"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config)
+ end.
+
+'sparc_sunos5.8_32b_emt1.0'(doc) -> [];
+'sparc_sunos5.8_32b_emt1.0'(suite) -> [];
+'sparc_sunos5.8_32b_emt1.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "" = Res#emem_res.nodename,
+ ?line "" = Res#emem_res.hostname,
+ ?line "" = Res#emem_res.pid,
+ ?line "" = Res#emem_res.start_time,
+ ?line "1.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["11",
+ "2558261", "8643", "560610", "15325", "551967"]
+ = Res#emem_res.last_values,
+ ?line ["2791121", "9317"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'pc_win2000_32b_emt1.0'(doc) -> [];
+'pc_win2000_32b_emt1.0'(suite) -> [];
+'pc_win2000_32b_emt1.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "" = Res#emem_res.nodename,
+ ?line "" = Res#emem_res.hostname,
+ ?line "" = Res#emem_res.pid,
+ ?line "" = Res#emem_res.start_time,
+ ?line "1.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["6",
+ "2965248", "8614", "640897", "68903", "632283"]
+ = Res#emem_res.last_values,
+ ?line ["3147090", "9283"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+
+'powerpc_darwin7.7.0_32b_emt1.0'(doc) -> [];
+'powerpc_darwin7.7.0_32b_emt1.0'(suite) -> [];
+'powerpc_darwin7.7.0_32b_emt1.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "" = Res#emem_res.nodename,
+ ?line "" = Res#emem_res.hostname,
+ ?line "" = Res#emem_res.pid,
+ ?line "" = Res#emem_res.start_time,
+ ?line "1.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["8",
+ "2852991", "8608", "529662", "15875", "521054"]
+ = Res#emem_res.last_values,
+ ?line ["3173335", "9278"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'alpha_osf1v5.1_64b_emt1.0'(doc) -> [];
+'alpha_osf1v5.1_64b_emt1.0'(suite) -> [];
+'alpha_osf1v5.1_64b_emt1.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "" = Res#emem_res.nodename,
+ ?line "" = Res#emem_res.hostname,
+ ?line "" = Res#emem_res.pid,
+ ?line "" = Res#emem_res.start_time,
+ ?line "1.0" = Res#emem_res.trace_version,
+ ?line "64 bits" = Res#emem_res.word_size,
+ ?line case Res#emem_res.max_word_size of
+ "32 bits" ->
+ ?line emem_comment(Config, ?EMEM_64_32_COMMENT);
+ "64 bits" ->
+ ?line ["22",
+ "6820094", "8612", "515518", "14812", "506906"]
+ = Res#emem_res.last_values,
+ ?line ["7292413", "9282"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config)
+ end.
+
+'sparc_sunos5.8_64b_emt1.0'(doc) -> [];
+'sparc_sunos5.8_64b_emt1.0'(suite) -> [];
+'sparc_sunos5.8_64b_emt1.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "" = Res#emem_res.nodename,
+ ?line "" = Res#emem_res.hostname,
+ ?line "" = Res#emem_res.pid,
+ ?line "" = Res#emem_res.start_time,
+ ?line "1.0" = Res#emem_res.trace_version,
+ ?line "64 bits" = Res#emem_res.word_size,
+ ?line case Res#emem_res.max_word_size of
+ "32 bits" ->
+ ?line emem_comment(Config, ?EMEM_64_32_COMMENT);
+ "64 bits" ->
+ ?line ["15",
+ "4965746", "8234", "543940", "14443", "535706"]
+ = Res#emem_res.last_values,
+ ?line ["11697645", "8908"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config)
+ end.
+
+%%
+%%
+%% Auxiliary functions
+%%
+%%
+
+receive_and_save_trace(PortNumber, FileName) when is_integer(PortNumber),
+ is_list(FileName) ->
+ {ok, F} = file:open(FileName, [write, compressed]),
+ {ok, LS} = gen_tcp:listen(PortNumber, [inet, {reuseaddr,true}, binary]),
+ {ok, S} = gen_tcp:accept(LS),
+ gen_tcp:close(LS),
+ receive_loop(S,F).
+
+receive_loop(Socket, File) ->
+ receive
+ {tcp, Socket, Data} ->
+ ok = file:write(File, Data),
+ receive_loop(Socket, File);
+ {tcp_closed, Socket} ->
+ file:close(File),
+ ok;
+ {tcp_error, Socket, Reason} ->
+ file:close(File),
+ {error, Reason}
+ end.
+
+send_trace({Host, PortNumber}, FileName) when is_list(Host),
+ is_integer(PortNumber),
+ is_list(FileName) ->
+ ?line {ok, F} = file:open(FileName, [read, compressed]),
+ ?line {ok, S} = gen_tcp:connect(Host, PortNumber, [inet,{packet, 0}]),
+ ?line send_loop(S, F);
+send_trace(EmuFlag, FileName) when is_list(EmuFlag),
+ is_list(FileName) ->
+ ?line ["+Mit", IpAddrStr, PortNoStr] = string:tokens(EmuFlag, " :"),
+ ?line send_trace({IpAddrStr, list_to_integer(PortNoStr)}, FileName).
+
+send_loop(Socket, File) ->
+ ?line case file:read(File, 128) of
+ {ok, Data} ->
+ ?line case gen_tcp:send(Socket, Data) of
+ ok -> ?line send_loop(Socket, File);
+ Error ->
+ ?line gen_tcp:close(Socket),
+ ?line file:close(File),
+ Error
+ end;
+ eof ->
+ ?line gen_tcp:close(Socket),
+ ?line file:close(File),
+ ?line ok;
+ Error ->
+ ?line gen_tcp:close(Socket),
+ ?line file:close(File),
+ ?line Error
+ end.
+
+check_emem(Dir, Type) when is_atom(Type) ->
+ ExeSuffix = case ?t:os_type() of
+ {win32, _} -> ".exe";
+ _ -> ""
+ end,
+ TypeSuffix = case Type of
+ opt -> "";
+ _ -> "." ++ atom_to_list(Type)
+ end,
+ Emem = "emem" ++ TypeSuffix ++ ExeSuffix,
+ case check_file(filename:join([Dir, Emem])) of
+ not_found -> ok;
+ File ->
+ Comment = case Type of
+ opt -> "";
+ _ -> "[emem " ++ atom_to_list(Type) ++ " compiled]"
+ end,
+ throw([{emem, File}, {emem_comment, Comment}])
+ end.
+
+check_dir(DirName) ->
+ case file:read_file_info(DirName) of
+ {ok, #file_info {type = directory, access = A}} when A == read;
+ A == read_write ->
+ DirName;
+ _ ->
+ not_found
+ end.
+
+check_file(FileName) ->
+ case file:read_file_info(FileName) of
+ {ok, #file_info {type = regular, access = A}} when A == read;
+ A == read_write ->
+ ?line FileName;
+ _ ->
+ ?line not_found
+ end.
+
+emem_comment(Config) when is_list(Config) ->
+ emem_comment(Config, "").
+
+emem_comment(Config, ExtraComment)
+ when is_list(Config), is_list(ExtraComment) ->
+ case {?config(emem_comment, Config), ExtraComment} of
+ {"", ""} -> ?line ok;
+ {"", XC} -> ?line {comment, XC};
+ {EmemC, ""} -> ?line {comment, EmemC};
+ {EmemC, XC} -> ?line {comment, EmemC ++ " " ++ XC}
+ end.
+
+run_emem_on_casefile(Config) ->
+ CaseName = atom_to_list(?config(testcase, Config)),
+ ?line File = filename:join([?config(data_dir, Config), CaseName ++ ".gz"]),
+ ?line case check_file(File) of
+ not_found ->
+ ?line ?t:fail({error, {filenotfound, File}});
+ _ ->
+ ?line ok
+ end,
+ ?line {ok, EmuFlag, Port} = start_emem(Config),
+ ?line Parent = self(),
+ ?line Ref = make_ref(),
+ ?line spawn_link(fun () ->
+ SRes = send_trace(EmuFlag, File),
+ Parent ! {Ref, SRes}
+ end),
+ ?line Res = get_emem_result(Port),
+ ?line receive
+ {Ref, ok} ->
+ ?line ok;
+ {Ref, SendError} ->
+ ?line ?t:format("Send result: ~p~n", [SendError])
+ end,
+ ?line Res.
+
+get_emem_result(Port) ->
+ ?line {Res, LV} = get_emem_result(Port, {#emem_res{}, []}),
+ ?line Res#emem_res{last_values = string:tokens(LV, " ")}.
+
+get_emem_result(Port, {_EmemRes, _LastValues} = Res) ->
+ ?line case get_emem_line(Port) of
+ eof ->
+ ?line Res;
+ Line ->
+ ?line get_emem_result(Port, parse_emem_line(Line, Res))
+ end.
+
+parse_emem_main_header_footer_line(Line, {ER, LV} = Res) ->
+
+ %% Header
+ ?line case has_prefix("> Nodename:", Line) of
+ {true, NN} ->
+ ?line throw({ER#emem_res{nodename = strip(NN)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Hostname:", Line) of
+ {true, HN} ->
+ ?line throw({ER#emem_res{hostname = strip(HN)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Pid:", Line) of
+ {true, P} ->
+ ?line throw({ER#emem_res{pid = strip(P)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Start time (UTC):", Line) of
+ {true, ST} ->
+ ?line throw({ER#emem_res{start_time = strip(ST)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Actual trace version:", Line) of
+ {true, TV} ->
+ ?line throw({ER#emem_res{trace_version = strip(TV)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Maximum trace word size:", Line) of
+ {true, MWS} ->
+ ?line throw({ER#emem_res{max_word_size = strip(MWS)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Actual trace word size:", Line) of
+ {true, WS} ->
+ ?line throw({ER#emem_res{word_size = strip(WS)}, LV});
+ false -> ?line ok
+ end,
+
+ %% Footer
+ ?line case has_prefix("> Maximum:", Line) of
+ {true, M} ->
+ ?line throw({ER#emem_res{maximum = string:tokens(M," ")}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Emulator exited with code:", Line) of
+ {true, EC} ->
+ ?line throw({ER#emem_res{exit_code = strip(EC)}, LV});
+ false -> ?line ok
+ end,
+ ?line Res.
+
+parse_emem_header_line(_Line, {_ER, _LV} = Res) ->
+ ?line Res.
+
+parse_emem_value_line(Line, {EmemRes, _OldLastValues}) ->
+ ?line {EmemRes, Line}.
+
+parse_emem_line("", Res) ->
+ ?line Res;
+parse_emem_line(Line, Res) ->
+ ?line [Prefix | _] = Line,
+ case Prefix of
+ $> -> ?line catch parse_emem_main_header_footer_line(Line, Res);
+ $| -> ?line catch parse_emem_header_line(Line, Res);
+ _ -> ?line catch parse_emem_value_line(Line, Res)
+ end.
+
+start_emem(Config) when is_list(Config) ->
+ ?line Emem = ?config(emem, Config),
+ ?line Cd = case ignore_cores:dir(Config) of
+ false -> [];
+ Dir -> [{cd, Dir}]
+ end,
+ ?line case open_port({spawn, Emem ++ " -t -n -o -i 1"},
+ Cd ++ [{line, 1024}, eof]) of
+ Port when is_port(Port) -> ?line {ok, read_emu_flag(Port), Port};
+ Error -> ?line ?t:fail(Error)
+ end.
+
+read_emu_flag(Port) ->
+ ?line Line = case get_emem_line(Port) of
+ eof -> ?line ?t:fail(unexpected_end_of_file);
+ L -> ?line L
+ end,
+ ?line case has_prefix("> Emulator command line argument:", Line) of
+ {true, EmuFlag} -> EmuFlag;
+ false -> ?line read_emu_flag(Port)
+ end.
+
+get_emem_line(Port, Acc) ->
+ ?line receive
+ {Port, {data, {eol, Data}}} ->
+ ?line Res = case Acc of
+ [] -> ?line Data;
+ _ -> ?line lists:flatten([Acc|Data])
+ end,
+ ?line ?t:format("~s", [Res]),
+ ?line Res;
+ {Port, {data, {noeol, Data}}} ->
+ ?line get_emem_line(Port, [Acc|Data]);
+ {Port, eof} ->
+ ?line port_close(Port),
+ ?line eof
+ end.
+
+get_emem_line(Port) ->
+ ?line get_emem_line(Port, []).
+
+short_hostname([]) ->
+ [];
+short_hostname([$.|_]) ->
+ [];
+short_hostname([C|Cs]) ->
+ [C | short_hostname(Cs)].
+
+has_prefix([], List) when is_list(List) ->
+ {true, List};
+has_prefix([P|Xs], [P|Ys]) ->
+ has_prefix(Xs, Ys);
+has_prefix(_, _) ->
+ false.
+
+strip(Str) -> string:strip(Str).
+
+mk_nodename(Config) ->
+ {A, B, C} = now(),
+ atom_to_list(?MODULE)
+ ++ "-" ++ atom_to_list(?config(testcase, Config))
+ ++ "-" ++ integer_to_list(A*1000000000000 + B*1000000 + C).
+
+start_node(Name, Args) ->
+ ?line Pa = filename:dirname(code:which(?MODULE)),
+ ?line ?t:start_node(Name, peer, [{args, Args ++ " -pa " ++ Pa}]).
+
+% stop_node(Node) ->
+% ?t:stop_node(Node).
+
+is_debug_compiled() ->
+ is_debug_compiled(erlang:system_info(system_version)).
+
+is_debug_compiled([$d,$e,$b,$u,$g | _]) ->
+ true;
+is_debug_compiled([ _, _, _, _]) ->
+ false;
+is_debug_compiled([]) ->
+ false;
+is_debug_compiled([_|Rest]) ->
+ is_debug_compiled(Rest).
diff --git a/lib/tools/test/eprof_SUITE.erl b/lib/tools/test/eprof_SUITE.erl
new file mode 100644
index 0000000000..028fea8fe1
--- /dev/null
+++ b/lib/tools/test/eprof_SUITE.erl
@@ -0,0 +1,97 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(eprof_SUITE).
+
+-include("test_server.hrl").
+
+-export([all/1,tiny/1,eed/1]).
+
+all(suite) -> [tiny,eed].
+
+
+tiny(suite) -> [];
+tiny(Config) when is_list(Config) ->
+ ?line ensure_eprof_stopped(),
+ ?line {ok, OldCurDir} = file:get_cwd(),
+ Datadir = ?config(data_dir, Config),
+ Privdir = ?config(priv_dir, Config),
+ ?line TTrap=?t:timetrap(60*1000),
+ % (Trace)Compile to priv_dir and make sure the correct version is loaded.
+ ?line {ok,eprof_suite_test} = compile:file(filename:join(Datadir,
+ "eprof_suite_test"),
+ [trace,{outdir, Privdir}]),
+ ?line ok = file:set_cwd(Privdir),
+ ?line code:purge(eprof_suite_test),
+ ?line {module,eprof_suite_test} = code:load_file(eprof_suite_test),
+ ?line {ok,_Pid} = eprof:start(),
+ ?line nothing_to_analyse = eprof:analyse(),
+ ?line nothing_to_analyse = eprof:total_analyse(),
+ ?line eprof:profile([], eprof_suite_test, test, [Config]),
+ ?line ok = eprof:analyse(),
+ ?line ok = eprof:total_analyse(),
+ ?line ok = eprof:log("eprof_SUITE_logfile"),
+ ?line stopped = eprof:stop(),
+ ?line ?t:timetrap_cancel(TTrap),
+ ?line ok = file:set_cwd(OldCurDir),
+ ok.
+
+eed(suite) -> [];
+eed(Config) when is_list(Config) ->
+ ?line ensure_eprof_stopped(),
+ ?line Datadir = ?config(data_dir, Config),
+ ?line Privdir = ?config(priv_dir, Config),
+ ?line TTrap=?t:timetrap(5*60*1000),
+
+ %% (Trace)Compile to priv_dir and make sure the correct version is loaded.
+ ?line code:purge(eed),
+ ?line {ok,eed} = c:c(filename:join(Datadir, "eed"), [trace,{outdir,Privdir}]),
+ ?line {ok,_Pid} = eprof:start(),
+ ?line Script = filename:join(Datadir, "ed.script"),
+ ?line ok = file:set_cwd(Datadir),
+ ?line {T1,_} = statistics(runtime),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line {T2,_} = statistics(runtime),
+ ?line {ok,ok} = eprof:profile([], eed, file, [Script]),
+ ?line {T3,_} = statistics(runtime),
+ ?line profiling_already_stopped = eprof:stop_profiling(),
+ ?line ok = eprof:analyse(),
+ ?line ok = eprof:total_analyse(),
+ ?line ok = eprof:log("eprof_SUITE_logfile"),
+ ?line stopped = eprof:stop(),
+ ?line ?t:timetrap_cancel(TTrap),
+ S = lists:flatten(io_lib:format("~p times slower", [10*(T3-T2)/(T2-T1)])),
+ {comment,S}.
+
+ensure_eprof_stopped() ->
+ Pid = whereis(eprof),
+ case whereis(eprof) of
+ undefined ->
+ ok;
+ Pid ->
+ ?line stopped=eprof:stop()
+ end.
diff --git a/lib/tools/test/eprof_SUITE_data/ed.script b/lib/tools/test/eprof_SUITE_data/ed.script
new file mode 100644
index 0000000000..94531a9e98
--- /dev/null
+++ b/lib/tools/test/eprof_SUITE_data/ed.script
@@ -0,0 +1,8 @@
+H
+r eed.erl
+g/^[a-z][a-zA-Z_]*\(/i\
+%%% -------------------------------------------------------------\
+%%% A stupid function header.\
+%%% -------------------------------------------------------------
+1,$p
+q
diff --git a/lib/tools/test/eprof_SUITE_data/eed.erl b/lib/tools/test/eprof_SUITE_data/eed.erl
new file mode 100644
index 0000000000..0175abdd0e
--- /dev/null
+++ b/lib/tools/test/eprof_SUITE_data/eed.erl
@@ -0,0 +1,815 @@
+%%%----------------------------------------------------------------------
+%%% File : eed.erl
+%%% Author : Bjorn Gustavsson <bjorn@strider>
+%%% Purpose : Unix `ed' look-alike.
+%%% Created : 24 Aug 1997 by Bjorn Gustavsson <bjorn@strider>
+%%%----------------------------------------------------------------------
+
+-module(eed).
+-author('bjorn@strider').
+
+-export([edit/0, edit/1, file/1, cmd_line/1]).
+
+-record(state, {dot = 0, % Line number of dot.
+ upto_dot = [], % Lines up to dot (reversed).
+ after_dot = [], % Lines after dot.
+ lines = 0, % Total number of lines.
+ print=false, % Print after command.
+ filename=[], % Current file.
+ pattern, % Current pattern.
+ in_global=false, % True if executing global command.
+ input=[], % Global input stream.
+ undo, % Last undo state.
+ marks=[], % List of marks.
+ modified=false, % Buffer is modified.
+ opts=[{prompt, ''}], % Options.
+ last_error, % The last error encountered.
+ input_fd % Input file descriptor.
+ }).
+
+-record(line, {contents, % Contents of line.
+ mark=false % Marked (for global prefix).
+ }).
+
+cmd_line([Script]) ->
+ file(Script),
+ halt().
+
+file(Script) ->
+ case file:open(Script, [read]) of
+ {ok,Fd} ->
+ loop(#state{input_fd=Fd}),
+ ok;
+ {error,E} ->
+ {error,E}
+ end.
+
+edit() ->
+ loop(#state{input_fd=group_leader()}).
+
+edit(Name) ->
+ loop(command([$e|Name], #state{input_fd=group_leader()})).
+
+loop(St0) ->
+ {ok, St1, Cmd} = get_line(St0),
+ case catch command(lib:nonl(Cmd), St1) of
+ {'EXIT', Reason} ->
+ %% XXX Should clear outstanding global command here.
+ loop(print_error({'EXIT', Reason}, St1));
+ quit ->
+ ok;
+ {error, Reason} ->
+ loop(print_error(Reason, St1));
+ St2 when record(St2, state) ->
+ loop(St2)
+ end.
+
+command(Cmd, St) ->
+ case parse_command(Cmd, St) of
+ quit ->
+ quit;
+ St1 when function(St1#state.print) ->
+ if
+ St1#state.dot /= 0 ->
+ print_current(St1);
+ true ->
+ ok
+ end,
+ St1#state{print=false};
+ St1 when record(St1, state) ->
+ St1
+ end.
+
+get_line(St) ->
+ Opts = St#state.opts,
+ {value, {prompt, Prompt}} = lists:keysearch(prompt, 1, Opts),
+ get_line(Prompt, St).
+
+get_line(Prompt, St) when St#state.input == [] ->
+ Line = get_line1(St#state.input_fd, Prompt, []),
+ {ok, St, Line};
+get_line(_, St) ->
+ get_input(St#state.input, St, []).
+
+get_input([eof], St, []) ->
+ {ok, St, eof};
+get_input([eof], St, Result) ->
+ {ok, St#state{input=[eof]}, lists:reverse(Result)};
+get_input([$\n|Rest], St, Result) ->
+ {ok, St#state{input=Rest}, lists:reverse(Result)};
+get_input([C|Rest], St, Result) ->
+ get_input(Rest, St, [C|Result]).
+
+get_line1(Io, Prompt, Result) ->
+ get_line2(Io, io:get_line(Io, Prompt), Result).
+
+get_line2(Io, eof, []) ->
+ eof;
+get_line2(Io, eof, Result) ->
+ lists:reverse(Result);
+get_line2(Io, [$\\, $\n], Result) ->
+ get_line1(Io, '', [$\n|Result]);
+get_line2(Io, [$\n], Result) ->
+ lists:reverse(Result, [$\n]);
+get_line2(Io, [C|Rest], Result) ->
+ get_line2(Io, Rest, [C|Result]).
+
+print_error(Reason, St0) ->
+ St1 = St0#state{last_error=Reason},
+ io:put_chars("?\n"),
+ case lists:member(help_always, St1#state.opts) of
+ true ->
+ help_command([], [], St1),
+ St1;
+ false ->
+ St1
+ end.
+
+format_error(bad_command) -> "unknown command";
+format_error(bad_filename) -> "illegal or missing filename";
+format_error(bad_file) -> "cannot open input file";
+format_error(bad_linenum) -> "line out of range";
+format_error(bad_delimiter) -> "illegal or missing delimiter";
+format_error(bad_undo) -> "nothing to undo";
+format_error(bad_mark) -> "mark not lower case ascii";
+format_error(bad_pattern) -> "invalid regular expression";
+format_error(buffer_modified) -> "warning: expecting `w'";
+format_error(nested_globals) -> "multiple globals not allowed";
+format_error(nomatch) -> "search string not found";
+format_error(missing_space) -> "no space after command";
+format_error(garbage_after_command) -> "illegal suffix";
+format_error(not_implemented) -> "not implemented yet";
+format_error({'EXIT', {Code, {Mod, Func, Args}}}) ->
+ lists:flatten(io_lib:format("aborted due to bug (~p)",
+ [{Code, {Mod, Func, length(Args)}}]));
+format_error(A) -> atom_to_list(A).
+
+
+
+%%% Parsing commands.
+
+parse_command(Cmd, St) ->
+ parse_command(Cmd, St, []).
+
+parse_command(Cmd, State, Nums) ->
+ case get_one(Cmd, State) of
+ {ok, Num, Rest, NewState} ->
+ parse_next_address(Rest, NewState, [Num|Nums]);
+ false ->
+ parse_command1(Cmd, State, Nums)
+ end.
+
+parse_next_address([$,|Rest], State, Nums) ->
+ parse_command(Rest, State, Nums);
+parse_next_address([$;|Rest], State, [Num|Nums]) ->
+ parse_command(Rest, move_to(Num, State), [Num|Nums]);
+parse_next_address(Rest, State, Nums) ->
+ parse_command1(Rest, State, Nums).
+
+parse_command1([Letter|Rest], State, Nums) ->
+ Cont = fun(Fun, NumLines, Def) ->
+ execute_command(Fun, NumLines, Def, State, Nums, Rest) end,
+ parse_cmd_char(Letter, Cont);
+parse_command1([], State, Nums) ->
+ execute_command(fun print_command/3, 1, next, State, Nums, []).
+
+get_one(Cmd, St) ->
+ case get_address(Cmd, St) of
+ {ok, Addr, Cmd1, St1} ->
+ get_one1(Cmd1, Addr, St1);
+ false ->
+ get_one1(Cmd, false, St)
+ end.
+
+get_one1([D|Rest], false, St) when $0 =< D, D =< $9 ->
+ get_one2(get_number([D|Rest]), 1, 0, St);
+get_one1([D|Rest], Sum, St) when $0 =< D, D =< $9 ->
+ get_one2(get_number([D|Rest]), 1, Sum, St);
+get_one1([$+, D|Rest], Sum, St) when $0 =< D, D =< $9 ->
+ get_one2(get_number([D|Rest]), 1, Sum, St);
+get_one1([$-, D|Rest], Sum, St) when $0 =< D, D =< $9 ->
+ get_one2(get_number([D|Rest]), -1, Sum, St);
+get_one1([$+|Rest], Sum, St) ->
+ get_one2({ok, 1, Rest}, 1, Sum, St);
+get_one1([$-|Rest], Sum, St) ->
+ get_one2({ok, 1, Rest}, -1, Sum, St);
+get_one1(Cmd, false, St) ->
+ false;
+get_one1(Cmd, Sum, St) ->
+ {ok, Sum, Cmd, St}.
+
+get_one2({ok, Number, Rest}, Mul, false, St) ->
+ get_one1(Rest, St#state.dot+Mul*Number, St);
+get_one2({ok, Number, Rest}, Mul, Sum, St) ->
+ get_one1(Rest, Sum+Mul*Number, St).
+
+get_number(Cmd) ->
+ get_number(Cmd, 0).
+
+get_number([D|Rest], Result) when $0 =< D, D =< $9 ->
+ get_number(Rest, Result*10+D-$0);
+get_number(Rest, Result) ->
+ {ok, Result, Rest}.
+
+get_address([$.|Rest], State) ->
+ {ok, State#state.dot, Rest, State};
+get_address([$$|Rest], State) ->
+ {ok, State#state.lines, Rest, State};
+get_address([$', Mark|Rest], St) when $a =< Mark, Mark =< $z ->
+ case lists:keysearch(Mark, 2, St#state.marks) of
+ {value, {Line, Mark}} ->
+ {ok, Line, Rest, St};
+ false ->
+ {ok, 0, Rest, St}
+ end;
+get_address([$'|Rest], State) ->
+ error(bad_mark);
+get_address([$/|Rest], State) ->
+ scan_forward($/, Rest, State);
+get_address([$?|Rest], State) ->
+ error(not_implemented);
+get_address(Cmd, St) ->
+ false.
+
+scan_forward(End, Patt0, State) ->
+ {ok, Rest, NewState} = get_pattern(End, Patt0, State),
+ Dot = NewState#state.dot,
+ After = NewState#state.after_dot,
+ scan_forward1(Dot+1, After, NewState, Rest).
+
+scan_forward1(Linenum, [Line|Rest], State, RestCmd) ->
+ case regexp:first_match(Line#line.contents, State#state.pattern) of
+ {match, _, _} ->
+ {ok, Linenum, RestCmd, State};
+ nomatch ->
+ scan_forward1(Linenum+1, Rest, State, RestCmd)
+ end;
+scan_forward1(_, [], State, RestCmd) ->
+ Dot = State#state.dot,
+ Upto = State#state.upto_dot,
+ case scan_forward2(Dot, Upto, State, RestCmd) of
+ false ->
+ error(bad_linenum);
+ Other ->
+ Other
+ end.
+
+scan_forward2(0, [], State, RestCmd) ->
+ false;
+scan_forward2(Linenum, [Line|Rest], State, RestCmd) ->
+ case scan_forward2(Linenum-1, Rest, State, RestCmd) of
+ false ->
+ case regexp:first_match(Line#line.contents, State#state.pattern) of
+ {match, _, _} ->
+ {ok, Linenum, RestCmd, State};
+ nomatch ->
+ false
+ end;
+ Other ->
+ Other
+ end.
+
+parse_cmd_char($S, Cont) -> Cont(fun quest_command/3, 0, none);
+parse_cmd_char($T, Cont) -> Cont(fun time_command/3, 0, none);
+parse_cmd_char($=, Cont) -> Cont(fun print_linenum/3, 1, last);
+parse_cmd_char($a, Cont) -> Cont(fun append_command/3, 1, dot);
+parse_cmd_char($c, Cont) -> Cont(fun change_command/3, 2, dot);
+parse_cmd_char($d, Cont) -> Cont(fun delete_command/3, 2, dot);
+parse_cmd_char($e, Cont) -> Cont(fun enter_command/3, 0, none);
+parse_cmd_char($E, Cont) -> Cont(fun enter_always_command/3, 0, none);
+parse_cmd_char($f, Cont) -> Cont(fun file_command/3, 0, none);
+parse_cmd_char($g, Cont) -> Cont(fun global_command/3, 2, all);
+parse_cmd_char($h, Cont) -> Cont(fun help_command/3, 0, none);
+parse_cmd_char($H, Cont) -> Cont(fun help_always_command/3, 0, none);
+parse_cmd_char($i, Cont) -> Cont(fun insert_command/3, 1, dot);
+parse_cmd_char($k, Cont) -> Cont(fun mark_command/3, 1, dot);
+parse_cmd_char($l, Cont) -> Cont(fun list_command/3, 2, dot);
+parse_cmd_char($m, Cont) -> Cont(fun move_command/3, 2, dot);
+parse_cmd_char($n, Cont) -> Cont(fun number_command/3, 2, dot);
+parse_cmd_char($p, Cont) -> Cont(fun print_command/3, 2, dot);
+parse_cmd_char($P, Cont) -> Cont(fun prompt_command/3, 0, none);
+parse_cmd_char($q, Cont) -> Cont(fun quit_command/3, 0, none);
+parse_cmd_char($Q, Cont) -> Cont(fun quit_always_command/3, 0, none);
+parse_cmd_char($r, Cont) -> Cont(fun read_command/3, 1, last);
+parse_cmd_char($s, Cont) -> Cont(fun subst_command/3, 2, dot);
+parse_cmd_char($t, Cont) -> Cont(fun transpose_command/3, 2, dot);
+parse_cmd_char($u, Cont) -> Cont(fun undo_command/3, 0, none);
+parse_cmd_char($v, Cont) -> Cont(fun vglobal_command/3, 2, all);
+parse_cmd_char($w, Cont) -> Cont(fun write_command/3, 2, all);
+parse_cmd_char(_, Cont) -> error(bad_command).
+
+execute_command(Fun, NumLines, Def, State, Nums, Rest) ->
+ Lines = check_lines(NumLines, Def, Nums, State),
+ Fun(Rest, Lines, State).
+
+check_lines(0, _, [], _State) ->
+ [];
+check_lines(1, dot, [], #state{dot=Dot}) ->
+ [Dot];
+check_lines(1, next, [], State) when State#state.dot < State#state.lines ->
+ [State#state.dot+1];
+check_lines(1, last, [], State) ->
+ [State#state.lines];
+check_lines(1, _, [Num|_], State) when 0 =< Num, Num =< State#state.lines ->
+ [Num];
+check_lines(2, dot, [], #state{dot=Dot}) ->
+ [Dot, Dot];
+check_lines(2, all, [], #state{lines=Lines}) ->
+ [1, Lines];
+check_lines(2, _, [Num], State) when 0 =< Num, Num =< State#state.lines ->
+ [Num, Num];
+check_lines(2, _, [Num2, Num1|_], State)
+when 0 =< Num1, Num1 =< Num2, Num2 =< State#state.lines ->
+ [Num1, Num2];
+check_lines(_, _, _, _) ->
+ error(bad_linenum).
+
+
+%%% Executing commands.
+
+%% ($)= - print line number
+
+print_linenum(Rest, [Line], State) ->
+ NewState = check_trailing_p(Rest, State),
+ io:format("~w\n", [Line]),
+ NewState.
+
+%% ? - print state (for debugging)
+
+quest_command([], [], State) ->
+ io:format("~p\n", [State]),
+ State.
+
+%% Tcmd - time command
+
+time_command(Cmd, [], St) ->
+ Fun = fun parse_command/2,
+ erlang:garbage_collect(),
+ {Elapsed, Val} = timer:tc(erlang, apply, [Fun, [Cmd, St]]),
+ io:format("Time used: ~p s~n", [Elapsed/1000000.0]),
+ case Val of
+ {error, Reason} ->
+ throw({error, Reason});
+ Other ->
+ Other
+ end.
+
+%% (.)a - append text
+
+append_command(Rest, [Line], St0) ->
+ St1 = save_for_undo(St0),
+ append(move_to(Line, check_trailing_p(Rest, St1))).
+
+append(St0) ->
+ {ok, St1, Line0} = get_line('', St0),
+ case Line0 of
+ eof ->
+ St1;
+ ".\n" ->
+ St1;
+ Line ->
+ append(insert_line(Line, St1))
+ end.
+
+%% (.,.)c
+
+change_command(Rest, Lines, St0) ->
+ St1 = delete_command(Rest, Lines, St0),
+ St2 = append_command([], [St1#state.dot-1], St1),
+ save_for_undo(St2, St0).
+
+%% (.,.)d - delete lines
+
+delete_command(Rest, [0, Last], St) ->
+ error(bad_linenum);
+delete_command(Rest, [First, Last], St0) ->
+ St1 = check_trailing_p(Rest, save_for_undo(St0)),
+ delete(Last-First+1, move_to(Last, St1)).
+
+delete(0, St) when St#state.dot == St#state.lines ->
+ St;
+delete(0, St) ->
+ next_line(St);
+delete(Left, St0) ->
+ St1 = delete_current_line(St0),
+ delete(Left-1, St1).
+
+%% e file - replace buffer with new file
+
+enter_command(Name, [], St) when St#state.modified == true ->
+ error(buffer_modified);
+enter_command(Name, [], St0) ->
+ enter_always_command(Name, [], St0).
+
+%% E file - replace buffer with new file
+
+enter_always_command(Name, [], St0) ->
+ St1 = read_command(Name, [0], #state{filename=St0#state.filename,
+ opts=St0#state.opts}),
+ St1#state{modified=false}.
+
+%% f file - print filename; set filename
+
+file_command([], [], St) ->
+ io:format("~s~n", [St#state.filename]),
+ St;
+file_command([$_|Name0], [], St) ->
+ Name = skip_blanks(Name0),
+ file_command([], [], St#state{filename=Name});
+file_command(_, _, _) ->
+ error(missing_space).
+
+%% (1,$)g/RE/commands - execute commands on all matching lines.
+%% (1,$)v/RE/commands - execute commands on all non-matching lines.
+
+global_command(Cmd, Lines, St) ->
+ check_global0(true, Cmd, Lines, St).
+
+vglobal_command(Cmd, Lines, St) ->
+ check_global0(false, Cmd, Lines, St).
+
+check_global0(_, _, _, St) when St#state.in_global == true ->
+ error(nested_globals);
+check_global0(Sense, [Sep|Pattern], Lines, St0) ->
+ {ok, Cmd, St1} = get_pattern(Sep, Pattern, St0),
+ St2 = mark(Sense, Lines, St1),
+ do_global_command(Cmd, St2#state{in_global=true}, 0).
+
+mark(Sense, [First, Last], St0) ->
+ St1 = move_to(Last, St0),
+ mark1(Sense, First-1, St1).
+
+mark1(Sense, First, St) when St#state.dot == First ->
+ St;
+mark1(Sense, First, St) ->
+ [Line|Prev] = St#state.upto_dot,
+ NewLine = case match(St) of
+ true -> Line#line{mark=Sense};
+ false -> Line#line{mark=not(Sense)}
+ end,
+ mark1(Sense, First, prev_line(St#state{upto_dot=[NewLine|Prev]})).
+
+do_global_command(Cmd, St0, Matches) ->
+ case find_mark(St0) of
+ {ok, St1} ->
+ St2 = St1#state{input=Cmd++[eof]},
+ {ok, St3, Cmd1} = get_line(St2),
+ St4 = command(Cmd1, St3),
+ %% XXX There might be several commands.
+ do_global_command(Cmd, St4, Matches+1);
+ false when Matches == 0 ->
+ error(nomatch);
+ false ->
+ St0#state{in_global=false, input=[]}
+ end.
+
+find_mark(State) ->
+ find_mark(State#state.lines, State).
+
+find_mark(0, _State) ->
+ false;
+find_mark(Limit, State) when State#state.dot == 0 ->
+ find_mark(Limit, next_line(State));
+find_mark(Limit, State) ->
+ case State#state.upto_dot of
+ [Line|Prev] when Line#line.mark == true ->
+ NewLine = Line#line{mark=false},
+ {ok, State#state{upto_dot=[NewLine|Prev]}};
+ _Other ->
+ find_mark(Limit-1, wrap_next_line(State))
+ end.
+
+%% h - print info about last error
+
+help_command([], [], St) ->
+ case St#state.last_error of
+ undefined ->
+ St;
+ Reason ->
+ io:put_chars(format_error(Reason)),
+ io:nl(),
+ St
+ end;
+help_command(_, _, _) ->
+ error(garbage_after_command).
+
+%% H - toggle automatic help mode on/off
+
+help_always_command([], [], St) ->
+ Opts = St#state.opts,
+ case lists:member(help_always, Opts) of
+ true ->
+ St#state{opts=Opts--[help_always]};
+ false ->
+ help_command([], [], St),
+ St#state{opts=[help_always|Opts]}
+ end.
+
+%% (.)i - insert text
+
+insert_command(Rest, [0], State) ->
+ error(bad_linenum);
+insert_command(Rest, [Line], State) ->
+ append_command(Rest, [Line-1], State).
+
+%% (.)kx - mark line
+
+mark_command(_, [0], St) ->
+ error(bad_linenum);
+mark_command([Mark|Rest], [Line], St) when $a =< Mark, Mark =< $z ->
+ error(not_implemented);
+mark_command(_, _, _) ->
+ error(bad_mark).
+
+%% (.,.)l - list lines
+
+list_command(Rest, Lines, St) ->
+ print([$l|Rest], Lines, St).
+
+%% (.,.)m - move lines
+
+move_command(Cmd, [First, Last], St) ->
+ error(not_implemented).
+
+%% (.,.)t - copy lines
+
+transpose_command(Cmd, [First, Last], St) ->
+ error(not_implemented).
+
+%% (.,.)n - print lines with line numbers
+
+number_command(Rest, Lines, St) ->
+ print([$n|Rest], Lines, St).
+
+%% (.,.)p - print lines
+
+print_command(Rest, Lines, St) ->
+ print([$p|Rest], Lines, St).
+
+%% P - toggle prompt
+
+prompt_command([], [], St) ->
+ Opts = St#state.opts,
+ case lists:keysearch(prompt, 1, Opts) of
+ {value, {prompt, ''}} ->
+ St#state{opts=[{prompt, '*'}|Opts]};
+ {value, Value} ->
+ St#state{opts=[{prompt, ''} | Opts--[Value]]}
+ end;
+prompt_command(_, _, _) ->
+ error(garbage_after_command).
+
+%% q - quit editor
+
+quit_command([], [], _) ->
+ quit;
+quit_command(_, _, _) ->
+ error(garbage_after_command).
+
+%% Q - quit editor
+
+quit_always_command([], [], _) ->
+ quit;
+quit_always_command(_, _, _) ->
+ error(garbage_after_command).
+
+%% ($)r file - read file
+
+read_command([], _, St) when St#state.filename == [] ->
+ error(bad_filename);
+read_command([], [After], St) ->
+ read(After, St#state.filename, St);
+read_command([$ |Name0], [After], St) when St#state.filename == [] ->
+ Name = skip_blanks(Name0),
+ read(After, Name, St#state{filename=Name});
+read_command([$ |Name0], [After], St) ->
+ Name = skip_blanks(Name0),
+ read(After, Name, St);
+read_command(_, _, _) ->
+ error(missing_space).
+
+read(After, Name, St0) ->
+ case file:read_file(Name) of
+ {ok, Bin} ->
+ Chars = size(Bin),
+ St1 = move_to(After, St0),
+ St2 = insert_line(binary_to_list(Bin), St1),
+ io:format("~w~n", [Chars]),
+ St2;
+ {error, _} ->
+ error(bad_file)
+ end.
+
+%% s/pattern/replacement/gp
+
+subst_command(_, [0, _], _) ->
+ error(bad_linenum);
+subst_command([$ |Cmd0], [First, Last], St0) ->
+ error(bad_delimiter);
+subst_command([$\n|Cmd0], [First, Last], St0) ->
+ error(bad_delimiter);
+subst_command([Sep|Cmd0], [First, Last], St0) ->
+ St1 = save_for_undo(St0),
+ {ok, Cmd1, St2} = get_pattern(Sep, Cmd0, St1),
+ {ok, Replacement, Cmd2} = get_replacement(Sep, Cmd1),
+ {ok, Sub, Cmd3} = subst_check_gflag(Cmd2),
+ St3 = check_trailing_p(Cmd3, St2),
+ subst_command(Last-First+1, Sub, Replacement, move_to(First-1, St3), nomatch);
+subst_command([], _, _) ->
+ error(bad_delimiter).
+
+subst_command(0, _, _, _, nomatch) ->
+ error(nomatch);
+subst_command(0, _, _, _, StLast) when record(StLast, state) ->
+ StLast;
+subst_command(Left, Sub, Repl, St0, LastMatch) ->
+ St1 = next_line(St0),
+ [Line|_] = St1#state.upto_dot,
+ case regexp:Sub(Line#line.contents, St1#state.pattern, Repl) of
+ {ok, _, 0} ->
+ subst_command(Left-1, Sub, Repl, St1, LastMatch);
+ {ok, NewContents, _} ->
+ %% XXX This doesn't work with marks.
+ St2 = delete_current_line(St1),
+ St3 = insert_line(NewContents, St2),
+ subst_command(Left-1, Sub, Repl, St3, St3)
+ end.
+
+subst_check_gflag([$g|Cmd]) -> {ok, gsub, Cmd};
+subst_check_gflag(Cmd) -> {ok, sub, Cmd}.
+
+%% u - undo
+
+undo_command([], [], St) when St#state.undo == undefined ->
+ error(bad_undo);
+undo_command([], [], #state{undo=Undo}) ->
+ Undo;
+undo_command(_, _, _) ->
+ error(garbage_after_command).
+
+%% (1,$)w - write buffer to file
+
+write_command(Cmd, [First, Last], St) ->
+ error(not_implemented).
+
+
+%%% Primitive buffer operations.
+
+print_current(St) ->
+ [Line|_] = St#state.upto_dot,
+ Printer = St#state.print,
+ Printer(Line#line.contents, St).
+
+delete_current_line(St) when St#state.dot == 0 ->
+ error(bad_linenum);
+delete_current_line(St) ->
+ Lines = St#state.lines,
+ [_|Prev] = St#state.upto_dot,
+ St#state{dot=St#state.dot-1, upto_dot=Prev, lines=Lines-1, modified=true}.
+
+insert_line(Line, State) ->
+ insert_line1(Line, State, []).
+
+insert_line1([$\n|Rest], State, Result) ->
+ NewState = insert_single_line(lists:reverse(Result, [$\n]), State),
+ insert_line1(Rest, NewState, []);
+insert_line1([C|Rest], State, Result) ->
+ insert_line1(Rest, State, [C|Result]);
+insert_line1([], State, []) ->
+ State;
+insert_line1([], State, Result) ->
+ insert_single_line(lists:reverse(Result, [$\n]), State).
+
+insert_single_line(Line0, State) ->
+ Line = #line{contents=Line0},
+ Dot = State#state.dot,
+ Before = State#state.upto_dot,
+ Lines = State#state.lines,
+ %% XXX Avoid updating the record every time.
+ State#state{dot=Dot+1, upto_dot=[Line|Before], lines=Lines+1, modified=true}.
+
+move_to(Line, State) when Line < State#state.dot ->
+ move_to(Line, prev_line(State));
+move_to(Line, State) when State#state.dot < Line ->
+ move_to(Line, next_line(State));
+move_to(Line, State) when Line == State#state.dot ->
+ State.
+
+prev_line(State) ->
+ Dot = State#state.dot,
+ Before = State#state.upto_dot,
+ After = State#state.after_dot,
+ State#state{dot=Dot-1, upto_dot=tl(Before), after_dot=[hd(Before)|After]}.
+
+next_line(State) ->
+ Dot = State#state.dot,
+ Before = State#state.upto_dot,
+ After = State#state.after_dot,
+ State#state{dot=Dot+1, upto_dot=[hd(After)|Before], after_dot=tl(After)}.
+
+wrap_next_line(State) when State#state.dot == State#state.lines ->
+ move_to(1, State);
+wrap_next_line(State) ->
+ next_line(State).
+
+
+%%% Utilities.
+
+get_pattern(End, Cmd, State) ->
+ get_pattern(End, Cmd, State, []).
+
+get_pattern(End, [End|Rest], State, []) when State#state.pattern /= undefined ->
+ {ok, Rest, State};
+get_pattern(End, [End|Rest], State, Result) ->
+ case regexp:parse(lists:reverse(Result)) of
+ {error, _} ->
+ error(bad_pattern);
+ {ok, Re} ->
+ {ok, Rest, State#state{pattern=Re}}
+ end;
+get_pattern(End, [C|Rest], State, Result) ->
+ get_pattern(End, Rest, State, [C|Result]);
+get_pattern(End, [], State, Result) ->
+ get_pattern(End, [End], State, Result).
+
+get_replacement(End, Cmd) ->
+ get_replacement(End, Cmd, []).
+
+get_replacement(End, [End|Rest], Result) ->
+ {ok, lists:reverse(Result), Rest};
+get_replacement(End, [$\\, $&|Rest], Result) ->
+ get_replacement(End, Rest, [$&, $\\|Result]);
+get_replacement(End, [$\\, C|Rest], Result) ->
+ get_replacement(End, Rest, [C|Result]);
+get_replacement(End, [C|Rest], Result) ->
+ get_replacement(End, Rest, [C|Result]);
+get_replacement(End, [], Result) ->
+ get_replacement(End, [End], Result).
+
+check_trailing_p([$l], St) ->
+ St#state{print=fun(Line, _) -> lister(Line, 0) end};
+check_trailing_p([$n], St) ->
+ St#state{print=fun numberer/2};
+check_trailing_p([$p], St) ->
+ St#state{print=fun(Line, _) -> io:put_chars(Line) end};
+check_trailing_p([], State) ->
+ State;
+check_trailing_p(Other, State) ->
+ error(garbage_after_command).
+
+error(Reason) ->
+ throw({error, Reason}).
+
+match(State) when State#state.dot == 0 ->
+ false;
+match(State) ->
+ [Line|_] = State#state.upto_dot,
+ Re = State#state.pattern,
+ case regexp:first_match(Line#line.contents, Re) of
+ {match, _, _} -> true;
+ nomatch -> false
+ end.
+
+skip_blanks([$ |Rest]) ->
+ skip_blanks(Rest);
+skip_blanks(Rest) ->
+ Rest.
+
+print(Rest, [Line], St0) when Line > 0 ->
+ St1 = check_trailing_p(Rest, St0),
+ print(Line, move_to(Line-1, St1));
+print(Rest, [First, Last], St0) when First > 0 ->
+ St1 = check_trailing_p(Rest, St0),
+ print(Last, move_to(First-1, St1)).
+
+print(Last, St) when St#state.dot == Last ->
+ St#state{print=false};
+print(Last, St0) ->
+ St1 = next_line(St0),
+ print_current(St1),
+ print(Last, St1).
+
+lister(Rest, 64) ->
+ io:put_chars("\\\n"),
+ lister(Rest, 0);
+lister([C|Rest], Num) ->
+ list_char(C),
+ lister(Rest, Num+1);
+lister([], _) ->
+ ok.
+
+list_char($\t) ->
+ io:put_chars("\\t");
+list_char($\n) ->
+ io:put_chars("$\n");
+list_char(C) ->
+ io:put_chars([C]).
+
+numberer(Line, St) ->
+ io:format("~w\t~s", [St#state.dot, Line]).
+
+save_for_undo(St) ->
+ St#state{undo=St#state{undo=undefined, print=false}}.
+
+save_for_undo(St, OldSt) ->
+ St#state{undo=OldSt#state{undo=undefined, print=false}}.
diff --git a/lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl b/lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl
new file mode 100644
index 0000000000..a88b6e21f2
--- /dev/null
+++ b/lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl
@@ -0,0 +1,74 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+%%%----------------------------------------------------------------------
+%%% Purpose : A priority queue.
+%%%----------------------------------------------------------------------
+%%% This module implements a priority queue as defined in
+%%% "Priority Queues and the STL" by Mark Nelson in Dr.Dobb's Journal, Jan 1996
+%%% see http://web2.airmail.net/markn/articles/pq_stl/priority.htm for more
+%%% information. (A heap implementation is planned aswell)
+%%%----------------------------------------------------------------------
+%%% The items of the queue is kept priority sorted, and because of that,
+%%% a push() operation costs more than a pop() operation (wich only
+%%% needs to return the top item of the queue(read: list)).
+%%%----------------------------------------------------------------------
+%%% The priority queue can be deceptively nice to use when creating for
+%%% example a Huffman coding tree.
+%%% See http://web2.airmail.net/markn/articles/pq_stl/priority.htm or
+%%% Dr.Dobb's Journal Jan, 96 for more information on this.
+%%%----------------------------------------------------------------------
+
+-module(eprof_suite_test).
+-export([test/1]).
+-export([new/0, push/3, pop/1]).
+
+test(Config) ->
+ Q1=new(),
+ Q2=push(Q1, "monkey", 3),
+ Q3=push(Q2, "banana", 4),
+ Q4=push(Q3, "jungle", 2),
+ Q5=push(Q4, "world", 5),
+ Q6=push(Q5, "universe",6),
+ Q7=push(Q6, "peanut", 1),
+% io:format("~p~n",[Q7]),
+ {Itm, Q8}=pop(Q7),
+ ok.
+
+%% Returns a new priority queue.
+new() ->
+ [].
+
+%% Pushes a new item with a set priority into the queue.
+push(Queue, Itm, Pri) ->
+ insert(Queue, Itm, Pri, []).
+
+%% Pops the item with the highest priority out of the queue.
+pop([{Itm, Pri}|Queue]) ->
+ {Itm, Queue}.
+
+%% --- -- -
+%% Support functions.
+insert([], Itm, Pri, NewQ) ->
+ lists:flatten([lists:reverse(NewQ)|[{Itm, Pri}]]);
+% Itm>QItm>NewQ>Queue
+insert([{QItm,QPri}|Queue], Itm, Pri, NewQ) when Pri>QPri->
+ A = [{Itm, Pri}|[{QItm, QPri}]],
+ lists:flatten([[A|NewQ]|Queue]);
+insert([QItm|Rest], Itm, Pri, NewQ) ->
+ insert(Rest, Itm, Pri, [QItm|NewQ]).
+%% --- -- -
diff --git a/lib/tools/test/fprof_SUITE.erl b/lib/tools/test/fprof_SUITE.erl
new file mode 100644
index 0000000000..e437007e76
--- /dev/null
+++ b/lib/tools/test/fprof_SUITE.erl
@@ -0,0 +1,1191 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(fprof_SUITE).
+
+-include("test_server.hrl").
+
+%% Test server framework exports
+-export([all/1, not_run/1]).
+
+%% Test suites
+-export([stack_seq/1, tail_seq/1, create_file_slow/1, spawn_simple/1,
+ imm_tail_seq/1, imm_create_file_slow/1, imm_compile/1,
+ cpu_create_file_slow/1]).
+
+%% Other exports
+-export([create_file_slow/2]).
+
+
+%% Debug exports
+-export([parse/1, verify/2]).
+-export([spawn_simple_test/3]).
+
+
+-define(line_trace,true).
+
+%-define(debug,true).
+-ifdef(debug).
+-define(dbg(Str,Args), io:format(Str,Args)).
+-else.
+-define(dbg(Str,Args), ok).
+-endif.
+
+
+
+%%%---------------------------------------------------------------------
+%%% Test suites
+%%%---------------------------------------------------------------------
+
+
+
+all(doc) ->
+ ["Test the 'fprof' profiling tool."];
+all(suite) ->
+ case test_server:is_native(?MODULE) of
+ true ->
+ [not_run];
+ false ->
+ [stack_seq, tail_seq, create_file_slow, spawn_simple,
+ imm_tail_seq, imm_create_file_slow, imm_compile,
+ cpu_create_file_slow]
+ end.
+
+not_run(Config) when is_list(Config) ->
+ {skipped, "Native code"}.
+
+%%%---------------------------------------------------------------------
+
+stack_seq(doc) ->
+ ["Tests a stack recursive variant of lists:seq/3"];
+stack_seq(suite) ->
+ [];
+stack_seq(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(20)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line TraceFile =
+ filename:join(PrivDir, ?MODULE_STRING"_stack_seq.trace"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_stack_seq.analysis"),
+ ?line Start = 1,
+ ?line Stop = 1000,
+ ?line Succ = fun (X) -> X + 1 end,
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line R0 = fprof:apply(fun seq/3, [Start, Stop, Succ], [{file, TraceFile}]),
+ ?line TS1 = erlang:now(),
+ ?line R = seq(Start, Stop, Succ),
+ ?line TS2 = erlang:now(),
+ ?line ok = fprof:profile(file, TraceFile),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ ?line R = R0,
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = (catch verify(T, P)),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line check_own_and_acc(TraceFile,AnalysisFile),
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(TraceFile),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc2 = ts_sub(TS2, TS1),
+ ?line io:format("ts:~w, fprof:~w, bare:~w.~n", [Acc, Acc1, Acc2]),
+ {comment, io_lib:format("~p times slower", [Acc1/Acc2])}.
+
+%%%---------------------------------------------------------------------
+
+tail_seq(doc) ->
+ ["Tests a tail recursive variant of lists:seq/3"];
+tail_seq(suite) ->
+ [];
+tail_seq(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(10)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line TraceFile =
+ filename:join(PrivDir, ?MODULE_STRING"_tail_seq.trace"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_tail_seq.analysis"),
+ ?line Start = 1,
+ ?line Stop = 1000,
+ ?line Succ = fun (X) -> X + 1 end,
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line R = seq_r(Start, Stop, Succ),
+ ?line TS1 = erlang:now(),
+ %%
+ ?line R1 = fprof:apply(fun seq_r/3, [Start, Stop, Succ],
+ [{file, TraceFile}]),
+ ?line TS2 = erlang:now(),
+ ?line ok = fprof:profile([{file,TraceFile}]),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ ?line R = R1,
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line check_own_and_acc(TraceFile,AnalysisFile),
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(TraceFile),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc2 = ts_sub(TS2, TS1),
+ ?line io:format("ts:~w, fprof:~w, bare:~w.~n", [Acc, Acc2, Acc1]),
+ {comment, io_lib:format("~p times slower", [Acc2/Acc1])}.
+
+%%%---------------------------------------------------------------------
+
+create_file_slow(doc) ->
+ ["Tests the create_file_slow benchmark"];
+create_file_slow(suite) ->
+ [];
+create_file_slow(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(40)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line TraceFile =
+ filename:join(PrivDir, ?MODULE_STRING"_create_file_slow.trace"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_create_file_slow.analysis"),
+ ?line DataFile =
+ filename:join(PrivDir, ?MODULE_STRING"_create_file_slow.data"),
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line ok = create_file_slow(DataFile, 1024),
+ ?line TS1 = erlang:now(),
+ %%
+ ?line ok = file:delete(DataFile),
+ ?line TS2 = erlang:now(),
+ ?line ok = fprof:apply(?MODULE, create_file_slow, [DataFile, 1024],
+ [{file, TraceFile}]),
+ ?line TS3 = erlang:now(),
+ ?line ok = fprof:profile(file, TraceFile),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line check_own_and_acc(TraceFile,AnalysisFile),
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(DataFile),
+ ?line file:delete(TraceFile),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc3 = ts_sub(TS3, TS2),
+ ?line io:format("ts:~w, fprof:~w, bare:~w.~n", [Acc, Acc3, Acc1]),
+ {comment, io_lib:format("~p times slower", [Acc3/Acc1])}.
+
+
+
+%%%---------------------------------------------------------------------
+
+spawn_simple(doc) ->
+ ["Tests process spawn"];
+spawn_simple(suite) ->
+ [];
+spawn_simple(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(30)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line TraceFile =
+ filename:join(PrivDir, ?MODULE_STRING"_spawn_simple.trace"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_spawn_simple.analysis"),
+ ?line Start = 1,
+ ?line Stop = 1000,
+ ?line Succ = fun (X) -> X + 1 end,
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line {{_, R1}, {_, R2}} = spawn_simple_test(Start, Stop, Succ),
+ ?line TS1 = erlang:now(),
+ %%
+ ?line ok = fprof:trace(start, TraceFile),
+ ?line {{P1, R3}, {P2, R4}} = spawn_simple_test(Start, Stop, Succ),
+ ?line ok = fprof:trace(stop),
+ ?line TS2 = erlang:now(),
+ ?line ok = fprof:profile(file, TraceFile),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ ?line R1 = R3,
+ ?line R2 = R4,
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc1 = pid_to_list(P1),
+ ?line Proc2 = pid_to_list(P2),
+ ?line Proc0 = pid_to_list(self()),
+ ?line io:format("~p~n ~p ~p ~p~n", [P, Proc0, Proc1, Proc2]),
+ ?line [{analysis_options, _}, [{totals, _, Acc, _}] | Procs] = P,
+ ?line [[{Proc0, _, undefined, _} | _]] =
+ lists:filter(fun ([Pt | _]) when element(1, Pt) == Proc0 -> true;
+ (_) -> false
+ end, Procs),
+ ?line [[{Proc1, _, undefined, _},
+ {spawned_by, Proc0},
+ {spawned_as, {erlang, apply, ["#Fun"++_, []]}},
+ {initial_calls, [{erlang, apply, 2},
+ {?MODULE, '-spawn_simple_test/3-fun-0-', 4}]}
+ | _]] =
+ lists:filter(fun ([Pt | _]) when element(1, Pt) == Proc1 -> true;
+ (_) -> false
+ end, Procs),
+ ?line [[{Proc2, _, undefined, _},
+ {spawned_by, Proc0},
+ {spawned_as, {erlang, apply, ["#Fun"++_, []]}},
+ {initial_calls, [{erlang, apply, 2},
+ {?MODULE, '-spawn_simple_test/3-fun-1-', 4}]}
+ | _]] =
+ lists:filter(fun ([Pt | _]) when element(1, Pt) == Proc2 -> true;
+ (_) -> false
+ end, Procs),
+ ?line 3 = length(Procs),
+ ?line R1 = lists:reverse(R2),
+ %%
+ ?line check_own_and_acc(TraceFile,AnalysisFile),
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(TraceFile),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc2 = ts_sub(TS2, TS1),
+ ?line io:format("ts:~w, fprof:~w, bare:~w.~n", [Acc, Acc2, Acc1]),
+ {comment, io_lib:format("~p times slower", [Acc2/Acc1])}.
+
+
+spawn_simple_test(Start, Stop, Succ) ->
+ Parent = self(),
+ Seq =
+ spawn_link(
+ fun () ->
+ Parent ! {self(), seq(Start, Stop, Succ)}
+ end),
+ SeqR =
+ spawn_link(
+ fun () ->
+ Parent ! {self(), seq_r(Start, Stop, Succ)}
+ end),
+ receive {Seq, SeqResult} ->
+ receive {SeqR, SeqRResult} ->
+ {{Seq, SeqResult}, {SeqR, SeqRResult}}
+ end
+ end.
+
+
+
+%%%---------------------------------------------------------------------
+
+imm_tail_seq(doc) ->
+ ["Tests a tail recursive variant of lists:seq/3 ",
+ "with immediate trace to profile"];
+imm_tail_seq(suite) ->
+ [];
+imm_tail_seq(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(10)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_imm_tail_seq.analysis"),
+ ?line Start = 1,
+ ?line Stop = 1000,
+ ?line Succ = fun (X) -> X + 1 end,
+ ?line ok = fprof:stop(kill),
+ ?line catch eprof:stop(),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line R0 = seq_r(Start, Stop, Succ),
+ ?line TS1 = erlang:now(),
+ %%
+ ?line profiling = eprof:start_profiling([self()]),
+ ?line TS2 = erlang:now(),
+ ?line R2 = seq_r(Start, Stop, Succ),
+ ?line TS3 = erlang:now(),
+ ?line profiling_stopped = eprof:stop_profiling(),
+ ?line R2 = R0,
+ %%
+ ?line eprof:analyse(),
+ ?line stopped = eprof:stop(),
+ %%
+ ?line {ok, Tracer} = fprof:profile(start),
+ ?line ok = fprof:trace([start, {tracer, Tracer}]),
+ ?line TS4 = erlang:now(),
+ ?line R4 = seq_r(Start, Stop, Succ),
+ ?line TS5 = erlang:now(),
+ ?line ok = fprof:trace(stop),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ ?line R4 = R0,
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc3 = ts_sub(TS3, TS2),
+ ?line Acc5 = ts_sub(TS5, TS4),
+ ?line io:format("~p (plain), ~p (eprof), ~p (fprof), ~p (cpu)~n",
+ [Acc1/1000, Acc3/1000, Acc5/1000, Acc/1000]),
+ {comment, io_lib:format("~p/~p (fprof/eprof) times slower",
+ [Acc5/Acc1, Acc3/Acc1])}.
+
+%%%---------------------------------------------------------------------
+
+imm_create_file_slow(doc) ->
+ ["Tests a tail recursive variant of lists:seq/3 ",
+ "with immediate trace to profile"];
+imm_create_file_slow(suite) ->
+ [];
+imm_create_file_slow(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(60)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line DataFile =
+ filename:join(PrivDir, ?MODULE_STRING"_imm_create_file_slow.data"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_imm_create_file_slow.analysis"),
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line ok = create_file_slow(DataFile, 1024),
+ ?line TS1 = erlang:now(),
+ ?line ok = file:delete(DataFile),
+ %%
+ ?line {ok, Tracer} = fprof:profile(start),
+ ?line TS2 = erlang:now(),
+ ?line ok = fprof:apply(?MODULE, create_file_slow, [DataFile, 1024],
+ [{tracer, Tracer}, continue]),
+ ?line TS3 = erlang:now(),
+ ?line ok = fprof:profile(stop),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(DataFile),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc3 = ts_sub(TS3, TS2),
+ ?line io:format("ts:~w, fprof:~w, bare:~w.~n", [Acc, Acc3, Acc1]),
+ {comment, io_lib:format("~p times slower", [Acc3/Acc1])}.
+
+%%%---------------------------------------------------------------------
+
+imm_compile(doc) ->
+ ["Tests to compile a small source file ",
+ "with immediate trace to profile"];
+imm_compile(suite) ->
+ [];
+imm_compile(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:minutes(20)),
+ ?line DataDir = ?config(data_dir, Config),
+ ?line SourceFile = filename:join(DataDir, "foo.erl"),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_imm_compile.analysis"),
+ ?line ok = fprof:stop(kill),
+ ?line catch eprof:stop(),
+ %%
+ ?line {ok, foo, _} = compile:file(SourceFile, [binary]),
+ ?line TS0 = erlang:now(),
+ ?line {ok, foo, _} = compile:file(SourceFile, [binary]),
+ ?line TS1 = erlang:now(),
+ %%
+ ?line profiling = eprof:start_profiling([self()]),
+ ?line TS2 = erlang:now(),
+ ?line {ok, foo, _} = compile:file(SourceFile, [binary]),
+ ?line TS3 = erlang:now(),
+ ?line profiling_stopped = eprof:stop_profiling(),
+ %%
+ ?line eprof:analyse(),
+ ?line stopped = eprof:stop(),
+ %%
+ ?line {ok, Tracer} = fprof:profile(start),
+ ?line ok = fprof:trace([start, {tracer, Tracer}]),
+ ?line TS4 = erlang:now(),
+ ?line {ok, foo, _} = compile:file(SourceFile, [binary]),
+ ?line TS5 = erlang:now(),
+ ?line ok = fprof:trace(stop),
+ %%
+ ?line io:format("Analysing...~n"),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n", [P]),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc3 = ts_sub(TS3, TS2),
+ ?line Acc5 = ts_sub(TS5, TS4),
+ ?line io:format("Verifying...~n"),
+ ?line ok = verify(T, P),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}] | _] ->
+ ok
+ end,
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line io:format("~p (plain), ~p (eprof), ~p (fprof), ~p(cpu)~n",
+ [Acc1/1000, Acc3/1000, Acc5/1000, Acc/1000]),
+ {comment, io_lib:format("~p/~p (fprof/eprof) times slower",
+ [Acc5/Acc1, Acc3/Acc1])}.
+
+%%%---------------------------------------------------------------------
+
+cpu_create_file_slow(doc) ->
+ ["Tests the create_file_slow benchmark using cpu_time"];
+cpu_create_file_slow(suite) ->
+ [];
+cpu_create_file_slow(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(40)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line TraceFile =
+ filename:join(PrivDir, ?MODULE_STRING"_cpu_create_file_slow.trace"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_cpu_create_file_slow.analysis"),
+ ?line DataFile =
+ filename:join(PrivDir, ?MODULE_STRING"_cpu_create_file_slow.data"),
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line Result = (catch fprof:apply(?MODULE, create_file_slow,
+ [DataFile, 1024],
+ [{file, TraceFile}, cpu_time])),
+ ?line TS1 = erlang:now(),
+ ?line TestResult =
+ case Result of
+ ok ->
+ ?line ok = fprof:profile(file, TraceFile),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line check_own_and_acc(TraceFile,AnalysisFile),
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(DataFile),
+ ?line file:delete(TraceFile),
+ ?line file:delete(AnalysisFile),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line io:format("cpu_ts:~w, fprof:~w~n", [Acc, Acc1]),
+ {comment, io_lib:format("~p% cpu utilization",
+ [100*Acc/Acc1])};
+ {'EXIT', not_supported} ->
+ case {os:type(), os:version()} of
+ {{unix, sunos}, {Major, Minor, _}}
+ when Major >= 5, Minor >= 7 ->
+ test_server:fail(Result);
+ _ ->
+ {skipped, "not_supported"}
+ end;
+ _ ->
+ test_server:fail(Result)
+ end,
+ ?line ?t:timetrap_cancel(Timetrap),
+ TestResult.
+
+
+
+%%%---------------------------------------------------------------------
+%%% Functions to test
+%%%---------------------------------------------------------------------
+
+
+
+%% Stack recursive seq
+seq(Stop, Stop, Succ) when is_function(Succ) ->
+ [Stop];
+seq(Start, Stop, Succ) when is_function(Succ) ->
+ [Start | seq(Succ(Start), Stop, Succ)].
+
+
+
+%% Tail recursive seq, result list is reversed
+seq_r(Start, Stop, Succ) when is_function(Succ) ->
+ seq_r(Start, Stop, Succ, []).
+
+seq_r(Stop, Stop, _, R) ->
+ [Stop | R];
+seq_r(Start, Stop, Succ, R) ->
+ seq_r(Succ(Start), Stop, Succ, [Start | R]).
+
+
+
+create_file_slow(Name, N) when is_integer(N), N >= 0 ->
+ {ok, FD} =
+ file:open(Name, [raw, write, delayed_write, binary]),
+ if N > 256 ->
+ ok = file:write(FD,
+ lists:map(fun (X) -> <<X:32/unsigned>> end,
+ lists:seq(0, 255))),
+ ok = create_file_slow(FD, 256, N);
+ true ->
+ ok = create_file_slow(FD, 0, N)
+ end,
+ ok = file:close(FD).
+
+create_file_slow(_FD, M, M) ->
+ ok;
+create_file_slow(FD, M, N) ->
+ ok = file:write(FD, <<M:32/unsigned>>),
+ create_file_slow(FD, M+1, N).
+
+
+
+%%%---------------------------------------------------------------------
+%%% Profile verification functions
+%%%---------------------------------------------------------------------
+
+
+
+verify(Tab, [{analysis_options, _},
+ [{totals, Cnt, Acc, Own} | _] | Processes]) ->
+ Processes_1 =
+ lists:map(
+ fun ([{Proc, Cnt_P, undefined, Own_P} | _]) ->
+ case sum_process(Tab, Proc) of
+ {Proc, Cnt_P, Acc_P, Own_P} = Clocks
+ when Acc_P >= Own_P ->
+ Clocks;
+ Weird ->
+ throw({error, [?MODULE, ?LINE, Weird]})
+ end
+ end,
+ Processes),
+ case lists:foldl(
+ fun ({_, Cnt_P2, Acc_P2, Own_P2},
+ {totals, Cnt_T, Acc_T, Own_T}) ->
+ {totals, Cnt_P2+Cnt_T, Acc_P2+Acc_T, Own_P2+Own_T}
+ end,
+ {totals, 0, 0, 0},
+ Processes_1) of
+ {totals, Cnt, Acc_T, Own} when Acc_T >= Acc ->
+ ok;
+ Weird ->
+ throw({error, [?MODULE, ?LINE, Weird]})
+ end.
+
+
+
+sum_process(Tab, Proc) ->
+ ets_select_fold(
+ Tab, [{{{Proc, '_'}, '_'}, [], ['$_']}], 100,
+ fun ({{P, MFA}, {Callers, {MFA, Cnt, Acc, Own}, Called}},
+ {P, Cnt_P, Acc_P, Own_P}) when P == Proc ->
+ ok = verify_callers(Tab, Proc, MFA, Callers),
+ ok = verify_called(Tab, Proc, MFA, Called),
+ {P, Cnt+Cnt_P, Acc+Acc_P, Own+Own_P};
+ (Weird, Clocks) ->
+ throw({error, [?MODULE, ?LINE, Weird, Clocks]})
+ end,
+ {Proc, 0, 0, 0}).
+
+verify_callers(_, _, _, []) ->
+ ok;
+verify_callers(Tab, Proc, MFA, [{Caller, Cnt, Acc, Own} | Tail]) ->
+ Id = {Proc, Caller},
+ case ets:lookup(Tab, Id) of
+ [{Id, {_, {Caller, _, _, _}, Called}}] ->
+ case lists:keysearch(MFA, 1, Called) of
+ {value, {MFA, Cnt, Acc, Own}} ->
+ verify_callers(Tab, Proc, MFA, Tail);
+ false ->
+ throw({error, [?MODULE, ?LINE, MFA, Id]})
+ end;
+ Weird ->
+ throw({error, [?MODULE, ?LINE, Weird]})
+ end.
+
+verify_called(_, _, _, []) ->
+ ok;
+verify_called(Tab, Proc, MFA, [{Called, Cnt, Acc, Own} | Tail]) ->
+ Id = {Proc, Called},
+ case ets:lookup(Tab, Id) of
+ [{Id, {Callers, {Called, _, _, _}, _}}] ->
+ case lists:keysearch(MFA, 1, Callers) of
+ {value, {MFA, Cnt, Acc, Own}} ->
+ verify_called(Tab, Proc, MFA, Tail);
+ false ->
+ throw({error, [?MODULE, ?LINE, MFA, Id]})
+ end;
+ Weird ->
+ throw({error, [?MODULE, ?LINE, Weird]})
+ end.
+
+
+
+%% Parse a analysis file and return an Ets table with all function entries,
+%% and a list of process entries. Checks the concistency of the function
+%% entries when they are read.
+parse(Filename) ->
+ case file:open(Filename, [read]) of
+ {ok, FD} ->
+ Result = parse_stream(FD),
+ file:close(FD),
+ Result;
+ Error ->
+ Error
+ end.
+
+parse_stream(FD) ->
+ Tab = ets:new(fprof_SUITE, []),
+ parse_stream(FD, Tab, [], void).
+
+parse_stream(FD, Tab, R, Proc) ->
+ case catch io:read(FD, '') of
+ {'EXIT', _} ->
+ {error, [?MODULE, ?LINE]};
+ {ok, Term} ->
+ case parse_term(Term) of
+ {ok, {analysis_options, _} = Term_1}
+ when Proc == void ->
+ parse_stream(FD, Tab, [Term_1 | R], analysis_options);
+ {ok, [{totals, _, _, _} | _] = Term_1}
+ when Proc == analysis_options ->
+ parse_stream(FD, Tab, [Term_1 | R], totals);
+ {ok, [{P, _, _, _} | _] = Term_1} ->
+ parse_stream(FD, Tab, [Term_1 | R], P);
+ {ok, {_Callers, {MFA, _, _, _}, _Called} = Term_1}
+ when Proc == totals; is_list(Proc) ->
+ ets:insert(Tab, {{Proc, MFA}, Term_1}),
+ parse_stream(FD, Tab, R, Proc);
+ {ok, Term_1} ->
+ {error, [?MODULE, ?LINE, Term_1]};
+ E ->
+ E
+ end;
+ eof ->
+ {ok, [Tab, lists:reverse(R)]};
+ Error ->
+ Error
+ end.
+
+parse_term({Callers, Func, Called})
+ when is_list(Callers), is_list(Called) ->
+ Callers_1 = lists:map(fun parse_clocks/1, Callers),
+ Func_1 = parse_clocks(Func),
+ Called_1 = lists:map(fun parse_clocks/1, Called),
+ Result = {Callers_1, Func_1, Called_1},
+ case chk_invariant(Result) of
+ ok ->
+ {ok, Result};
+ Error ->
+ Error
+ end;
+parse_term([{_, _, _, _} = Clocks | Tail]) ->
+ {ok, [parse_clocks(Clocks) | Tail]};
+parse_term(Term) ->
+ {ok, Term}.
+
+parse_clocks({MFA, Cnt, undefined, Own}) ->
+ {MFA, Cnt, undefined, round(Own*1000)};
+parse_clocks({MFA, Cnt, Acc, Own}) ->
+ {MFA, Cnt, round(Acc*1000), round(Own*1000)};
+parse_clocks(Clocks) ->
+ Clocks.
+
+
+
+chk_invariant({Callers, {MFA, Cnt, Acc, Own}, Called} = Term) ->
+ {_, Callers_Cnt, Callers_Acc, Callers_Own} = Callers_Sum = sum(Callers),
+% {_, Called_Cnt, Called_Acc, Called_Own} = Called_Sum = sum(Called),
+ case {MFA,
+ lists:keymember(suspend, 1, Callers),
+ lists:keymember(garbage_collect, 1, Callers),
+ Called} of
+ {suspend, false, _, []} ->
+ ok;
+ {suspend, _, _, _} = Weird ->
+ {error, [?MODULE, ?LINE, Weird, Term]};
+ {garbage_collect, false, false, []} ->
+ ok;
+ {garbage_collect, false, false, [{suspend, _, _, _}]} ->
+ ok;
+ {garbage_collect, _, _, _} = Weird ->
+ {error, [?MODULE, ?LINE, Weird, Term]};
+ {undefined, false, false, _}
+ when Callers == [], Cnt == 0, Acc == 0, Own == 0 ->
+ ok;
+ {undefined, _, _, _} = Weird ->
+ {error, [?MODULE, ?LINE, Weird, Term]};
+ {_, _, _, _} ->
+ case chk_self_call(Term) of
+ true when Callers_Cnt /= Cnt; Callers_Acc /= Acc;
+ Callers_Own /= Own ->
+ {error, [?MODULE, ?LINE, Callers_Sum, Term]};
+% true when Called_Acc + Own /= Acc ->
+% io:format("WARNING: ~p:~p, ~p, ~p.~n",
+% [?MODULE, ?LINE, Term, Called_Sum]),
+% {error, [?MODULE, ?LINE, Term, Called_Sum]};
+% ok;
+ true ->
+ ok;
+ false ->
+ {error, [?MODULE, ?LINE, Term]}
+ end
+ end.
+
+ts_sub({A, B, C}, {A0, B0, C0}) ->
+ ((A - A0)*1000000000000 + (B - B0))*1000000 + C - C0.
+
+sum(Funcs) ->
+ {sum, _Cnt, _Acc, _Own} =
+ lists:foldl(
+ fun ({_, C1, A1, O1}, {sum, C2, A2, O2}) ->
+ {sum, C1+C2, A1+A2, O1+O2}
+ end,
+ {sum, 0, 0, 0},
+ Funcs).
+
+chk_self_call({Callers, {MFA, _Cnt, _Acc, _Own}, Called}) ->
+ case lists:keysearch(MFA, 1, Callers) of
+ false ->
+ true;
+ {value, {MFA, C, 0, O}} ->
+ case lists:keysearch(MFA, 1, Called) of
+ false ->
+ false;
+ {value, {MFA, C, 0, O}} ->
+ true;
+ {value, _} ->
+ false
+ end;
+ {value, _} ->
+ false
+ end.
+
+
+
+%%%---------------------------------------------------------------------
+%%% Fairly generic support functions
+%%%---------------------------------------------------------------------
+
+
+ets_select_fold(Table, MatchSpec, Limit, Fun, Acc) ->
+ ets:safe_fixtable(Table, true),
+ ets_select_fold_1(ets:select(Table, MatchSpec, Limit), Fun, Acc).
+
+ets_select_fold_1('$end_of_table', _, Acc) ->
+ Acc;
+ets_select_fold_1({Matches, Continuation}, Fun, Acc) ->
+ ets_select_fold_1(ets:select(Continuation),
+ Fun,
+ lists:foldl(Fun, Acc, Matches)).
+
+
+
+% ets_select_foreach(Table, MatchSpec, Limit, Fun) ->
+% ets:safe_fixtable(Table, true),
+% ets_select_foreach_1(ets:select(Table, MatchSpec, Limit), Fun).
+
+% ets_select_foreach_1('$end_of_table', _) ->
+% ok;
+% ets_select_foreach_1({Matches, Continuation}, Fun) ->
+% lists:foreach(Fun, Matches),
+% ets_select_foreach_1(ets:select(Continuation), Fun).
+
+
+%%%---------------------------------------------------------------------
+%%% Simple smulation of fprof used for checking own and acc times for
+%%% each function.
+%%% The function 'undefined' is ignored
+%%%---------------------------------------------------------------------
+
+%% check_own_and_acc_traced(TraceFile, AnalysisFile) ->
+%% check_own_and_acc(TraceFile, AnalysisFile, fun handle_trace_traced/2).
+
+check_own_and_acc(TraceFile, AnalysisFile) ->
+ check_own_and_acc(TraceFile, AnalysisFile, fun handle_trace/2).
+
+check_own_and_acc(TraceFile, AnalysisFile, HandlerFun) ->
+ dbg:trace_client(file,TraceFile,{HandlerFun,{init,self()}}),
+ receive {result,Result} ->
+ compare(Result,get_own_and_acc_from_analysis(AnalysisFile))
+ end.
+
+%% handle_trace_traced(Trace, Msg) ->
+%% io:format("handle_trace_traced(~p, ~p).", [Trace, Msg]),
+%% handle_trace(Trace, Msg).
+
+handle_trace(Trace,{init,Parent}) ->
+ ?dbg("~p",[start]),
+ ets:new(fprof_verify_tab,[named_table]),
+ handle_trace(Trace,Parent);
+handle_trace({trace_ts,Pid,in,MFA,TS},P) ->
+ ?dbg("~p",[{{in,Pid,MFA},get(Pid)}]),
+ case get(Pid) of
+ [suspend|[suspend|_]=NewStack] ->
+ T = ts_sub(TS,get({Pid,last_ts})),
+ update_acc(Pid,NewStack,T),
+ put(Pid,NewStack);
+ [suspend|NewStack] = Stack ->
+ T = ts_sub(TS,get({Pid,last_ts})),
+ update_acc(Pid,Stack,T),
+ put(Pid,NewStack);
+ [] ->
+ put(Pid,[MFA]),
+ insert(Pid,MFA);
+ undefined ->
+ put(first_ts,TS),
+ put(Pid,[MFA]),
+ insert(Pid,MFA)
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,out,_MfaOrZero,TS},P) ->
+ ?dbg("~p",[{{out,Pid,_MfaOrZero},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ case get(Pid) of
+ [suspend|S] = Stack ->
+ update_acc(Pid,S,T),
+ put(Pid,[suspend|Stack]);
+ [MFA|_] = Stack ->
+ insert(Pid,suspend),
+ update_own(Pid,MFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[suspend|Stack]);
+ [] ->
+ insert(Pid,suspend),
+ put(Pid,[suspend])
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,call,MFA,{cp,Caller},TS},P) ->
+ ?dbg("~p",[{{call,Pid,MFA},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ case get(Pid) of
+ [MFA|_] = Stack ->
+ %% recursive
+ update_own(Pid,MFA,T),
+ update_acc(Pid,Stack,T);
+ [CallingMFA|_] = Stack when Caller==undefined ->
+ insert(Pid,MFA),
+ update_own(Pid,CallingMFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[MFA|Stack]);
+ [] when Caller==undefined ->
+ insert(Pid,MFA),
+ insert(Pid,MFA),
+ put(Pid,[MFA]);
+ Stack0 ->
+ Stack = [CallingMFA|_] = insert_caller(Caller,Stack0,[]),
+ insert(Pid,MFA),
+ insert(Pid,Caller),
+ update_own(Pid,CallingMFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[MFA|Stack])
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,return_to,MFA,TS},P) ->
+ ?dbg("~p",[{{return_to,Pid,MFA},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ case get(Pid) of
+ [MFA|_] = Stack ->
+ %% recursive
+ update_own(Pid,MFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,Stack);
+ [ReturnFromMFA,MFA|RestOfStack] = Stack ->
+ update_own(Pid,ReturnFromMFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[MFA|RestOfStack]);
+ [ReturnFromMFA|RestOfStack] = Stack ->
+ update_own(Pid,ReturnFromMFA,T),
+ update_acc(Pid,Stack,T),
+ case find_return_to(MFA,RestOfStack) of
+ [] when MFA==undefined ->
+ put(Pid,[]);
+ [] ->
+ insert(Pid,MFA),
+ put(Pid,[MFA]);
+ NewStack ->
+ put(Pid,NewStack)
+ end
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,gc_start,_,TS},P) ->
+ ?dbg("~p",[{{gc_start,Pid},get(Pid)}]),
+ case get(Pid) of
+ [suspend|_] = Stack ->
+ T = ts_sub(TS,get({Pid,last_ts})),
+ insert(Pid,garbage_collect),
+ update_acc(Pid,Stack,T),
+ put(Pid,[garbage_collect|Stack]);
+ [CallingMFA|_] = Stack ->
+ T = ts_sub(TS,get({Pid,last_ts})),
+ insert(Pid,garbage_collect),
+ update_own(Pid,CallingMFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[garbage_collect|Stack]);
+ undefined ->
+ put(first_ts,TS),
+ put(Pid,[garbage_collect]),
+ insert(Pid,garbage_collect)
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,gc_end,_,TS},P) ->
+ ?dbg("~p",[{{gc_end,Pid},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ case get(Pid) of
+ [garbage_collect|RestOfStack] = Stack ->
+ update_own(Pid,garbage_collect,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,RestOfStack)
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,spawn,NewPid,{M,F,Args},TS},P) ->
+ MFA = {M,F,length(Args)},
+ ?dbg("~p",[{{spawn,Pid,NewPid,MFA},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ put({NewPid,last_ts},TS),
+ put(NewPid,[suspend,MFA]),
+ insert(NewPid,suspend),
+ insert(NewPid,MFA),
+ case get(Pid) of
+ [SpawningMFA|_] = Stack ->
+ update_own(Pid,SpawningMFA,T),
+ update_acc(Pid,Stack,T)
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,exit,_Reason,TS},P) ->
+ ?dbg("~p",[{{exit,Pid,_Reason},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ case get(Pid) of
+ [DyingMFA|_] = Stack ->
+ update_own(Pid,DyingMFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[]);
+ [] ->
+ ok
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,_,Link,_,_},P)
+ when Link==link;
+ Link==unlink;
+ Link==getting_linked;
+ Link==getting_unlinked ->
+ P;
+handle_trace(end_of_trace,P) ->
+ ?dbg("~p",['end']),
+ Result = ets:tab2list(fprof_verify_tab),
+ {TotOwn,ProcOwns} = get_proc_owns(Result,[],0),
+ TotAcc = ts_sub(get_last_ts(),get(first_ts)),
+ P ! {result,[{totals,TotAcc,TotOwn}|ProcOwns]++Result},
+ P;
+handle_trace(Other,_P) ->
+ exit({unexpected,Other}).
+
+find_return_to(MFA,[MFA|_]=Stack) ->
+ Stack;
+find_return_to(MFA,[_|Stack]) ->
+ find_return_to(MFA,Stack);
+find_return_to(_MFA,[]) ->
+ [].
+
+insert_caller(MFA,[MFA|Rest],Result) ->
+ lists:reverse(Result)++[MFA|Rest];
+insert_caller(MFA,[Other|Rest],Result) ->
+ insert_caller(MFA,Rest,[Other|Result]);
+insert_caller(MFA,[],Result) ->
+ lists:reverse([MFA|Result]).
+
+insert(Pid,MFA) ->
+ case ets:member(fprof_verify_tab,{Pid,MFA}) of
+ false ->
+ ets:insert(fprof_verify_tab,{{Pid,MFA},0,0});
+ true ->
+ ok
+ end.
+
+update_own(Pid,MFA,T) ->
+ ets:update_counter(fprof_verify_tab,{Pid,MFA},{3,T}).
+
+update_acc(Pid,[MFA|Rest],T) ->
+ case lists:member(MFA,Rest) of
+ true ->
+ %% Only charge one time for recursive functions
+ ok;
+ false ->
+ ets:update_counter(fprof_verify_tab,{Pid,MFA},{2,T})
+ end,
+ update_acc(Pid,Rest,T);
+update_acc(_Pid,[],_T) ->
+ ok.
+
+
+get_last_ts() ->
+ get_last_ts(get(),{0,0,0}).
+get_last_ts([{{_,last_ts},TS}|Rest],Last) when TS>Last ->
+ get_last_ts(Rest,TS);
+get_last_ts([_|Rest],Last) ->
+ get_last_ts(Rest,Last);
+get_last_ts([],Last) ->
+ Last.
+
+get_proc_owns([{{Pid,_MFA},_Acc,Own}|Rest],Result,Sum) ->
+ NewResult =
+ case lists:keysearch(Pid,1,Result) of
+ {value,{Pid,undefined,PidOwn}} ->
+ lists:keyreplace(Pid,1,Result,{Pid,undefined,PidOwn+Own});
+ false ->
+ [{Pid,undefined,Own}|Result]
+ end,
+ get_proc_owns(Rest,NewResult,Sum+Own);
+get_proc_owns([],Result,Sum) ->
+ {Sum,Result}.
+
+
+compare([X|Rest],FprofResult) ->
+ FprofResult1 =
+ case lists:member(X,FprofResult) of
+ true ->
+ ?dbg("~p",[X]),
+ lists:delete(X,FprofResult);
+ false ->
+ case lists:keysearch(element(1,X),1,FprofResult) of
+ {value,Fprof} ->
+ put(compare_error,true),
+ io:format("Error: Different values\n"
+ "Fprof: ~p\n"
+ "Simulator: ~p",[Fprof,X]),
+ lists:delete(Fprof,FprofResult);
+ false ->
+ put(compare_error,true),
+ io:format("Error: Missing in fprof: ~p",[X]),
+ FprofResult
+ end
+ end,
+ compare(Rest,FprofResult1);
+compare([],Rest) ->
+ case {remove_undefined(Rest,[]),get(compare_error)} of
+ {[],undefined} -> ok;
+ {Error,_} ->
+ case Error of
+ [] -> ok;
+ _ -> io:format("\nMissing in simulator results:\n~p\n",[Error])
+ end,
+ ?t:fail({error,mismatch_between_simulator_and_fprof})
+ end.
+
+remove_undefined([{{_Pid,undefined},_,_}|Rest],Result) ->
+ remove_undefined(Rest,Result);
+remove_undefined([X|Rest],Result) ->
+ remove_undefined(Rest,[X|Result]);
+remove_undefined([],Result) ->
+ Result.
+
+get_own_and_acc_from_analysis(Log) ->
+ case file:consult(Log) of
+ {ok,[_Options,[{totals,_,TotAcc,TotOwn}]|Rest]} ->
+ get_own_and_acc(undefined,Rest,
+ [{totals,m1000(TotAcc),m1000(TotOwn)}]);
+ Error ->
+ exit({error,{cant_open,Log,Error}})
+ end.
+
+get_own_and_acc(_,[[{PidStr,_,Acc,Own}|_]|Rest],Result) ->
+ Pid = list_to_pid(PidStr),
+ get_own_and_acc(Pid,Rest,[{Pid,m1000(Acc),m1000(Own)}|Result]);
+get_own_and_acc(Pid,[{_Callers,{MFA,_,Acc,Own},_Called}|Rest],Result) ->
+ get_own_and_acc(Pid,Rest,[{{Pid,MFA},m1000(Acc),m1000(Own)}|Result]);
+get_own_and_acc(_,[],Result) ->
+ lists:reverse(Result).
+
+m1000(undefined) ->
+ undefined;
+m1000(X) ->
+ round(X*1000).
+
diff --git a/lib/tools/test/fprof_SUITE_data/foo.erl b/lib/tools/test/fprof_SUITE_data/foo.erl
new file mode 100644
index 0000000000..eaa8132b1e
--- /dev/null
+++ b/lib/tools/test/fprof_SUITE_data/foo.erl
@@ -0,0 +1,41 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+-module(foo).
+
+-export([create_file_slow/2]).
+
+
+
+create_file_slow(Name, N) when integer(N), N >= 0 ->
+ {ok, FD} =
+ file:open(Name, [raw, write, delayed_write, binary]),
+ if N > 256 ->
+ ok = file:write(FD,
+ lists:map(fun (X) -> <<X:32/unsigned>> end,
+ lists:seq(0, 255))),
+ ok = create_file_slow(FD, 256, N);
+ true ->
+ ok = create_file_slow(FD, 0, N)
+ end,
+ ok = file:close(FD).
+
+create_file_slow(FD, M, M) ->
+ ok;
+create_file_slow(FD, M, N) ->
+ ok = file:write(FD, <<M:32/unsigned>>),
+ create_file_slow(FD, M+1, N).
diff --git a/lib/tools/test/ignore_cores.erl b/lib/tools/test/ignore_cores.erl
new file mode 120000
index 0000000000..8902a469ef
--- /dev/null
+++ b/lib/tools/test/ignore_cores.erl
@@ -0,0 +1 @@
+../../../erts/test/ignore_cores.erl \ No newline at end of file
diff --git a/lib/tools/test/instrument_SUITE.erl b/lib/tools/test/instrument_SUITE.erl
new file mode 100644
index 0000000000..da5930e015
--- /dev/null
+++ b/lib/tools/test/instrument_SUITE.erl
@@ -0,0 +1,129 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(instrument_SUITE).
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2]).
+
+-export(['+Mim true'/1, '+Mis true'/1]).
+
+-include("test_server.hrl").
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=?t:timetrap(10000),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog=?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+all(suite) -> ['+Mim true', '+Mis true'].
+
+'+Mim true'(doc) -> ["Check that memory data can be read and processed"];
+'+Mim true'(suite) -> [];
+'+Mim true'(Config) when is_list(Config) ->
+ ?line Node = start_slave("+Mim true"),
+ ?line MD = rpc:call(Node, instrument, memory_data, []),
+ ?line [{total,[{sizes,S1,S2,S3},{blocks,B1,B2,B3}]}]
+ = rpc:call(Node, instrument, memory_status, [total]),
+ ?line stop_slave(Node),
+ ?line true = S1 =< S2,
+ ?line true = S2 =< S3,
+ ?line true = B1 =< B2,
+ ?line true = B2 =< B3,
+ ?line MDS = instrument:sort(MD),
+ ?line {Low, High} = instrument:mem_limits(MDS),
+ ?line true = Low < High,
+ ?line {_, AL} = MDS,
+ ?line SumBlocks = instrument:sum_blocks(MD),
+ ?line case SumBlocks of
+ N when is_integer(N) ->
+ ?line N = lists:foldl(fun ({_,_,Size,_}, Sum) ->
+ Size+Sum
+ end,
+ 0,
+ AL),
+ ?line N =< S3;
+ Other ->
+ ?line ?t:fail(Other)
+ end,
+ ?line lists:foldl(
+ fun ({TDescr,Addr,Size,Proc}, MinAddr) ->
+ ?line true = TDescr /= invalid_type,
+ ?line true = is_integer(TDescr),
+ ?line true = is_integer(Addr),
+ ?line true = is_integer(Size),
+ ?line true = Addr >= MinAddr,
+ ?line case Proc of
+ {0, Number, Serial} ->
+ ?line true = is_integer(Number),
+ ?line true = is_integer(Serial);
+ undefined ->
+ ok;
+ BadProc ->
+ ?line ?t:fail({badproc, BadProc})
+ end,
+ ?line NextMinAddr = Addr+Size,
+ ?line true = NextMinAddr =< High,
+ ?line NextMinAddr
+ end,
+ Low,
+ AL),
+ ?line {_, DAL} = instrument:descr(MDS),
+ ?line lists:foreach(
+ fun ({TDescr,_,_,Proc}) ->
+ ?line true = TDescr /= invalid_type,
+ ?line true = is_atom(TDescr) orelse is_list(TDescr),
+ ?line true = is_pid(Proc) orelse Proc == undefined
+ end,
+ DAL),
+ ?line ASL = lists:map(fun ({_,A,S,_}) -> {A,S} end, AL),
+ ?line ASL = lists:map(fun ({_,A,S,_}) -> {A,S} end, DAL),
+ ?line instrument:holes(MDS),
+ ?line {comment,
+ "total status - sum of blocks = " ++ integer_to_list(S1-SumBlocks)}.
+
+'+Mis true'(doc) -> ["Check that memory data can be read and processed"];
+'+Mis true'(suite) -> [];
+'+Mis true'(Config) when is_list(Config) ->
+ ?line Node = start_slave("+Mis true"),
+ ?line [{total,[{sizes,S1,S2,S3},{blocks,B1,B2,B3}]}]
+ = rpc:call(Node, instrument, memory_status, [total]),
+ ?line true = S1 =< S2,
+ ?line true = S2 =< S3,
+ ?line true = B1 =< B2,
+ ?line true = B2 =< B3,
+ ?line true = is_list(rpc:call(Node,instrument,memory_status,[allocators])),
+ ?line true = is_list(rpc:call(Node,instrument,memory_status,[classes])),
+ ?line true = is_list(rpc:call(Node,instrument,memory_status,[types])),
+ ?line ok.
+
+start_slave(Args) ->
+ ?line {A, B, C} = now(),
+ ?line MicroSecs = A*1000000000000 + B*1000000 + C,
+ ?line Name = "instr_" ++ integer_to_list(MicroSecs),
+ ?line Pa = filename:dirname(code:which(?MODULE)),
+ ?line {ok, Node} = ?t:start_node(list_to_atom(Name),
+ slave,
+ [{args, "-pa " ++ Pa ++ " " ++ Args}]),
+ ?line Node.
+
+
+stop_slave(Node) ->
+ ?line true = ?t:stop_node(Node).
diff --git a/lib/tools/test/make_SUITE.erl b/lib/tools/test/make_SUITE.erl
new file mode 100644
index 0000000000..72dccdb465
--- /dev/null
+++ b/lib/tools/test/make_SUITE.erl
@@ -0,0 +1,295 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(make_SUITE).
+
+-export([all/1, make_all/1, make_files/1]).
+-export([otp_6057_init/1,
+ otp_6057_a/1, otp_6057_b/1, otp_6057_c/1,
+ otp_6057_end/1]).
+
+-include("test_server.hrl").
+
+-include_lib("kernel/include/file.hrl").
+
+%% in ./make_SUITE_data there are test-files used by this
+%% test suite. There are 4 files named test1.erl ... test5.erl.
+%% The test files are attacked in various ways in order to put make on trial.
+%%
+%% Also, and Emakefile exists in ./make_SUITE_data. This file specifies
+%% that the file :"test5.erl" shall be compiled with the 'S' option,
+%% i.e. produce "test5.S" instead of "test5.<objext>"
+
+all(suite) -> [make_all, make_files,
+ {conf, otp_6057_init,
+ [otp_6057_a,otp_6057_b,otp_6057_c], otp_6057_end}].
+
+test_files() -> ["test1", "test2", "test3", "test4"].
+
+make_all(suite) -> [];
+make_all(Config) when is_list(Config) ->
+ ?line Current = prepare_data_dir(Config),
+ ?line up_to_date = make:all(),
+ ?line ok = ensure_exists(test_files()),
+ ?line ok = ensure_exists(["test5"],".S"), % Emakefile: [{test5,['S']}
+ ?line file:set_cwd(Current),
+ ?line ensure_no_messages(),
+ ok.
+
+make_files(suite) -> [];
+make_files(Config) when is_list(Config) ->
+ ?line Current = prepare_data_dir(Config),
+
+ %% Make files that exist.
+
+ ?line Files = [test1, test2],
+ ?line up_to_date = make:files(Files), % ok files
+ ?line ok = ensure_exists(Files),
+
+ ?line error = make:files([test1,test7]), % non existing file
+ ?line up_to_date = make:files([test1,test2],[debug_info]), % with option
+
+ ?line file:set_cwd(Current),
+ ?line ensure_no_messages(),
+ ok.
+
+
+%% Moves to the data directory of this suite, clean it from any object
+%% files (*.jam for a JAM emulator). Returns the previous directory.
+prepare_data_dir(Config) ->
+ ?line {ok, Current} = file:get_cwd(),
+ ?line {value, {data_dir, Dir}} = lists:keysearch(data_dir, 1, Config),
+ ?line file:set_cwd(Dir),
+ ?line {ok, Files} = file:list_dir("."),
+ ?line delete_obj(Files, code:objfile_extension()),
+ ?line ensure_no_messages(),
+ Current.
+
+delete_obj([File|Rest], ObjExt) ->
+ ?line case filename:extension(File) of
+ ObjExt -> file:delete(File);
+ ".S" -> file:delete(File);
+ _ -> ok
+ end,
+ ?line delete_obj(Rest, ObjExt);
+delete_obj([], _) ->
+ ok.
+
+
+
+%% Ensure that the given object files exists.
+ensure_exists(Names) ->
+ ensure_exists(Names, code:objfile_extension()).
+
+ensure_exists([Name|Rest], ObjExt) when is_atom(Name) ->
+ ensure_exists([atom_to_list(Name)|Rest], ObjExt);
+ensure_exists([Name|Rest], ObjExt) ->
+ case filelib:is_regular(Name++ObjExt) of
+ true ->
+ ensure_exists(Rest, ObjExt);
+ false ->
+ Name++ObjExt
+ end;
+ensure_exists([], _) ->
+ ok.
+
+otp_6057_init(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line PrivDir = ?config(priv_dir, Config),
+
+ %% Create the directories PrivDir/otp_6057/src1, /src2 and /ebin
+ Src1 = filename:join([PrivDir, otp_6057, src1]),
+ Src2 = filename:join([PrivDir, otp_6057, src2]),
+ Ebin = filename:join([PrivDir, otp_6057, ebin]),
+ ?line ok = file:make_dir(filename:join(PrivDir, otp_6057)),
+ ?line ok = file:make_dir(Src1),
+ ?line ok = file:make_dir(Src2),
+ ?line ok = file:make_dir(Ebin),
+
+ %% Copy test1.erl and test2.erl to src1, and test3.erl to src2
+ Test1orig = filename:join(DataDir, "test1.erl"),
+ Test2orig = filename:join(DataDir, "test2.erl"),
+ Test3orig = filename:join(DataDir, "test3.erl"),
+ Test1 = filename:join(Src1, "test1.erl"),
+ Test2 = filename:join(Src1, "test2.erl"),
+ Test3 = filename:join(Src2, "test3.erl"),
+ ?line {ok, _} = file:copy(Test1orig, Test1),
+ ?line {ok, _} = file:copy(Test2orig, Test2),
+ ?line {ok, _} = file:copy(Test3orig, Test3),
+
+ %% Create an Emakefile in src1
+ Emakefile = filename:join(Src1, "Emakefile"),
+ ?line {ok, Fd} = file:open(Emakefile, write),
+ ?line ok = io:write(Fd, {["test1.erl","test2","../src2/test3"],
+ [{outdir,"../ebin"}]}),
+ ?line ok = io:fwrite(Fd, ".~n", []),
+ ?line ok = file:close(Fd),
+
+ ?line ensure_no_messages(),
+ Config.
+
+otp_6057_a(suite) ->
+ [];
+otp_6057_a(doc) ->
+ ["Test that make:all/0 looks for object file in correct place"];
+otp_6057_a(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+
+ %% Go to src1, saving old CWD
+ ?line {ok, CWD} = file:get_cwd(),
+ Src1 = filename:join([PrivDir, otp_6057, src1]),
+ ?line ok = file:set_cwd(Src1),
+
+ %% Call make:all()
+ ?line up_to_date = make:all(),
+
+ %% Ensure that all beam files are created in the ebin directory
+ Ebin = filename:join([PrivDir, otp_6057, ebin]),
+ Test1 = filename:join(Ebin, test1),
+ Test2 = filename:join(Ebin, test2),
+ Test3 = filename:join(Ebin, test3),
+ case ensure_exists([Test1, Test2, Test3]) of
+ ok -> ok;
+ Missing ->
+ ?line ?t:fail({"missing beam file", Missing})
+ end,
+
+ %% Check creation date of test1.beam and make sure it is not
+ %% recompiled if make:all() is called again.
+ %% (Sleep a while, if the file is recompiled within a second then
+ %% mtime will be the same).
+ ?line {ok, FileInfo1} = file:read_file_info(Test1++".beam"),
+ Date1 = FileInfo1#file_info.mtime,
+ ?t:sleep(?t:seconds(2)),
+ ?line up_to_date = make:all(),
+ ?line {ok, FileInfo2} = file:read_file_info(Test1++".beam"),
+ case FileInfo2#file_info.mtime of
+ Date1 -> ok;
+ _Date2 ->
+ ?line ?t:fail({"recompiled beam file", Test1++".beam"})
+ end,
+
+ %% Remove the beam files
+ ?line ok =
+ ensure_removed([Test1++".beam",Test2++".beam",Test2++".beam"]),
+
+ %% Return to original CWD
+ ?line ok = file:set_cwd(CWD),
+
+ ?line ensure_no_messages(),
+ ok.
+
+otp_6057_b(suite) ->
+ [];
+otp_6057_b(doc) ->
+ ["Test that make:files/1 can handle a file in another directory"];
+otp_6057_b(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+
+ %% Go to src1, saving old CWD
+ ?line {ok, CWD} = file:get_cwd(),
+ Src1 = filename:join([PrivDir, otp_6057, src1]),
+ ?line ok = file:set_cwd(Src1),
+
+ %% Ensure there is no beam file already
+ Ebin = filename:join([PrivDir, otp_6057, ebin]),
+ Test3 = filename:join(Ebin, "test3"),
+ ?line ok = ensure_removed([Test3++".beam"]),
+
+ %% Call make:files/1
+ ?line up_to_date = make:files(["../src2/test3"]),
+
+ %% Ensure that the beam file is created in the ebin directory
+ case ensure_exists([Test3]) of
+ ok -> ok;
+ Missing ->
+ ?line ?t:fail({"missing beam file", Missing})
+ end,
+
+ %% Remove the beam file
+ ?line ok = ensure_removed([Test3++".beam"]),
+
+ %% Return to original CWD
+ ?line ok = file:set_cwd(CWD),
+
+ ?line ensure_no_messages(),
+ ok.
+
+otp_6057_c(suite) ->
+ [];
+otp_6057_c(doc) ->
+ ["Test that make:files/1 find options in Emakefile if a file is "
+ "given with the .erl extension there"];
+otp_6057_c(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+
+ %% Go to src1, saving old CWD
+ ?line {ok, CWD} = file:get_cwd(),
+ Src1 = filename:join([PrivDir, otp_6057, src1]),
+ ?line ok = file:set_cwd(Src1),
+
+ %% Ensure there are no beam files already
+ Ebin = filename:join([PrivDir, otp_6057, ebin]),
+ Test1 = filename:join(Ebin, "test1"),
+ Test2 = filename:join(Ebin, "test2"),
+ ?line ok = ensure_removed([Test1++".beam",Test2++".beam"]),
+
+ %% Call make:files/1
+ ?line up_to_date = make:files([test1, test2]),
+
+ %% Ensure that the beam files are created in the ebin directory
+ Ebin = filename:join([PrivDir, otp_6057, ebin]),
+ case ensure_exists([Test1, Test2]) of
+ ok -> ok;
+ Missing ->
+ ?line ?t:fail({"missing beam file", Missing})
+ end,
+
+ %% Remove the beam files
+ ?line ok = ensure_removed([Test1++".beam", Test2++".beam"]),
+
+ %% Return to original CWD
+ ?line ok = file:set_cwd(CWD),
+
+ ?line ensure_no_messages(),
+ ok.
+
+otp_6057_end(Config) when is_list(Config) ->
+ Config.
+
+ensure_removed([File|Files]) ->
+ file:delete(File),
+ ensure_removed(Files);
+ensure_removed([]) ->
+ ok.
+
+ensure_no_messages() ->
+ ensure_no_messages(0).
+
+ensure_no_messages(N) ->
+ receive
+ Any ->
+ io:format("Unexpected message: ~p", [Any]),
+ ensure_no_messages(N+1)
+ after 0 ->
+ case N of
+ 0 -> ok;
+ N -> ?t:fail()
+ end
+ end.
+
diff --git a/lib/tools/test/make_SUITE_data/Emakefile b/lib/tools/test/make_SUITE_data/Emakefile
new file mode 100644
index 0000000000..ae9abb3cbe
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/Emakefile
@@ -0,0 +1,20 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+
+{test5,['S']}.
+'*'.
diff --git a/lib/tools/test/make_SUITE_data/test1.erl b/lib/tools/test/make_SUITE_data/test1.erl
new file mode 100644
index 0000000000..f4a133008e
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test1.erl
@@ -0,0 +1,10 @@
+-module(test1).
+-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
+-vsn('$Revision: /main/release/2 $').
+-compile(export_all).
+
+f1() ->
+ true.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/make_SUITE_data/test2.erl b/lib/tools/test/make_SUITE_data/test2.erl
new file mode 100644
index 0000000000..5845357c3e
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test2.erl
@@ -0,0 +1,10 @@
+-module(test2).
+-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
+-vsn('$Revision: /main/release/2 $').
+-compile(export_all).
+
+f1() ->
+ true.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/make_SUITE_data/test3.erl b/lib/tools/test/make_SUITE_data/test3.erl
new file mode 100644
index 0000000000..4339260ecb
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test3.erl
@@ -0,0 +1,10 @@
+-module(test3).
+-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
+-vsn('$Revision: /main/release/2 $').
+-compile(export_all).
+
+f1() ->
+ true.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/make_SUITE_data/test4.erl b/lib/tools/test/make_SUITE_data/test4.erl
new file mode 100644
index 0000000000..11b37123f1
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test4.erl
@@ -0,0 +1,10 @@
+-module(test4).
+-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
+-vsn('$Revision: /main/release/2 $').
+-compile(export_all).
+
+f1() ->
+ true.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/make_SUITE_data/test5.erl b/lib/tools/test/make_SUITE_data/test5.erl
new file mode 100644
index 0000000000..108ab8e494
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test5.erl
@@ -0,0 +1,10 @@
+-module(test5).
+-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
+-vsn('$Revision: /main/release/1').
+-compile(export_all).
+
+f1() ->
+ true.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/tools.spec b/lib/tools/test/tools.spec
new file mode 100644
index 0000000000..93d5930472
--- /dev/null
+++ b/lib/tools/test/tools.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../tools_test"}}.
diff --git a/lib/tools/test/tools.spec.win b/lib/tools/test/tools.spec.win
new file mode 100644
index 0000000000..b43d542ff1
--- /dev/null
+++ b/lib/tools/test/tools.spec.win
@@ -0,0 +1,2 @@
+{topcase, {dir, "../tools_test"}}.
+{skip, {emem_SUITE, "Not on windows, yet. FIXME!!!"}}.
diff --git a/lib/tools/test/tools_SUITE.erl b/lib/tools/test/tools_SUITE.erl
new file mode 100644
index 0000000000..6b952f10ab
--- /dev/null
+++ b/lib/tools/test/tools_SUITE.erl
@@ -0,0 +1,56 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(tools_SUITE).
+
+-include("test_server.hrl").
+
+%% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+-define(application, tools).
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_testcase/2, fin_per_testcase/2]).
+
+%% Test cases must be exported.
+-export([app_test/1]).
+
+all(doc) ->
+ [];
+all(suite) ->
+ [app_test].
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+fin_per_testcase(_Case, Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%%
+%%% Test cases starts here.
+%%%
+
+app_test(doc) ->
+ ["Test that the .app file does not contain any `basic' errors"];
+app_test(suite) ->
+ [];
+app_test(Config) when is_list(Config) ->
+ ?line ?t:app_test(tools, tolerant).
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
new file mode 100644
index 0000000000..0bbb3ba0f1
--- /dev/null
+++ b/lib/tools/test/xref_SUITE.erl
@@ -0,0 +1,2743 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-module(xref_SUITE).
+
+%-define(debug, true).
+
+-ifdef(debug).
+-define(format(S, A), io:format(S, A)).
+-define(line, put(line, ?LINE), ).
+-define(config(X,Y), "./log_dir/").
+-define(t,test_server).
+-define(datadir, "xref_SUITE_data").
+-define(privdir, "xref_SUITE_priv").
+-define(copydir, "xref_SUITE_priv/datacopy").
+-else.
+-include("test_server.hrl").
+-define(format(S, A), ok).
+-define(datadir, ?config(data_dir, Conf)).
+-define(privdir, ?config(priv_dir, Conf)).
+-define(copydir, ?config(copy_dir, Conf)).
+-endif.
+
+-export([all/1, init/1, fini/1]).
+
+-export([xref/1,
+ addrem/1, convert/1, intergraph/1, lines/1, loops/1,
+ no_data/1, modules/1]).
+
+-export([files/1,
+ add/1, default/1, info/1, lib/1, read/1, read2/1, remove/1,
+ replace/1, update/1, deprecated/1, trycatch/1,
+ abstract_modules/1, fun_mfa/1, qlc/1]).
+
+-export([analyses/1,
+ analyze/1, basic/1, md/1, q/1, variables/1, unused_locals/1]).
+
+-export([misc/1,
+ format_error/1, otp_7423/1, otp_7831/1]).
+
+-import(lists, [append/2, flatten/1, keysearch/3, member/2, sort/1, usort/1]).
+
+-import(sofs, [converse/1, from_term/1, intersection/2, is_sofs_set/1,
+ range/1, relation_to_family/1, set/1, to_external/1,
+ union/2]).
+
+-export([init_per_testcase/2, fin_per_testcase/2]).
+
+%% Checks some info counters of a server and some relations that should hold.
+-export([check_count/1, check_state/1]).
+
+-include_lib("kernel/include/file.hrl").
+
+-include_lib("tools/src/xref.hrl").
+
+all(suite) ->
+ {conf, init, [xref, files, analyses, misc], fini}.
+
+init(Conf) when is_list(Conf) ->
+ DataDir = ?datadir,
+ PrivDir = ?privdir,
+ ?line CopyDir = fname(PrivDir, "datacopy"),
+ ?line TarFile = fname(PrivDir, "datacopy.tgz"),
+ ?line {ok, Tar} = erl_tar:open(TarFile, [write, compressed]),
+ ?line ok = erl_tar:add(Tar, DataDir, CopyDir, [compressed]),
+ ?line ok = erl_tar:close(Tar),
+ ?line ok = erl_tar:extract(TarFile, [compressed]),
+ ?line ok = file:delete(TarFile),
+ [{copy_dir, CopyDir} | Conf].
+
+fini(Conf) when is_list(Conf) ->
+ %% Nothing.
+ Conf.
+
+init_per_testcase(_Case, Config) ->
+ Dog=?t:timetrap(?t:minutes(2)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, _Config) ->
+ Dog=?config(watchdog, _Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+xref(suite) ->
+ [addrem, convert, intergraph, lines, loops, no_data, modules].
+
+%% Seems a bit short...
+addrem(suite) -> [];
+addrem(doc) -> ["Simple test of removing modules"];
+addrem(Conf) when is_list(Conf) ->
+ S0 = new(),
+
+ F1 = {m1,f1,1},
+ F2 = {m2,f1,2},
+
+ E1 = {F1,F2},
+ E2 = {F2,F1},
+
+ D1 = {F1,12},
+ DefAt_m1 = [D1],
+ X_m1 = [F1],
+ % L_m1 = [],
+ XC_m1 = [E1],
+ LC_m1 = [],
+ LCallAt_m1 = [],
+ XCallAt_m1 = [{E1,13}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ D2 = {F2,7},
+ DefAt_m2 = [D2],
+ X_m2 = [F2],
+ % L_m2 = [],
+ XC_m2 = [E2],
+ LC_m2 = [],
+ LCallAt_m2 = [],
+ XCallAt_m2 = [{E2,96}],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ ?line S5 = set_up(S2),
+
+ ?line {ok, XMod1, S6} = remove_module(S5, m1),
+ ?line [a1] = XMod1#xref_mod.app_name,
+ ?line {ok, XMod2, S6a} = remove_module(S6, m2),
+ ?line [a2] = XMod2#xref_mod.app_name,
+ ?line S7 = set_up(S6a),
+
+ ?line AppInfo1 = #xref_app{name = a1, rel_name = [r1]},
+ ?line S9 = add_application(S7, AppInfo1),
+ ?line S10 = set_up(S9),
+ ?line AppInfo2 = #xref_app{name = a2, rel_name = [r1]},
+ ?line _S11 = add_application(S10, AppInfo2),
+ ok.
+
+convert(suite) -> [];
+convert(doc) -> ["Coercion of data"];
+convert(Conf) when is_list(Conf) ->
+ S0 = new(),
+
+ F1 = {m1,f1,1},
+ F6 = {m1,f2,6}, % X
+ F2 = {m2,f1,2},
+ F3 = {m2,f2,3}, % X
+ F7 = {m2,f3,7}, % X
+ F4 = {m3,f1,4}, % X
+ F5 = {m3,f2,5},
+
+ UF1 = {m1,f12,17},
+ UF2 = {m17,f17,177},
+
+ E1 = {F1,F3}, % X
+ E2 = {F6,F7}, % X
+ E3 = {F2,F6}, % X
+ E4 = {F1,F4}, % X
+ E5 = {F4,F5},
+ E6 = {F7,F4}, % X
+
+ UE1 = {F2,UF2}, % X
+ UE2 = {F5,UF1}, % X
+
+ D1 = {F1,12},
+ D6 = {F6,3},
+ DefAt_m1 = [D1,D6],
+ X_m1 = [F6],
+ % L_m1 = [F1],
+ XC_m1 = [E1,E2,E4],
+ LC_m1 = [],
+ LCallAt_m1 = [],
+ XCallAt_m1 = [{E1,13},{E2,17},{E4,7}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ D2 = {F2,7},
+ D3 = {F3,9},
+ D7 = {F7,19},
+ DefAt_m2 = [D2,D3,D7],
+ X_m2 = [F3,F7],
+ % L_m2 = [F2],
+ XC_m2 = [E3,E6,UE1],
+ LC_m2 = [],
+ LCallAt_m2 = [],
+ XCallAt_m2 = [{E3,96},{E6,12},{UE1,77}],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ D4 = {F4,6},
+ D5 = {F5,97},
+ DefAt_m3 = [D4,D5],
+ X_m3 = [F4],
+ % L_m3 = [F5],
+ XC_m3 = [UE2],
+ LC_m3 = [E5],
+ LCallAt_m3 = [{E5,19}],
+ XCallAt_m3 = [{UE2,22}],
+ Info3 = #xref_mod{name = m3, app_name = [a3]},
+ ?line S3 = add_module(S2, Info3, DefAt_m3, X_m3, LCallAt_m3, XCallAt_m3,
+ XC_m3, LC_m3),
+
+ Info4 = #xref_mod{name = m4, app_name = [a2]},
+ ?line S4 = add_module(S3, Info4, [], [], [], [], [], []),
+
+ AppInfo1 = #xref_app{name = a1, rel_name = [r1]},
+ ?line S9 = add_application(S4, AppInfo1),
+ AppInfo2 = #xref_app{name = a2, rel_name = [r1]},
+ ?line S10 = add_application(S9, AppInfo2),
+ AppInfo3 = #xref_app{name = a3, rel_name = [r2]},
+ ?line S11 = add_application(S10, AppInfo3),
+
+ RelInfo1 = #xref_rel{name = r1},
+ ?line S12 = add_release(S11, RelInfo1),
+ RelInfo2 = #xref_rel{name = r2},
+ ?line S13 = add_release(S12, RelInfo2),
+
+ ?line S = set_up(S13),
+
+ ?line {ok, _} = eval("(Lin)(m1->m1:Mod) * m1->m1", type_error, S),
+ ?line {ok, _} = eval("(XXL)(Lin)(m1->m1:Mod) * m1->m1", type_error, S),
+
+ ?line AllDefAt = eval("(Lin) M", S),
+ ?line AllV = eval("(Fun) M", S),
+ ?line AllCallAt = eval("(XXL)(Lin) E", S),
+ ?line AllE = eval("E", S),
+
+ ?line AM = eval("AM", S),
+ ?line A = eval("A", S),
+ ?line R = eval("R", S),
+
+
+ % vertices
+ % general 1 step
+ ?line {ok, _} = eval("(Fun) (Lin) M", AllV, S),
+ ?line {ok, _} = eval("(Fun) (Lin) (Lin) M", AllV, S),
+ ?line {ok, _} = eval(f("(Fun) (Lin) ~p", [[F1, F3]]), [F1,F3], S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [AllV]), [m1,m17,m2,m3], S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [[F1,F3,F6]]), [m1,m2], S),
+ ?line {ok, _} = eval("(App) M", A, S),
+ ?line {ok, _} = eval(f("(App) ~p", [[m1,m2,m4]]), [a1,a2], S),
+ ?line {ok, _} = eval(f("(Rel) ~p", [A]), R, S),
+ ?line {ok, _} = eval(f("(Rel) ~p", [[a1,a2,a2]]), [r1], S),
+ % general 2 steps
+ ?line {ok, _} = eval("(Mod) (Lin) M", [m1,m17,m2,m3], S),
+ ?line {ok, _} = eval(f("(App) ~p", [AllV]), [a1,a2,a3], S),
+ ?line {ok, _} = eval("(Rel) M", R, S),
+ % general 4 steps
+ ?line {ok, _} = eval("(Rel) (Lin) M", [r1,r2], S),
+
+ % special 1 step
+ ?line {ok, _} = eval(f("(Lin) ~p", [AllV]), AllDefAt, S),
+ ?line {ok, _} = eval(f("(Lin) ~p", [[F1,F3]]), [{F1,12},{F3,9}], S),
+ ?line {ok, _} = eval("(Fun) M", AllV, S),
+ ?line {ok, _} = eval(f("(Fun) ~p", [[m1,m2]]), [F1,F2,F3,F6,F7,UF1], S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [A]), AM, S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [[a1,a2]]), [m1,m2,m4], S),
+ ?line {ok, _} = eval(f("(App) ~p", [R]), A, S),
+ ?line {ok, _} = eval(f("(App) ~p", [[r1]]), [a1,a2], S),
+ % special 2 steps
+ ?line {ok, _} = eval("(Lin) M", AllDefAt, S),
+ ?line AnalyzedV = eval("(Fun) AM", S),
+ ?line {ok, _} = eval(f("(Fun) ~p", [A]), AnalyzedV, S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [R]), AM, S),
+ % special 4 steps
+ ?line AnalyzedAllDefAt = eval("(Lin) AM", S),
+ ?line {ok, _} = eval("(Lin) R", AnalyzedAllDefAt, S),
+
+ % edges
+ Ms = [{m1,m2},{m1,m3},{m2,m1},{m2,m3},{m3,m3}],
+ UMs = [{m2,m17},{m3,m1}],
+ AllMs = append(Ms, UMs),
+ As = [{a1,a2},{a1,a3},{a2,a1},{a2,a3},{a3,a3}],
+ Rs = [{r1,r1},{r1,r2},{r2,r2}],
+
+ % general 1 step
+ ?line {ok, _} = eval("(Fun) (Lin) E", AllE, S),
+ ?line {ok, _} = eval(f("(Fun)(Lin) ~p", [[E1, E6]]), [E1, E6], S),
+ ?line {ok, _} = eval("(Mod) E", AllMs, S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [[E1, E6]]), [{m1,m2},{m2,m3}], S),
+ ?line {ok, _} = eval(f("(App) ~p", [As]), As, S),
+ ?line {ok, _} = eval("(App) [m1->m2,m2->m3]", [{a1,a2},{a2,a3}], S),
+ ?line {ok, _} = eval(f("(Rel) ~p", [As]), Rs, S),
+ ?line {ok, _} = eval("(Rel) a1->a2", [{r1,r1}], S),
+
+ % special 1 step
+ ?line {ok, _} = eval("(XXL) (Lin) (Fun) E", AllCallAt, S),
+ ?line {ok, _} = eval("(XXL) (XXL) (Lin) (Fun) E", AllCallAt, S),
+
+ ?line {ok, _} = eval(f("(XXL) (Lin) ~p", [[E1, E6]]),
+ [{{D1,D3},[13]}, {{D7,D4},[12]}], S),
+ ?line {ok, _} = eval(f("(Fun) ~p", [AllMs]), AllE, S),
+ ?line {ok, _} = eval("(Fun) [m1->m2,m2->m3]", [E1,E2,E6], S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [As]), Ms, S),
+ ?line {ok, _} = eval("(Mod) [a1->a2,a2->a3]", [{m1,m2},{m2,m3}], S),
+ ?line {ok, _} = eval(f("(App) ~p", [Rs]), As, S),
+ ?line {ok, _} = eval("(App) r1->r1", [{a1,a2},{a2,a1}], S),
+ ok.
+
+intergraph(suite) -> [];
+intergraph(doc) -> ["Inter Call Graph"];
+intergraph(Conf) when is_list(Conf) ->
+ S0 = new(),
+
+ F1 = {m1,f1,1}, % X
+ F2 = {m1,f2,2}, % X
+ F3 = {m1,f3,3},
+ F4 = {m1,f4,4},
+ F5 = {m1,f5,5},
+
+ F6 = {m2,f1,6}, % X
+ F7 = {m2,f1,7},
+ F8 = {m2,f1,8},
+ F9 = {m2,f1,9},
+ F10 = {m2,f1,10},
+ F11 = {m2,f1,11},
+
+ % Note: E1 =:= E4!
+ E1 = {F2,F1},
+ E2 = {F2,F3},
+ E3 = {F3,F1},
+ E4 = {F2,F1}, % X
+ E5 = {F4,F2},
+ E6 = {F5,F4},
+ E7 = {F4,F5},
+
+ E8 = {F6,F7},
+ E9 = {F7,F8},
+ E10 = {F8,F1}, % X
+ E11 = {F6,F9},
+ E12 = {F6,F10},
+ E13 = {F9,F11},
+ E14 = {F10,F11},
+ E15 = {F11,F1}, % X
+
+ D1 = {F1,1},
+ D2 = {F2,2},
+ D3 = {F3,3},
+ D4 = {F4,4},
+ D5 = {F5,5},
+ DefAt_m1 = [D1,D2,D3,D4,D5],
+ X_m1 = [F1,F2],
+ % L_m1 = [F3,F4,F5],
+ XC_m1 = [E4],
+ LC_m1 = [E1,E2,E3,E5,E6,E7],
+ % Note: E1 and E4 together!
+ LCallAt_m1 = [{E1,1},{E2,2},{E3,3},{E5,5},{E6,6},{E7,7}],
+ XCallAt_m1 = [{E1,4}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ D6 = {F6,6},
+ D7 = {F7,7},
+ D8 = {F8,8},
+ D9 = {F9,9},
+ D10 = {F10,10},
+ D11 = {F11,11},
+ DefAt_m2 = [D6,D7,D8,D9,D10,D11],
+ X_m2 = [F6],
+ % L_m2 = [F7,F8,F9,F10,F11],
+ XC_m2 = [E10,E15],
+ LC_m2 = [E8,E9,E11,E12,E13,E14],
+ LCallAt_m2 = [{E8,8},{E9,9},{E11,11},{E12,12},{E13,13},{E14,14}],
+ XCallAt_m2 = [{E10,10},{E15,15}],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ AppInfo1 = #xref_app{name = a1, rel_name = [r1]},
+ ?line S5 = add_application(S2, AppInfo1),
+ AppInfo2 = #xref_app{name = a2, rel_name = [r1]},
+ ?line S6 = add_application(S5, AppInfo2),
+
+ RelInfo = #xref_rel{name = r1},
+ ?line S7 = add_release(S6, RelInfo),
+
+ ?line S = set_up(S7),
+
+ ?line {ok, _} = eval("EE | m1", [E1,E5,E6,E7], S),
+ ?line {ok, _} = eval("EE | m2", [{F6,F1}], S),
+ ?line {ok, _} = eval("EE | m2 + EE | m2", [{F6,F1}], S),
+
+ ?line {ok, _} = eval("(Fun)(Lin)(E | m1)",
+ to_external(union(set(XC_m1), set(LC_m1))), S),
+ ?line {ok, _} = eval("(XXL)(ELin) (EE | m1)",
+ [{{D2,D1},[1,2,4]},{{D4,D2},[5]},{{D5,D4},[6]},{{D4,D5},[7]}],
+ S),
+ ?line {ok, _} = eval("(XXL)(ELin)(EE | m2)", [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(ELin)(EE | m2)",
+ [{{D6,D1},[8,11,12]}], S),
+
+ %% Combining graphs (equal or different):
+ ?line {ok, _} = eval("(XXL)(ELin)(EE | m2 + EE | m2)",
+ [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(EE | m2 * EE | m2)",
+ [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(EE | m2 - EE | m1)",
+ [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(EE | m2 - E | m2)",
+ [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(Fun)(ELin)(EE | m2)",
+ [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("EE | m1 + E | m1", LC_m1, S),
+ ?line {ok, _} = eval(f("EE | ~p + E | ~p", [F2, F2]), [E1,E2], S),
+ %% [1,4] from 'calls' is a subset of [1,2,4] from Inter Call Graph:
+ ?line {ok, _} = eval(f("(XXL)(Lin) (E | ~p)", [F2]),
+ [{{D2,D1},[1,4]},{{D2,D3},[2]}], S),
+
+ ?line {ok, _} = eval(f("(XXL)(ELin) (EE | ~p)", [F2]),
+ [{{D2,D1},[1,2,4]}], S),
+ ?line {ok, _} = eval(f("(XXL)((ELin)(EE | ~p) + (Lin)(E | ~p))", [F2, F2]),
+ [{{D2,D1},[1,2,4]},{{D2,D3},[2]}], S),
+ ?line {ok, _} =
+ eval(f("(XXL)((ELin) ~p + (Lin) ~p)", [{F2, F1}, {F2, F1}]),
+ [{{D2,D1},[1,2,4]}], S),
+ ?line {ok, _} = eval(f("(Fun)(Lin) ~p", [{F2, F1}]), [E1], S),
+ %% The external call E4 is included in the reply:
+ ?line {ok, _} = eval("(XXL)(Lin)(LC | m1)",
+ [{{D2,D1},[1,4]},{{D2,D3},[2]},{{D3,D1},[3]},
+ {{D4,D2},[5]},{{D4,D5},[7]},{{D5,D4},[6]}], S),
+ %% The local call E1 is included in the reply:
+ ?line {ok, _} = eval("(XXL)(Lin)(XC | m1)", [{{D2,D1},[1,4]}], S),
+
+ ?line {ok, _} = eval(f("(LLin) (E | ~p || ~p) + (XLin) (E | ~p || ~p)",
+ [F2, F1, F2, F1]), [{E4,[1,4]}], S),
+
+ ?line {ok, _} = eval("# (ELin) E", 6, S),
+
+ ok.
+
+lines(suite) -> [];
+lines(doc) -> ["More test of Inter Call Graph, and regular expressions"];
+lines(Conf) when is_list(Conf) ->
+ S0 = new(),
+
+ F1 = {m1,f1,1}, % X
+ F2 = {m1,f2,2},
+ F3 = {m1,f3,3},
+ F4 = {m2,f4,4}, % X
+ F5 = {m1,f5,5}, % X
+ F6 = {m1,f6,6},
+
+ E1 = {F1,F2},
+ E2 = {F2,F1}, % X
+ E3 = {F3,F2},
+ E4 = {F1,F4}, % X
+ E5 = {F2,F4}, % X
+ E6 = {F5,F6},
+ E7 = {F6,F4}, % X
+
+ D1 = {F1,1},
+ D2 = {F2,2},
+ D3 = {F3,3},
+ D4 = {F4,4},
+ D5 = {F5,5},
+ D6 = {F6,6},
+
+ DefAt_m1 = [D1,D2,D3,D5,D6],
+ X_m1 = [F1,F5],
+ % L_m1 = [F2,F3,F6],
+ XC_m1 = [E4,E5,E7],
+ LC_m1 = [E1,E2,E3,E6],
+ LCallAt_m1 = [{E1,1},{E3,3},{E6,6}],
+ XCallAt_m1 = [{E2,2},{E4,4},{E5,5},{E7,7}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ DefAt_m2 = [D4],
+ X_m2 = [F4],
+ % L_m2 = [],
+ XC_m2 = [],
+ LC_m2 = [],
+ LCallAt_m2 = [],
+ XCallAt_m2 = [],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ AppInfo1 = #xref_app{name = a1, rel_name = [r1]},
+ ?line S5 = add_application(S2, AppInfo1),
+ AppInfo2 = #xref_app{name = a2, rel_name = [r1]},
+ ?line S6 = add_application(S5, AppInfo2),
+
+ RelInfo = #xref_rel{name = r1},
+ ?line S7 = add_release(S6, RelInfo),
+
+ ?line S = set_up(S7),
+
+ ?line {ok, _} = eval("(XXL) (ELin) (EE | m1)",
+ [{{D1,D1},[1]},{{D1,D4},[1,4]},{{D3,D1},[3]},{{D3,D4},[3]},
+ {{D5,D4},[6]}], S),
+ ?line {ok, _} = eval("(XXL)(Lin) (E | m1)",
+ [{{D1,D2},[1]},{{D1,D4},[4]},{{D2,D1},[2]},
+ {{D2,D4},[5]},{{D3,D2},[3]},{{D5,D6},[6]},{{D6,D4},[7]}],
+ S),
+ ?line {ok, _} = eval("(E | m1) + (EE | m1)",
+ [E1,E2,E3,E4,E5,E6,E7,{F1,F1},{F3,F1},{F3,F4},{F5,F4}],
+ S),
+ ?line {ok, _} = eval("(Lin)(E | m1)",
+ [{E4,[4]},{E1,[1]},{E2,[2]},{E5,[5]},
+ {E3,[3]},{E7,[7]},{E6,[6]}], S),
+ ?line {ok, _} = eval("(ELin)(EE | m1)",
+ [{{F1,F1},[1]},{{F1,F4},[1,4]},{{F3,F1},[3]},{{F3,F4},[3]},
+ {{F5,F4},[6]}], S),
+ ?line {ok, _} = eval("(Lin)(E | m1) + (ELin)(EE | m1)",
+ [{E4,[1,4]},{E1,[1]},{E2,[2]},{E5,[5]},
+ {E3,[3]},{E7,[7]},{E6,[6]},
+ {{F1,F1},[1]},{{F3,F1},[3]},{{F3,F4},[3]},
+ {{F5,F4},[6]}], S),
+ ?line {ok, _} = eval("(Lin)(E | m1) - (ELin)(EE | m1)",
+ [{E1,[1]},{E2,[2]},{E5,[5]},
+ {E3,[3]},{E7,[7]},{E6,[6]}], S),
+ ?line {ok, _} = eval("(Lin)(E | m1) * (ELin)(EE | m1)",
+ [{E4,[4]}], S),
+ ?line {ok, _} = eval("(XXL)(Lin) (E | m1)",
+ [{{D1,D4},[4]},{{D1,D2},[1]},{{D2,D1},[2]},{{D2,D4},[5]},
+ {{D3,D2},[3]},{{D6,D4},[7]},{{D5,D6},[6]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin) (EE | m1)",
+ [{{D1,D1},[1]},{{D1,D4},[1,4]},{{D3,D1},[3]},{{D3,D4},[3]},
+ {{D5,D4},[6]}], S),
+ ?line {ok, _} = eval("(XXL)(Lin)(Fun)(Lin) (E | m1)",
+ [{{D1,D4},[4]},{{D1,D2},[1]},{{D2,D1},[2]},{{D2,D4},[5]},
+ {{D3,D2},[3]},{{D6,D4},[7]},{{D5,D6},[6]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(Fun)(ELin) (EE | m1)",
+ [{{D1,D1},[1]},{{D1,D4},[1,4]},{{D3,D1},[3]},{{D3,D4},[3]},
+ {{D5,D4},[6]}], S),
+
+ %% A few tests on regexp.
+ ?line {ok, _} = eval("\"(foo\":Mod", parse_error, S),
+ ?line {ok, _} = eval("_Foo:_/_", parse_error, S),
+ ?line {ok, _} = eval("\".*foo\"", parse_error, S),
+ ?line {ok, _} = eval("_:_/_:Lin", parse_error, S),
+ ?line {ok, _} = eval("_:_/_:Mod", parse_error, S),
+ ?line {ok, _} = eval("_:_/_:App", parse_error, S),
+ ?line {ok, _} = eval("_:_/_:Rel", parse_error, S),
+ ?line {ok, _} = eval("m2:_/4", [F4], S),
+ ?line {ok, _} = eval("m2:_/4:Fun", [F4], S),
+ ?line {ok, _} = eval("\"m.?\":\"f.*\"/\"6\"", [F6], S),
+ ?line {ok, _} = eval("_:_/6", [F6], S),
+ ?line {ok, _} = eval("m1:\"f1\"/_", [F1], S),
+ ?line {ok, _} = eval("\"m1\":f1/_", [F1], S),
+ ?line {ok, _} = eval("\"m1\":Mod", [m1], S),
+ ?line {ok, _} = eval("\"a1\":App", [a1], S),
+ ?line {ok, _} = eval("\"r1\":Rel", [r1], S),
+ ?line {ok, _} = eval("_:_/-1", [], S),
+
+ ok.
+
+loops(suite) -> [];
+loops(doc) -> ["More Inter Call Graph, loops and \"unusual\" cases"];
+loops(Conf) when is_list(Conf) ->
+ S0 = new(),
+
+ F1 = {m1,f1,1}, % X
+ F2 = {m1,f2,2},
+ F3 = {m1,f3,3}, % X
+ F4 = {m1,f4,4},
+ F5 = {m1,f5,5},
+ F6 = {m1,f1,6}, % X
+ F7 = {m1,f1,7},
+
+ E1 = {F1,F1}, % X
+ E2 = {F2,F2},
+ E3 = {F3,F4},
+ E4 = {F4,F5},
+ E5 = {F5,F3}, % X
+
+ D1 = {F1,1},
+ D2 = {F2,2},
+ D3 = {F3,3},
+ D4 = {F4,4},
+ D5 = {F5,5},
+ D6 = {F6,6},
+ D7 = {F7,7},
+ DefAt_m1 = [D1,D2,D3,D4,D5,D6,D7],
+ X_m1 = [F1,F3,F6],
+ % L_m1 = [F2,F4,F5],
+ XC_m1 = [],
+ LC_m1 = [E1,E2,E3,E4,E5],
+ LCallAt_m1 = [{E2,2},{E3,3},{E4,4}],
+ XCallAt_m1 = [{E1,1},{E5,5}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ ?line S = set_up(S1),
+
+ % Neither F6 nor F7 is included. Perhaps one should change that?
+ ?line {ok, _} = eval("EE | m1", [E1,E2,{F3,F3}], S),
+ ?line {ok, _} = eval(f("(XXL)(ELin) (EE | ~p)", [F3]), [{{D3,D3},[3]}], S),
+
+ ?line {ok, _} = eval("m1->m1 | m1->m1", type_error, S),
+ ?line {ok, _} = eval(f("~p | ~p", [F2, F1]), type_error, S),
+
+ ?line {ok, _} = eval(f("range (closure EE | ~p)", [F1]), [F1], S),
+ ?line {ok, _} = eval(f("domain (closure EE || ~p)", [F3]), [F3], S),
+
+ ?line {ok, _} = eval(f("domain (closure E || ~p)", [F3]), [F3,F4,F5], S),
+
+ ?line {ok, _} = eval("components E", [[F1],[F2],[F3,F4,F5]], S),
+ ?line {ok, _} = eval("components EE", [[F1],[F2],[F3]], S),
+
+ ok.
+
+no_data(suite) -> [];
+no_data(doc) -> ["Simple tests when there is no data"];
+no_data(Conf) when is_list(Conf) ->
+ S0 = new(),
+ ?line S1 = set_up(S0),
+ ?line {ok, _} = eval("M", [], S1),
+ ?line {ok, _} = eval("A", [], S1),
+ ?line {ok, _} = eval("R", [], S1),
+
+ ModInfo = #xref_mod{name = m, app_name = []},
+ ?line S2 = add_module(S1, ModInfo, [], [], [], [], [], []),
+ AppInfo = #xref_app{name = a, rel_name = []},
+ ?line S3 = add_application(S2, AppInfo),
+ RelInfo = #xref_rel{name = r, dir = ""},
+ ?line S4 = add_release(S3, RelInfo),
+ ?line S5 = set_up(S4),
+ ?line {ok, _} = eval("M", [m], S5),
+ ?line {ok, _} = eval("A", [a], S5),
+ ?line {ok, _} = eval("R", [r], S5),
+ ok.
+
+modules(suite) -> [];
+modules(doc) -> ["Modules mode"];
+modules(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir, "rel2"),
+ X = fname(Dir, "x.erl"),
+ Y = fname(Dir, "y.erl"),
+ A1_1 = fname([Dir,"lib","app1-1.1"]),
+ A2 = fname([Dir,"lib","app2-1.1"]),
+ EB1_1 = fname(A1_1, "ebin"),
+ EB2 = fname(A2, "ebin"),
+ Xbeam = fname(EB2, "x.beam"),
+ Ybeam = fname(EB1_1, "y.beam"),
+
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB2}]),
+ ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
+
+ ?line {ok, S0} = xref_base:new([{xref_mode, modules}]),
+ ?line {ok, release2, S1} =
+ xref_base:add_release(S0, Dir, [{name,release2}]),
+ ?line S = set_up(S1),
+ ?line {{error, _, {unavailable_analysis, undefined_function_calls}}, _} =
+ xref_base:analyze(S, undefined_function_calls),
+ ?line {{error, _, {unavailable_analysis, locals_not_used}}, _} =
+ xref_base:analyze(S, locals_not_used),
+ ?line {{error, _, {unavailable_analysis, {call, foo}}}, _} =
+ xref_base:analyze(S, {call, foo}),
+ ?line {{error, _, {unavailable_analysis, {use, foo}}}, _} =
+ xref_base:analyze(S, {use, foo}),
+ ?line analyze(undefined_functions, [{x,undef,0}], S),
+ ?line 5 = length(xref_base:info(S)),
+
+ %% More: all info, conversions.
+
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+ ?line ok = xref_base:delete(S),
+ ok.
+
+files(suite) ->
+ [add, default, info, lib, read, read2, remove, replace, update,
+ deprecated, trycatch, abstract_modules, fun_mfa, qlc].
+
+add(suite) -> [];
+add(doc) -> ["Add modules, applications, releases, directories"];
+add(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir, "rel2"),
+ UDir = fname([CopyDir,"dir","unreadable"]),
+ DDir = fname(CopyDir,"dir"),
+ UFile = fname([DDir, "dir","unreadable.beam"]),
+ X = fname(Dir, "x.erl"),
+ Y = fname(Dir, "y.erl"),
+ A1_1 = fname([Dir,"lib","app1-1.1"]),
+ A2 = fname([Dir,"lib","app2-1.1"]),
+ EB1_1 = fname(A1_1, "ebin"),
+ EB2 = fname(A2, "ebin"),
+ Xbeam = fname(EB2, "x.beam"),
+ Ybeam = fname(EB1_1, "y.beam"),
+
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB2}]),
+ ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
+
+ ?line case os:type() of
+ {unix, _} ->
+ ?line make_udir(UDir),
+ ?line make_ufile(UFile);
+ _ ->
+ true
+ end,
+
+ ?line {error, _, {invalid_options,[not_an_option] }} =
+ xref_base:new([not_an_option]),
+ ?line {error, _, {invalid_options,[{verbose,not_a_value}] }} =
+ xref_base:new([{verbose,not_a_value}]),
+ ?line S = new(),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref_base:set_up(S, [not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,true},not_an_option]}} =
+ xref_base:add_directory(S, foo, [{builtins,true},not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref_base:add_directory(S, foo, [{builtins,not_a_value}]),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref_base:add_directory(S, {foo,bar}, []),
+ ?line {error, _, {invalid_options,[{builtins,true},not_an_option]}} =
+ xref_base:add_module(S, foo, [{builtins,true},not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref_base:add_module(S, foo, [{builtins,not_a_value}]),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref_base:add_module(S, {foo,bar}, []),
+ ?line {error, _, {invalid_options,[{builtins,true},not_an_option]}} =
+ xref_base:add_application(S, foo, [{builtins,true},not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref_base:add_application(S, foo, [{builtins,not_a_value}]),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref_base:add_application(S, {foo,bar}, []),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref_base:add_release(S, foo, [not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref_base:add_release(S, foo, [{builtins,not_a_value}]),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref_base:add_release(S, {foo,bar}, []),
+ ?line {ok, S1} =
+ xref_base:set_default(S, [{verbose,false}, {warnings, false}]),
+ ?line case os:type() of
+ {unix, _} ->
+ ?line {error, _, {file_error, _, _}} =
+ xref_base:add_release(S, UDir);
+ _ ->
+ true
+ end,
+ ?line {error, _, {file_error, _, _}} =
+ xref_base:add_release(S, fname(["/a/b/c/d/e/f","__foo"])),
+ ?line {ok, release2, S2} =
+ xref_base:add_release(S1, Dir, [{name,release2}]),
+ ?line {error, _, {module_clash, {x, _, _}}} =
+ xref_base:add_module(S2, Xbeam),
+ ?line {ok, S3} = xref_base:remove_release(S2, release2),
+ ?line {ok, rel2, S4} = xref_base:add_release(S3, Dir),
+ ?line {error, _, {release_clash, {rel2, _, _}}} =
+ xref_base:add_release(S4, Dir),
+ ?line {ok, S5} = xref_base:remove_release(S4, rel2),
+ %% One unreadable file and one JAM file found (no verification here):
+ ?line {ok, [], S6} = xref_base:add_directory(S5, fname(CopyDir,"dir"),
+ [{recurse,true}, {warnings,true}]),
+ ?line case os:type() of
+ {unix, _} ->
+ ?line {error, _, {file_error, _, _}} =
+ xref_base:add_directory(S6, UDir);
+ _ ->
+ true
+ end,
+ ?line {ok, app1, S7} = xref_base:add_application(S6, A1_1),
+ ?line {error, _, {application_clash, {app1, _, _}}} =
+ xref_base:add_application(S7, A1_1),
+ ?line {ok, S8} = xref_base:remove_application(S7, app1),
+ ?line ok = xref_base:delete(S8),
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+ ?line case os:type() of
+ {unix, _} ->
+ ?line ok = file:del_dir(UDir),
+ ?line ok = file:delete(UFile);
+ _ ->
+ true
+ end,
+ ok.
+
+default(suite) -> [];
+default(doc) -> ["Default values of options"];
+default(Conf) when is_list(Conf) ->
+ S = new(),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref_base:set_default(S, not_an_option, true),
+ ?line {error, _, {invalid_options,[{builtins, not_a_value}]}} =
+ xref_base:set_default(S, builtins, not_a_value),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref_base:get_default(S, not_an_option),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref_base:set_default(S, [not_an_option]),
+
+ ?line D = xref_base:get_default(S),
+ ?line [{builtins,false},{recurse,false},{verbose,false},{warnings,true}] =
+ D,
+
+ ?line ok = xref_base:delete(S),
+ ok.
+
+info(suite) -> [];
+info(doc) -> ["The info functions"];
+info(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"rel2"),
+ LDir = fname(CopyDir,"lib_test"),
+ X = fname(Dir, "x.erl"),
+ Y = fname(Dir, "y.erl"),
+ A1_1 = fname([Dir,"lib","app1-1.1"]),
+ A2 = fname([Dir,"lib","app2-1.1"]),
+ EB1_1 = fname(A1_1, "ebin"),
+ EB2 = fname(A2, "ebin"),
+ Xbeam = fname(EB2, "x.beam"),
+ Ybeam = fname(EB1_1, "y.beam"),
+
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB2}]),
+ ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
+
+ ?line {ok, _} = start(s),
+ ?line {error, _, {no_such_info, release}} = xref:info(s, release),
+ ?line {error, _, {no_such_info, release}} = xref:info(s, release, rel),
+ ?line {error, _, {no_such_module, mod}} = xref:info(s, modules, mod),
+ ?line {error, _, {no_such_application, app}} =
+ xref:info(s, applications, app),
+ ?line {error, _, {no_such_release, rel}} = xref:info(s, releases, rel),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?line {ok, rel2} = xref:add_release(s, Dir),
+ ?line 9 = length(xref:info(s)),
+ ?line [{x,_}, {y, _}] = xref:info(s, modules),
+ ?line [{app1,_}, {app2, _}] = xref:info(s, applications),
+ ?line [{rel2,_}] = xref:info(s, releases),
+ ?line [] = xref:info(s, libraries),
+ ?line [{x,_}] = xref:info(s, modules, x),
+ ?line [{rel2,_}] = xref:info(s, releases, rel2),
+ ?line {error, _, {no_such_library, foo}} = xref:info(s, libraries, [foo]),
+
+ ?line {ok, lib1} =
+ compile:file(fname(LDir,lib1),[debug_info,{outdir,LDir}]),
+ ?line {ok, lib2} =
+ compile:file(fname(LDir,lib2),[debug_info,{outdir,LDir}]),
+ ?line ok = xref:set_library_path(s, [LDir], [{verbose,false}]),
+ ?line [{lib1,_}, {lib2, _}] = xref:info(s, libraries),
+ ?line [{lib1,_}, {lib2, _}] = xref:info(s, libraries, [lib1,lib2]),
+ ?line ok = file:delete(fname(LDir, "lib1.beam")),
+ ?line ok = file:delete(fname(LDir, "lib2.beam")),
+
+ ?line check_state(s),
+
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+
+ ok.
+
+lib(suite) -> [];
+lib(doc) -> ["Library modules"];
+lib(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"lib_test"),
+ UDir = fname([CopyDir,"dir","non_existent"]),
+
+ ?line {ok, lib1} = compile:file(fname(Dir,lib1),[debug_info,{outdir,Dir}]),
+ ?line {ok, lib2} = compile:file(fname(Dir,lib2),[debug_info,{outdir,Dir}]),
+ ?line {ok, lib3} = compile:file(fname(Dir,lib3),[debug_info,{outdir,Dir}]),
+ ?line {ok, t} = compile:file(fname(Dir,t),[debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = start(s),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?line {ok, t} = xref:add_module(s, fname(Dir,"t.beam")),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref:set_library_path(s, ["foo"], [not_an_option]),
+ ?line {error, _, {invalid_path,otp}} = xref:set_library_path(s,otp),
+ ?line {error, _, {invalid_path,[""]}} = xref:set_library_path(s,[""]),
+ ?line {error, _, {invalid_path,[[$a | $b]]}} =
+ xref:set_library_path(s,[[$a | $b]]),
+ ?line {error, _, {invalid_path,[otp]}} = xref:set_library_path(s,[otp]),
+ ?line {ok, []} = xref:get_library_path(s),
+ ?line ok = xref:set_library_path(s, [Dir], [{verbose,false}]),
+ ?line {ok, UnknownFunctions} = xref:q(s, "U"),
+ ?line [{lib1,unknown,0}, {lib2,local,0},
+ {lib2,unknown,0}, {unknown,unknown,0}]
+ = UnknownFunctions,
+ ?line {ok, [{lib2,f,0},{lib3,f,0}]} = xref:q(s, "DF"),
+ ?line {ok, []} = xref:q(s, "DF_1"),
+ ?line {ok, [{lib2,f,0}]} = xref:q(s, "DF_2"),
+ ?line {ok, [{lib2,f,0}]} = xref:q(s, "DF_3"),
+
+ ?line {ok, [unknown]} = xref:q(s, "UM"),
+ ?line {ok, UnknownDefAt} = xref:q(s, "(Lin)U"),
+ ?line [{{lib1,unknown,0},0},{{lib2,local,0},0}, {{lib2,unknown,0},0},
+ {{unknown,unknown,0},0}] = UnknownDefAt,
+ ?line {ok, LibFuns} = xref:q(s, "X * LM"),
+ ?line [{lib2,f,0},{lib3,f,0}] = LibFuns,
+ ?line {ok, LibMods} = xref:q(s, "LM"),
+ ?line [lib1,lib2,lib3] = LibMods,
+ ?line {ok, [{{lib2,f,0},0},{{lib3,f,0},0}]} = xref:q(s, "(Lin) (LM * X)"),
+ ?line {ok, [{{lib1,unknown,0},0}, {{lib2,f,0},0}, {{lib2,local,0},0},
+ {{lib2,unknown,0},0}, {{lib3,f,0},0}]} = xref:q(s,"(Lin)LM"),
+ ?line {ok,[lib1,lib2,lib3,t,unknown]} = xref:q(s,"M"),
+ ?line {ok,[{lib2,f,0},{lib3,f,0},{t,t,0}]} = xref:q(s,"X * M"),
+ ?line check_state(s),
+
+ ?line copy_file(fname(Dir, "lib1.erl"), fname(Dir,"lib1.beam")),
+ ?line ok = xref:set_library_path(s, [Dir]),
+ ?line {error, _, _} = xref:q(s, "U"),
+
+ %% OTP-3921. AM and LM not always disjoint.
+ ?line {ok, lib1} = compile:file(fname(Dir,lib1),[debug_info,{outdir,Dir}]),
+ ?line {ok, lib1} = xref:add_module(s, fname(Dir,"lib1.beam")),
+ ?line check_state(s),
+
+ ?line {error, _, {file_error, _, _}} = xref:set_library_path(s, [UDir]),
+
+ ?line xref:stop(s),
+ ?line ok = file:delete(fname(Dir, "lib1.beam")),
+ ?line ok = file:delete(fname(Dir, "lib2.beam")),
+ ?line ok = file:delete(fname(Dir, "lib3.beam")),
+ ?line ok = file:delete(fname(Dir, "t.beam")),
+
+ ?line {ok, cp} = compile:file(fname(Dir,cp),[debug_info,{outdir,Dir}]),
+ ?line {ok, _} = start(s),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?line {ok, cp} = xref:add_module(s, fname(Dir,"cp.beam")),
+ ?line {ok, [{lists, sort, 1}]} = xref:q(s, "U"),
+ ?line ok = xref:set_library_path(s, code_path),
+ ?line {ok, []} = xref:q(s, "U"),
+ ?line check_state(s),
+ ?line xref:stop(s),
+ ?line ok = file:delete(fname(Dir, "cp.beam")),
+ ok.
+
+read(suite) -> [];
+read(doc) -> ["Data read from the Abstract Code"];
+read(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"read"),
+ File = fname(Dir, "read"),
+ Beam = fname(Dir, "read.beam"),
+ ?line {ok, read} = compile:file(File, [debug_info,{outdir,Dir}]),
+ ?line do_read(File, abstract_v2),
+ ?line copy_file(fname(Dir, "read.beam.v1"), Beam),
+ ?line do_read(File, abstract_v1),
+ ?line ok = file:delete(Beam),
+ ok.
+
+do_read(File, Version) ->
+ ?line {ok, _} = start(s),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?line {ok, read} = xref:add_module(s, File),
+
+ ?line {U, OK, OKB} = read_expected(Version),
+
+ %% {ok, UC} = xref:q(s, "(Lin) UC"),
+ %% RR = to_external(converse(family_to_relation(family(UC)))),
+ %% lists:foreach(fun(X) -> io:format("~w~n", [X]) end, RR),
+ Unres = to_external(relation_to_family(converse(from_term(U)))),
+ ?line {ok, Unres} = xref:q(s, "(Lin) UC"),
+
+ %% {ok, EE} = xref:q(s, "(Lin) (E - UC)"),
+ %% AA = to_external(converse(family_to_relation(family(EE)))),
+ %% lists:foreach(fun(X) -> io:format("~w~n", [X]) end, AA),
+ Calls = to_external(relation_to_family(converse(from_term(OK)))),
+ ?line {ok, Calls} = xref:q(s, "(Lin) (E - UC) "),
+
+ ?line ok = check_state(s),
+ ?line {ok, UM} = xref:q(s, "UM"),
+ ?line true = member('$M_EXPR', UM),
+
+ ?line {ok, X} = xref:q(s, "X"),
+ ?line true = member({read, module_info, 0}, X),
+ ?line false = member({foo, module_info, 0}, X),
+ ?line false = member({erlang, module_info, 0}, X),
+ ?line {ok, Unknowns} = xref:q(s, "U"),
+ ?line false = member({read, module_info, 0}, Unknowns),
+ ?line true = member({foo, module_info, 0}, Unknowns),
+ ?line true = member({erlang, module_info, 0}, Unknowns),
+ ?line {ok, LC} = xref:q(s, "LC"),
+ ?line true = member({{read,bi,0},{read,bi,0}}, LC),
+
+ ?line ok = xref:set_library_path(s, add_erts_code_path(fname(code:lib_dir(kernel),ebin))),
+ ?line io:format("~p~n",[(catch xref:get_library_path(s))]),
+ ?line {ok, X2} = xref:q(s, "X"),
+ ?line ok = check_state(s),
+ ?line true = member({read, module_info, 0}, X2),
+ ?line false = member({foo, module_info, 0}, X2),
+ ?line true = member({erlang, module_info, 0}, X2),
+ ?line {ok, Unknowns2} = xref:q(s, "U"),
+ ?line false = member({read, module_info, 0}, Unknowns2),
+ ?line true = member({foo, module_info, 0}, Unknowns2),
+ ?line false = member({erlang, module_info, 0}, Unknowns2),
+
+ ?line ok = xref:remove_module(s, read),
+ ?line {ok, read} = xref:add_module(s, File, [{builtins,true}]),
+
+ UnresB = to_external(relation_to_family(converse(from_term(U)))),
+ ?line {ok, UnresB} = xref:q(s, "(Lin) UC"),
+ CallsB = to_external(relation_to_family(converse(from_term(OKB)))),
+ ?line {ok, CallsB} = xref:q(s, "(Lin) (E - UC) "),
+ ?line ok = check_state(s),
+ ?line {ok, XU} = xref:q(s, "XU"),
+ ?line Erl = set([{erlang,length,1},{erlang,integer,1},
+ {erlang,binary_to_term,1}]),
+ ?line [{erlang,binary_to_term,1},{erlang,length,1}] =
+ to_external(intersection(set(XU), Erl)),
+ ?line xref:stop(s).
+
+%% What is expected when xref_SUITE_data/read/read.erl is added:
+read_expected(Version) ->
+ %% Line positions in xref_SUITE_data/read/read.erl:
+ POS1 = 28, POS2 = POS1+10, POS3 = POS2+6, POS4 = POS3+6, POS5 = POS4+10,
+ POS6 = POS5+5, POS7 = POS6+6, POS8 = POS7+6, POS9 = POS8+8,
+ POS10 = POS9+10, POS11 = POS10+7, POS12 = POS11+8, POS13 = POS12+10,
+ POS14 = POS13+18, % POS15 = POS14+23,
+
+ FF = {read,funfuns,0},
+ U = [{POS1+5,{FF,{dist,'$F_EXPR',0}}},
+ {POS1+8,{FF,{dist,'$F_EXPR',0}}},
+ {POS2+8,{{read,funfuns,0},{expr,'$F_EXPR',1}}},
+ {POS3+4,{FF,{expr,'$F_EXPR',2}}},
+ {POS4+2,{FF,{modul,'$F_EXPR',1}}},
+ {POS4+4,{FF,{spm,'$F_EXPR',1}}},
+ {POS4+6,{FF,{spm,'$F_EXPR',1}}},
+ {POS4+8,{FF,{spm,'$F_EXPR',1}}},
+ {POS5+1,{FF,{'$M_EXPR','$F_EXPR',0}}},
+ {POS5+2,{FF,{'$M_EXPR','$F_EXPR',0}}},
+ {POS5+3,{FF,{'$M_EXPR','$F_EXPR',0}}},
+ {POS6+1,{FF,{'$M_EXPR','$F_EXPR',0}}},
+ {POS6+2,{FF,{'$M_EXPR','$F_EXPR',0}}},
+ {POS6+4,{FF,{n,'$F_EXPR',-1}}},
+ {POS7+1,{FF,{'$M_EXPR',f,1}}},
+ {POS7+2,{FF,{'$M_EXPR',f,1}}},
+ {POS8+2,{FF,{hej,'$F_EXPR',1}}},
+ {POS8+3,{FF,{t,'$F_EXPR',1}}},
+ {POS8+5,{FF,{a,'$F_EXPR',1}}},
+ {POS8+7,{FF,{m,'$F_EXPR',1}}},
+ {POS9+1,{FF,{'$M_EXPR',f,1}}},
+ {POS9+3,{FF,{a,'$F_EXPR',1}}},
+ {POS10+1,{FF,{'$M_EXPR',foo,1}}},
+ {POS10+2,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS10+3,{FF,{'$M_EXPR','$F_EXPR',2}}},
+ {POS10+4,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS10+5,{FF,{'$M_EXPR',san,1}}},
+ {POS10+6,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS11+1,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS11+2,{FF,{'$M_EXPR','$F_EXPR',-1}}},
+ {POS11+3,{FF,{m,f,-1}}},
+ {POS11+4,{FF,{m,f,-1}}},
+ {POS11+5,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS11+6,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS12+1,{FF,{'$M_EXPR','$F_EXPR',-1}}},
+ {POS12+4,{FF,{'$M_EXPR','$F_EXPR',2}}},
+ {POS12+7,{FF,{'$M_EXPR','$F_EXPR',-1}}},
+ {POS12+8,{FF,{m4,f4,-1}}},
+ {POS13+2,{FF,{debug,'$F_EXPR',0}}},
+ {POS13+3,{FF,{'$M_EXPR','$F_EXPR',-1}}},
+ {POS14+8,{{read,bi,0},{'$M_EXPR','$F_EXPR',1}}}],
+
+ O1 = [{0,{FF,{modul,'$F_EXPR',179}}},
+ {0,{FF,{read,'$F_EXPR',178}}},
+ {20,{{read,lc,0},{ets,new,0}}},
+ {21,{{read,lc,0},{ets,tab2list,1}}},
+ {POS1+1,{FF,{erlang,spawn,1}}},
+ {POS1+1,{FF,{mod17,fun17,0}}},
+ {POS1+2,{FF,{erlang,spawn,1}}},
+ {POS1+2,{FF,{read,local,0}}},
+ {POS1+3,{FF,{erlang,spawn,1}}},
+ {POS1+4,{FF,{dist,func,0}}},
+ {POS1+4,{FF,{erlang,spawn,1}}},
+ {POS1+5,{FF,{erlang,spawn,1}}},
+ {POS1+6,{FF,{erlang,spawn_link,1}}},
+ {POS1+6,{FF,{mod17,fun17,0}}},
+ {POS1+7,{FF,{dist,func,0}}},
+ {POS1+7,{FF,{erlang,spawn_link,1}}},
+ {POS1+8,{FF,{erlang,spawn_link,1}}},
+ {POS2+1,{FF,{d,f,0}}},
+ {POS2+1,{FF,{dist,func,2}}},
+ {POS2+1,{FF,{erlang,spawn,2}}},
+ {POS2+2,{FF,{dist,func,2}}},
+ {POS2+2,{FF,{erlang,spawn,2}}},
+ {POS2+2,{FF,{mod42,func,0}}},
+ {POS2+3,{FF,{d,f,0}}},
+ {POS2+3,{FF,{dist,func,2}}},
+ {POS2+3,{FF,{erlang,spawn_link,2}}},
+ {POS2+4,{FF,{dist,func,2}}},
+ {POS2+4,{FF,{erlang,spawn_link,2}}},
+ {POS2+4,{FF,{mod42,func,0}}},
+ {POS3+1,{FF,{dist,func,2}}},
+ {POS3+3,{FF,{dist,func,2}}},
+ {POS4+1,{FF,{erlang,spawn,4}}},
+ {POS4+1,{FF,{modul,function,0}}},
+ {POS4+2,{FF,{erlang,spawn,4}}},
+ {POS4+3,{FF,{dist,func,2}}},
+ {POS4+3,{FF,{erlang,spawn,4}}},
+ {POS4+3,{FF,{spm,spf,2}}},
+ {POS4+4,{FF,{dist,func,2}}},
+ {POS4+4,{FF,{erlang,spawn,4}}},
+ {POS4+5,{FF,{dist,func,2}}},
+ {POS4+5,{FF,{erlang,spawn_link,4}}},
+ {POS4+5,{FF,{spm,spf,2}}},
+ {POS4+6,{FF,{dist,func,2}}},
+ {POS4+6,{FF,{erlang,spawn_link,4}}},
+ {POS4+7,{FF,{erlang,spawn_opt,4}}},
+ {POS4+7,{FF,{read,bi,0}}},
+ {POS4+7,{FF,{spm,spf,2}}},
+ {POS4+8,{FF,{erlang,spawn_opt,4}}},
+ {POS4+8,{FF,{read,bi,0}}},
+ {POS5+1,{FF,{erlang,spawn,1}}},
+ {POS5+2,{FF,{erlang,spawn,1}}},
+ {POS5+3,{FF,{erlang,spawn_link,1}}},
+ {POS6+1,{FF,{erlang,spawn,2}}},
+ {POS6+2,{FF,{erlang,spawn_link,2}}},
+ {POS7+1,{FF,{erlang,spawn,4}}},
+ {POS7+2,{FF,{erlang,spawn_opt,4}}},
+ {POS8+1,{FF,{hej,san,1}}},
+ {POS8+4,{FF,{a,b,1}}},
+ {POS8+4,{FF,{erlang,apply,2}}},
+ {POS8+5,{FF,{erlang,apply,2}}},
+ {POS8+6,{FF,{erlang,apply,3}}},
+ {POS8+6,{FF,{m,f,1}}},
+ {POS8+7,{FF,{erlang,apply,3}}},
+ {POS9+1,{FF,{erlang,apply,3}}},
+ {POS9+1,{FF,{read,bi,0}}},
+ {POS9+2,{FF,{a,b,1}}},
+ {POS9+2,{FF,{erlang,apply,2}}},
+ {POS9+3,{FF,{erlang,apply,2}}},
+ {POS9+4,{FF,{erlang,apply,2}}},
+ {POS9+4,{FF,{erlang,not_a_function,1}}},
+ {POS9+5,{FF,{erlang,apply,3}}},
+ {POS9+5,{FF,{mod,func,2}}},
+ {POS9+6,{FF,{erlang,apply,1}}},
+ {POS9+7,{FF,{erlang,apply,2}}},
+ {POS9+7,{FF,{math,add3,1}}},
+ {POS9+8,{FF,{q,f,1}}},
+ {POS10+4,{FF,{erlang,apply,2}}},
+ {POS10+5,{FF,{mod1,fun1,1}}},
+ {POS11+1,{FF,{erlang,apply,3}}},
+ {POS11+2,{FF,{erlang,apply,3}}},
+ {POS11+3,{FF,{erlang,apply,3}}},
+ {POS11+4,{FF,{erlang,apply,3}}},
+ {POS11+6,{FF,{erlang,apply,2}}},
+ {POS12+1,{FF,{erlang,apply,2}}},
+ {POS12+4,{FF,{erlang,apply,2}}},
+ {POS12+5,{FF,{erlang,apply,3}}},
+ {POS12+5,{FF,{m3,f3,2}}},
+ {POS12+7,{FF,{erlang,apply,2}}},
+ {POS12+8,{FF,{erlang,apply,3}}},
+ {POS13+1,{FF,{dm,df,1}}},
+ {POS13+6,{{read,bi,0},{foo,module_info,0}}},
+ {POS13+7,{{read,bi,0},{read,module_info,0}}},
+ {POS13+9,{{read,bi,0},{t,foo,1}}},
+ {POS14+11,{{read,bi,0},{erlang,module_info,0}}},
+ {POS14+17,{{read,bi,0},{read,bi,0}}}],
+
+ OK = case Version of
+ abstract_v1 ->
+ [{POS8+3, {FF,{erlang,apply,3}}},
+ {POS10+1, {FF,{erlang,apply,3}}},
+ {POS10+6, {FF,{erlang,apply,3}}}]
+ ++ O1;
+ _ ->
+% [{POS15+2,{{read,bi,0},{foo,t,0}}},
+% {POS15+3,{{read,bi,0},{bar,t,0}}},
+% {POS15+6,{{read,bi,0},{read,local,0}}},
+% {POS15+8,{{read,bi,0},{foo,t,0}}},
+% {POS15+10,{{read,bi,0},{bar,t,0}}}] ++
+ O1
+ end,
+
+ %% When builtins =:= true:
+ OKB = [{POS13+1,{FF,{erts_debug,apply,4}}},
+ {POS13+2,{FF,{erts_debug,apply,4}}},
+ {POS13+3,{FF,{erts_debug,apply,4}}},
+ {POS1+3, {FF,{erlang,binary_to_term,1}}},
+ {POS3+1, {FF,{erlang,spawn,3}}},
+ {POS3+2, {FF,{erlang,spawn,3}}},
+ {POS3+3, {FF,{erlang,spawn_link,3}}},
+ {POS3+4, {FF,{erlang,spawn_link,3}}},
+ {POS6+4, {FF,{erlang,spawn,3}}},
+ {POS13+5, {{read,bi,0},{erlang,length,1}}},
+ {POS14+3, {{read,bi,0},{erlang,length,1}}}]
+ ++ OK,
+
+ {U, OK, OKB}.
+
+read2(suite) -> [];
+read2(doc) -> ["Data read from the Abstract Code (cont)"];
+read2(Conf) when is_list(Conf) ->
+ %% Handles the spawn_opt versions added in R9 (OTP-4180).
+ %% Expected augmentations: try/catch, cond.
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"read"),
+ File = fname(Dir, "read2.erl"),
+ MFile = fname(Dir, "read2"),
+ Beam = fname(Dir, "read2.beam"),
+ Test = <<"-module(read2).
+ -compile(export_all).
+
+ f() ->
+ spawn_opt({read2,f}, % POS2
+ [f()]),
+ spawn_opt(fun() -> foo end, [link]),
+ spawn_opt(f(),
+ {read2,f}, [{min_heap_size,1000}]),
+ spawn_opt(f(),
+ fun() -> f() end, [flopp]),
+ spawn_opt(f(),
+ read2, f, [], []);
+ f() ->
+ %% Duplicated unresolved calls are ignored:
+ (f())(foo,bar),(f())(foo,bar). % POS1
+ ">>,
+ ?line ok = file:write_file(File, Test),
+ ?line {ok, read2} = compile:file(File, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, read2} = xref:add_module(s, MFile),
+ ?line {U0, OK0} = read2_expected(),
+
+ U = to_external(relation_to_family(converse(from_term(U0)))),
+ OK = to_external(relation_to_family(converse(from_term(OK0)))),
+ ?line {ok, U2} = xref:q(s, "(Lin) UC"),
+ ?line {ok, OK2} = xref:q(s, "(Lin) (E - UC)"),
+ ?line true = U =:= U2,
+ ?line true = OK =:= OK2,
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+
+read2_expected() ->
+ POS1 = 16,
+ POS2 = 5,
+ FF = {read2,f,0},
+ U = [{POS1,{FF,{'$M_EXPR','$F_EXPR',2}}}],
+ OK = [{POS2,{FF,{erlang,spawn_opt,2}}},
+ {POS2,{FF,FF}},
+ {POS2+1,{FF,FF}},
+ {POS2+2,{FF,{erlang,spawn_opt,2}}},
+ {POS2+3,{FF,{erlang,spawn_opt,3}}},
+ {POS2+3,{FF,FF}},
+ {POS2+3,{FF,FF}},
+ {POS2+5,{FF,{erlang,spawn_opt,3}}},
+ {POS2+5,{FF,FF}},
+ {POS2+6,{FF,FF}},
+ {POS2+7,{FF,{erlang,spawn_opt,5}}},
+ {POS2+7,{FF,FF}},
+ {POS2+7,{FF,FF}},
+ {POS1,{FF,FF}}],
+ {U, OK}.
+
+remove(suite) -> [];
+remove(doc) -> ["Remove modules, applications, releases"];
+remove(Conf) when is_list(Conf) ->
+ S = new(),
+ ?line {error, _, {no_such_module, mod}} =
+ xref_base:remove_module(S, mod),
+ ?line {error, _, {no_such_application, app}} =
+ xref_base:remove_application(S, app),
+ ?line {error, _, {no_such_release, rel}} =
+ xref_base:remove_release(S, rel),
+ ?line ok = xref_base:delete(S),
+ ok.
+
+replace(suite) -> [];
+replace(doc) -> ["Replace modules, applications, releases"];
+replace(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"rel2"),
+ X = fname(Dir, "x.erl"),
+ Y = fname(Dir, "y.erl"),
+ A1_0 = fname(Dir, fname("lib","app1-1.0")),
+ A1_1 = fname(Dir, fname("lib","app1-1.1")),
+ A2 = fname(Dir, fname("lib","app2-1.1")),
+ EB1_0 = fname(A1_0, "ebin"),
+ EB1_1 = fname(A1_1, "ebin"),
+ Xbeam = fname(EB1_1, "x.beam"),
+ Ybeam = fname(EB1_1, "y.beam"),
+
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB1_0}]),
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB1_1}]),
+ ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
+
+ ?line {ok, _} = start(s),
+ ?line {ok, false} = xref:set_default(s, verbose, false),
+ ?line {ok, true} = xref:set_default(s, warnings, false),
+ ?line {ok, rel2} = xref:add_release(s, Dir, []),
+ ?line {error, _, _} = xref:replace_application(s, app1, "no_data"),
+ ?line {error, _, {no_such_application, app12}} =
+ xref:replace_application(s, app12, A1_0, []),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref:replace_application(s, app1, {foo,bar}, []),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref:replace_application(s, foo, bar, [not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref:replace_application(s, foo, bar, [{builtins,not_a_value}]),
+ ?line {ok, app1} =
+ xref:replace_application(s, app1, A1_0),
+ ?line [{_, AppInfo}] = xref:info(s, applications, app1),
+ ?line {value, {release, [rel2]}} = keysearch(release, 1, AppInfo),
+
+ ?line {error, _, {no_such_module, xx}} =
+ xref:replace_module(s, xx, Xbeam, []),
+ ?line {error, _, {invalid_options,[{builtins,true},not_an_option]}} =
+ xref:replace_module(s, foo, bar,[{builtins,true},not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref:replace_module(s, foo, bar, [{builtins,not_a_value}]),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref:replace_module(s, x, {foo,bar}),
+ ?line {ok, x} = xref:replace_module(s, x, Xbeam),
+ ?line [{x, ModInfo}] = xref:info(s, modules, x),
+ ?line {value, {application, [app1]}} =
+ keysearch(application, 1, ModInfo),
+
+ ?line {ok, x} = compile:file(X, [no_debug_info, {outdir,EB1_1}]),
+ ?line {error, _, {no_debug_info, _}} = xref:replace_module(s, x, Xbeam),
+ ?line {error, _, {module_mismatch, x,y}} =
+ xref:replace_module(s, x, Ybeam),
+ ?line case os:type() of
+ {unix, _} ->
+ ?line hide_file(Ybeam),
+ ?line {error, _, {file_error, _, _}} =
+ xref:replace_module(s, x, Ybeam);
+ _ ->
+ true
+ end,
+ ?line ok = xref:remove_module(s, x),
+ ?line {error, _, {no_debug_info, _}} = xref:add_module(s, Xbeam),
+
+ %% "app2" is ignored, the old application name is kept
+ ?line {ok, app1} = xref:replace_application(s, app1, A2),
+
+ ?line xref:stop(s),
+ ?line ok = file:delete(fname(EB1_0, "x.beam")),
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+ ok.
+
+update(suite) -> [];
+update(doc) -> ["The update() function"];
+update(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"update"),
+ Source = fname(Dir, "x.erl"),
+ Beam = fname(Dir, "x.beam"),
+ ?line copy_file(fname(Dir, "x.erl.1"), Source),
+ ?line {ok, x} = compile:file(Source, [debug_info, {outdir,Dir}]),
+
+ ?line {ok, _} = start(s),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?line {ok, [x]} = xref:add_directory(s, Dir, [{builtins,true}]),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref:update(s, [not_an_option]),
+ ?line {ok, []} = xref:update(s),
+ ?line {ok, [{erlang,atom_to_list,1}]} = xref:q(s, "XU"),
+
+ ?line [{x, ModInfo}] = xref:info(s, modules, x),
+ ?line case keysearch(directory, 1, ModInfo) of
+ {value, {directory, Dir}} -> ok
+ end,
+
+ timer:sleep(2000), % make sure modification time has changed
+ ?line copy_file(fname(Dir, "x.erl.2"), Source),
+ ?line {ok, x} = compile:file(Source, [debug_info, {outdir,Dir}]),
+ ?line {ok, [x]} = xref:update(s, []),
+ ?line {ok, [{erlang,list_to_atom,1}]} = xref:q(s, "XU"),
+
+ timer:sleep(2000),
+ ?line {ok, x} = compile:file(Source, [no_debug_info,{outdir,Dir}]),
+ ?line {error, _, {no_debug_info, _}} = xref:update(s),
+
+ ?line xref:stop(s),
+ ?line ok = file:delete(Beam),
+ ?line ok = file:delete(Source),
+ ok.
+
+deprecated(suite) -> [];
+deprecated(doc) -> ["OTP-4695: Deprecated functions."];
+deprecated(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+ File = fname(Dir, "depr.erl"),
+ MFile_r9c = fname(Dir, "depr_r9c"),
+ MFile = fname(Dir, "depr"),
+ Beam = fname(Dir, "depr.beam"),
+ %% This file has been compiled to ?datadir/depr_r9c.beam
+ %% using the R9C compiler. From R10B and onwards the linter
+ %% checks the 'deprecated' attribute as well.
+% Test = <<"-module(depr).
+
+% -export([t/0,f/1,bar/2,f/2,g/3]).
+
+% -deprecated([{f,1}, % DF
+% {bar,2,eventually}]). % DF_3
+% -deprecated([{f,1,next_major_release}]). % DF_2 (again)
+% -deprecated([{frutt,0,next_version}]). % message...
+% -deprecated([{f,2,next_major_release}, % DF_2
+% {g,3,next_version}, % DF_1
+% {ignored,10,100}]). % message...
+% -deprecated([{does_not_exist,1}]). % message...
+
+% -deprecated(foo). % message...
+
+% t() ->
+% frutt(1),
+% g(1,2, 3),
+% ?MODULE:f(10).
+
+% f(A) ->
+% ?MODULE:f(A,A).
+
+% f(X, Y) ->
+% ?MODULE:g(X, Y, X).
+
+% g(F, G, H) ->
+% ?MODULE:bar(F, {G,H}).
+
+% bar(_, _) ->
+% true.
+
+% frutt(_) ->
+% frutt().
+
+% frutt() ->
+% true.
+% ">>,
+
+% ?line ok = file:write_file(File, Test),
+% ?line {ok, depr_r9c} = compile:file(File, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, depr_r9c} = xref:add_module(s, MFile_r9c),
+ M9 = depr_r9c,
+ DF_1 = usort([{{M9,f,2},{M9,g,3}}]),
+ DF_2 = usort(DF_1++[{{M9,f,1},{M9,f,2}},{{M9,t,0},{M9,f,1}}]),
+ DF_3 = usort(DF_2++[{{M9,g,3},{M9,bar,2}}]),
+ DF = usort(DF_3++[{{M9,t,0},{M9,f,1}}]),
+
+ ?line {ok,DF} = xref:analyze(s, deprecated_function_calls),
+ ?line {ok,DF_1} =
+ xref:analyze(s, {deprecated_function_calls,next_version}),
+ ?line {ok,DF_2} =
+ xref:analyze(s, {deprecated_function_calls,next_major_release}),
+ ?line {ok,DF_3} =
+ xref:analyze(s, {deprecated_function_calls,eventually}),
+
+ D = to_external(range(from_term(DF))),
+ D_1 = to_external(range(from_term(DF_1))),
+ D_2 = to_external(range(from_term(DF_2))),
+ D_3 = to_external(range(from_term(DF_3))),
+
+ ?line {ok,D} = xref:analyze(s, deprecated_functions),
+ ?line {ok,D_1} =
+ xref:analyze(s, {deprecated_functions,next_version}),
+ ?line {ok,D_2} =
+ xref:analyze(s, {deprecated_functions,next_major_release}),
+ ?line {ok,D_3} =
+ xref:analyze(s, {deprecated_functions,eventually}),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ Test2= <<"-module(depr).
+
+ -export([t/0,f/1,bar/2,f/2,g/3]).
+
+ -deprecated([{'_','_',eventually}]). % DF_3
+ -deprecated([{f,'_',next_major_release}]). % DF_2
+ -deprecated([{g,'_',next_version}]). % DF_1
+ -deprecated([{bar,2}]). % DF
+
+ t() ->
+ g(1,2, 3),
+ ?MODULE:f(10).
+
+ f(A) ->
+ ?MODULE:f(A,A).
+
+ f(X, Y) ->
+ ?MODULE:g(X, Y, X).
+
+ g(F, G, H) ->
+ ?MODULE:bar(F, {G,H}).
+
+ bar(_, _) ->
+ ?MODULE:t().
+ ">>,
+
+ ?line ok = file:write_file(File, Test2),
+ ?line {ok, depr} = compile:file(File, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, depr} = xref:add_module(s, MFile),
+
+ M = depr,
+ DFa_1 = usort([{{M,f,2},{M,g,3}}]),
+ DFa_2 = usort(DFa_1++[{{M,f,1},{M,f,2}},{{M,t,0},{M,f,1}}]),
+ DFa_3 = usort(DFa_2++[{{M,bar,2},{M,t,0}},{{M,g,3},{M,bar,2}}]),
+ DFa = DFa_3,
+
+ ?line {ok,DFa} = xref:analyze(s, deprecated_function_calls),
+ ?line {ok,DFa_1} =
+ xref:analyze(s, {deprecated_function_calls,next_version}),
+ ?line {ok,DFa_2} =
+ xref:analyze(s, {deprecated_function_calls,next_major_release}),
+ ?line {ok,DFa_3} =
+ xref:analyze(s, {deprecated_function_calls,eventually}),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ %% All of the module is deprecated.
+ Test3= <<"-module(depr).
+
+ -export([t/0,f/1,bar/2,f/2,g/3]).
+
+ -deprecated([{f,'_',next_major_release}]). % DF_2
+ -deprecated([{g,'_',next_version}]). % DF_1
+ -deprecated(module). % DF
+
+ t() ->
+ g(1,2, 3),
+ ?MODULE:f(10).
+
+ f(A) ->
+ ?MODULE:f(A,A).
+
+ f(X, Y) ->
+ ?MODULE:g(X, Y, X).
+
+ g(F, G, H) ->
+ ?MODULE:bar(F, {G,H}).
+
+ bar(_, _) ->
+ ?MODULE:t().
+ ">>,
+
+ ?line ok = file:write_file(File, Test3),
+ ?line {ok, depr} = compile:file(File, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, depr} = xref:add_module(s, MFile),
+
+ DFb_1 = usort([{{M,f,2},{M,g,3}}]),
+ DFb_2 = usort(DFb_1++[{{M,f,1},{M,f,2}},{{M,t,0},{M,f,1}}]),
+ DFb_3 = DFb_2,
+ DFb = usort(DFb_2++[{{M,bar,2},{M,t,0}},{{M,g,3},{M,bar,2}}]),
+
+ ?line {ok,DFb} = xref:analyze(s, deprecated_function_calls),
+ ?line {ok,DFb_1} =
+ xref:analyze(s, {deprecated_function_calls,next_version}),
+ ?line {ok,DFb_2} =
+ xref:analyze(s, {deprecated_function_calls,next_major_release}),
+ ?line {ok,DFb_3} =
+ xref:analyze(s, {deprecated_function_calls,eventually}),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+
+trycatch(suite) -> [];
+trycatch(doc) -> ["OTP-5152: try/catch, final (?) version."];
+trycatch(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+ File = fname(Dir, "trycatch.erl"),
+ MFile = fname(Dir, "trycatch"),
+ Beam = fname(Dir, "trycatch.beam"),
+ Test = <<"-module(trycatch).
+
+ -export([trycatch/0]).
+
+ trycatch() ->
+ try
+ foo:bar(),
+ bar:foo() of
+ 1 -> foo:foo();
+ 2 -> bar:bar()
+ catch
+ error:a -> err:e1();
+ error:b -> err:e2()
+ after
+ fini:shed()
+ end.
+ ">>,
+
+ ?line ok = file:write_file(File, Test),
+ ?line {ok, trycatch} = compile:file(File, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, trycatch} = xref:add_module(s, MFile),
+ A = trycatch,
+ {ok,[{{{A,A,0},{bar,bar,0}},[10]},
+ {{{A,A,0},{bar,foo,0}},[8]},
+ {{{A,A,0},{err,e1,0}},[12]},
+ {{{A,A,0},{err,e2,0}},[13]},
+ {{{A,A,0},{fini,shed,0}},[15]},
+ {{{A,A,0},{foo,bar,0}},[7]},
+ {{{A,A,0},{foo,foo,0}},[9]}]} =
+ xref:q(s, "(Lin) (E | trycatch:trycatch/0)"),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+
+abstract_modules(suite) -> [];
+abstract_modules(doc) -> ["OTP-5520: Abstract (parameterized) modules."];
+abstract_modules(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+ File = fname(Dir, "absmod.erl"),
+ MFile = fname(Dir, "absmod"),
+ Beam = fname(Dir, "absmod.beam"),
+ Test = <<"-module(param, [A, B]).
+
+ -export([args/1]).
+
+ args(C) ->
+ X = local(C),
+ Y = THIS:new(), % undef
+ Z = new(A, B),
+ {X, Y, Z}.
+
+ local(C) ->
+ module_info(C).
+ ">>,
+
+ ?line ok = file:write_file(File, Test),
+
+ %% The compiler will no longer allow us to have a mismatch between
+ %% the module name and the output file, so we must use a trick.
+ ?line {ok, param, BeamCode} = compile:file(File, [binary,debug_info]),
+ ?line ok = file:write_file(filename:join(Dir, Beam), BeamCode),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, param} = xref:add_module(s, MFile, {warnings,false}),
+ A = param,
+ ?line {ok, [{{{A,args,1},{'$M_EXPR',new,0}},[7]},
+ {{{A,args,1},{A,local,1}},[6]},
+ {{{A,args,1},{A,new,2}},[8]},
+ {{{A,local,1},{A,module_info,1}},[12]},
+ {{{param,new,2},{param,instance,2}},[0]}]} =
+ xref:q(s, "(Lin) E"),
+ ?line {ok,[{param,args,1},
+ {param,instance,2},
+ {param,local,1},
+ {param,module_info,1},
+ {param,new,2}]} = xref:q(s, "F"),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line {ok, _} = xref:start(s, {xref_mode, modules}),
+ ?line {ok, param} = xref:add_module(s, MFile),
+ ?line {ok,[{param,args,1},
+ {param,instance,2},
+ {param,new,2}]} = xref:q(s, "X"),
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+fun_mfa(suite) -> [];
+fun_mfa(doc) -> ["OTP-5653: fun M:F/A."];
+fun_mfa(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+ File = fname(Dir, "fun_mfa.erl"),
+ MFile = fname(Dir, "fun_mfa"),
+ Beam = fname(Dir, "fun_mfa.beam"),
+ Test = <<"-module(fun_mfa).
+
+ -export([t/0, t1/0, t2/0, t3/0]).
+
+ t() ->
+ F = fun ?MODULE:t/0,
+ (F)().
+
+ t1() ->
+ F = fun t/0,
+ (F)().
+
+ t2() ->
+ fun ?MODULE:t/0().
+
+ t3() ->
+ fun t3/0().
+ ">>,
+
+ ?line ok = file:write_file(File, Test),
+ A = fun_mfa,
+ ?line {ok, A} = compile:file(File, [debug_info,{outdir,Dir}]),
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, A} = xref:add_module(s, MFile, {warnings,false}),
+ ?line {ok, [{{{A,t,0},{'$M_EXPR','$F_EXPR',0}},[7]},
+ {{{A,t,0},{A,t,0}},[6]},
+ {{{A,t1,0},{'$M_EXPR','$F_EXPR',0}},[11]},
+ {{{A,t1,0},{A,t,0}},[10]},
+ {{{A,t2,0},{A,t,0}},[14]},
+ {{{A,t3,0},{fun_mfa,t3,0}},[17]}]} =
+ xref:q(s, "(Lin) E"),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+qlc(suite) -> [];
+qlc(doc) -> ["OTP-5195: A bug fix when using qlc:q/1,2."];
+qlc(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+ File = fname(Dir, "qlc.erl"),
+ MFile = fname(Dir, "qlc"),
+ Beam = fname(Dir, "qlc.beam"),
+ Test = <<"-module(qlc).
+
+ -include_lib(\"stdlib/include/qlc.hrl\").
+
+ -export([t/0]).
+
+ t() ->
+ dets:open_file(t, []),
+ dets:insert(t, [{1,a},{2,b},{3,c},{4,d}]),
+ MS = ets:fun2ms(fun({X,Y}) when (X > 1) or (X < 5) -> {Y}
+ end),
+ QH1 = dets:table(t, [{traverse, {select, MS}}]),
+ QH2 = qlc:q([{Y} || {X,Y} <- dets:table(t),
+ (X > 1) or (X < 5)]),
+ true = qlc:info(QH1) =:= qlc:info(QH2),
+ dets:close(t),
+ ok.
+ ">>,
+
+ ?line ok = file:write_file(File, Test),
+ A = qlc,
+ ?line {ok, A} = compile:file(File, [debug_info,{outdir,Dir}]),
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, A} = xref:add_module(s, MFile, {warnings,false}),
+ ?line {ok, _} = xref:q(s, "(Lin) E"), % is can be loaded
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+
+analyses(suite) ->
+ [analyze, basic, md, q, variables, unused_locals].
+
+analyze(suite) -> [];
+analyze(doc) -> ["Simple analyses"];
+analyze(Conf) when is_list(Conf) ->
+ S0 = new(),
+ ?line {{error, _, {invalid_options,[not_an_option]}}, _} =
+ xref_base:analyze(S0, undefined_function_calls, [not_an_option]),
+ ?line {{error, _, {invalid_query,{q}}}, _} = xref_base:q(S0,{q}),
+ ?line {{error, _, {unknown_analysis,foo}}, _} = xref_base:analyze(S0, foo),
+ ?line {{error, _, {unknown_constant,"foo:bar/-1"}}, _} =
+ xref_base:analyze(S0, {use,{foo,bar,-1}}),
+
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"rel2"),
+ X = fname(Dir, "x.erl"),
+ Y = fname(Dir, "y.erl"),
+ A1_1 = fname([Dir,"lib","app1-1.1"]),
+ A2 = fname([Dir,"lib","app2-1.1"]),
+ EB1_1 = fname(A1_1, "ebin"),
+ EB2 = fname(A2, "ebin"),
+ Xbeam = fname(EB2, "x.beam"),
+ Ybeam = fname(EB1_1, "y.beam"),
+
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB2}]),
+ ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
+
+ ?line {ok, rel2, S1} = xref_base:add_release(S0, Dir, [{verbose,false}]),
+ ?line S = set_up(S1),
+
+ ?line {ok, _} =
+ analyze(undefined_function_calls, [{{x,xx,0},{x,undef,0}}], S),
+ ?line {ok, _} = analyze(undefined_functions, [{x,undef,0}], S),
+ ?line {ok, _} = analyze(locals_not_used, [{x,l,0},{x,l1,0}], S),
+ ?line {ok, _} = analyze(exports_not_used, [{x,xx,0},{y,t,0}], S),
+
+ ?line {ok, _} =
+ analyze(deprecated_function_calls, [{{y,t,0},{x,t,0}}], S),
+ ?line {ok, _} = analyze({deprecated_function_calls,next_version}, [], S),
+ ?line {ok, _} =
+ analyze({deprecated_function_calls,next_major_release}, [], S),
+ ?line {ok, _} = analyze({deprecated_function_calls,eventually},
+ [{{y,t,0},{x,t,0}}], S),
+ ?line {ok, _} = analyze(deprecated_functions, [{x,t,0}], S),
+ ?line {ok, _} = analyze({deprecated_functions,next_version}, [], S),
+ ?line {ok, _} =
+ analyze({deprecated_functions,next_major_release}, [], S),
+ ?line {ok, _} = analyze({deprecated_functions,eventually}, [{x,t,0}], S),
+
+ ?line {ok, _} = analyze({call, {x,xx,0}}, [{x,undef,0}], S),
+ ?line {ok, _} =
+ analyze({call, [{x,xx,0},{x,l,0}]}, [{x,l1,0},{x,undef,0}], S),
+ ?line {ok, _} = analyze({use, {x,l,0}}, [{x,l1,0}], S),
+ ?line {ok, _} =
+ analyze({use, [{x,l,0},{x,l1,0}]}, [{x,l,0},{x,l1,0}], S),
+
+ ?line {ok, _} = analyze({module_call, x}, [x], S),
+ ?line {ok, _} = analyze({module_call, [x,y]}, [x], S),
+ ?line {ok, _} = analyze({module_use, x}, [x,y], S),
+ ?line {ok, _} = analyze({module_use, [x,y]}, [x,y], S),
+
+ ?line {ok, _} = analyze({application_call, app1}, [app2], S),
+ ?line {ok, _} = analyze({application_call, [app1,app2]}, [app2], S),
+ ?line {ok, _} = analyze({application_use, app2}, [app1,app2], S),
+ ?line {ok, _} = analyze({application_use, [app1,app2]}, [app1,app2], S),
+
+ ?line ok = xref_base:delete(S),
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+ ok.
+
+basic(suite) -> [];
+basic(doc) -> ["Use of operators"];
+basic(Conf) when is_list(Conf) ->
+ ?line S0 = new(),
+
+ F1 = {m1,f1,1},
+ F6 = {m1,f2,6}, % X
+ F2 = {m2,f1,2},
+ F3 = {m2,f2,3}, % X
+ F7 = {m2,f3,7}, % X
+ F4 = {m3,f1,4}, % X
+ F5 = {m3,f2,5},
+
+ UF1 = {m1,f12,17},
+ UF2 = {m17,f17,177},
+
+ E1 = {F1,F3}, % X
+ E2 = {F6,F7}, % X
+ E3 = {F2,F6}, % X
+ E4 = {F1,F4}, % X
+ E5 = {F4,F5},
+ E6 = {F7,F4}, % X
+ E7 = {F1,F6},
+
+ UE1 = {F2,UF2}, % X
+ UE2 = {F5,UF1}, % X
+
+ D1 = {F1,12},
+ D6 = {F6,3},
+ DefAt_m1 = [D1,D6],
+ X_m1 = [F6],
+ % L_m1 = [F1],
+ XC_m1 = [E1,E2,E4],
+ LC_m1 = [E7],
+ LCallAt_m1 = [{E7,12}],
+ XCallAt_m1 = [{E1,13},{E2,17},{E4,7}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ D2 = {F2,7},
+ D3 = {F3,9},
+ D7 = {F7,19},
+ DefAt_m2 = [D2,D3,D7],
+ X_m2 = [F3,F7],
+ % L_m2 = [F2],
+ XC_m2 = [E3,E6,UE1],
+ LC_m2 = [],
+ LCallAt_m2 = [],
+ XCallAt_m2 = [{E3,96},{E6,12},{UE1,77}],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ D4 = {F4,6},
+ D5 = {F5,97},
+ DefAt_m3 = [D4,D5],
+ X_m3 = [F4],
+ % L_m3 = [F5],
+ XC_m3 = [UE2],
+ LC_m3 = [E5],
+ LCallAt_m3 = [{E5,19}],
+ XCallAt_m3 = [{UE2,22}],
+ Info3 = #xref_mod{name = m3, app_name = [a3]},
+ ?line S3 = add_module(S2, Info3, DefAt_m3, X_m3, LCallAt_m3, XCallAt_m3,
+ XC_m3, LC_m3),
+
+ Info4 = #xref_mod{name = m4, app_name = [a2]},
+ ?line S4 = add_module(S3, Info4, [], [], [], [], [], []),
+
+ AppInfo1 = #xref_app{name = a1, rel_name = [r1]},
+ ?line S9 = add_application(S4, AppInfo1),
+ AppInfo2 = #xref_app{name = a2, rel_name = [r1]},
+ ?line S10 = add_application(S9, AppInfo2),
+ AppInfo3 = #xref_app{name = a3, rel_name = [r2]},
+ ?line S11 = add_application(S10, AppInfo3),
+
+ RelInfo1 = #xref_rel{name = r1},
+ ?line S12 = add_release(S11, RelInfo1),
+ RelInfo2 = #xref_rel{name = r2},
+ ?line S13 = add_release(S12, RelInfo2),
+
+ ?line S = set_up(S13),
+
+ ?line {ok, _} = eval("[m1,m2] + m:f/1", unknown_constant, S),
+ ?line {ok, _} = eval("[m1, m2, m:f/1]", type_mismatch, S),
+
+ ?line {ok, _} = eval("[m1, m1->m2]", type_mismatch, S),
+ ?line {ok, _} = eval("components:f/1", unknown_constant, S),
+ ?line {ok, _} = eval("'of':f/1", unknown_constant, S),
+ ?line {ok, _} = eval("of:f/1", parse_error, S),
+ ?line {ok, _} = eval("components", unknown_constant, S),
+ ?line {ok, _} = eval("[components, of, closure]", parse_error, S),
+ ?line {ok, _} = eval("[components, 'of', closure]", unknown_constant, S),
+
+ ?line {ok, _} = eval("[a1->a2,m1->m2]", type_mismatch, S),
+ ?line {ok, _} = eval("a1->a2,m1->m2", parse_error, S),
+
+ ?line {ok, _} = eval("m1->a1", type_mismatch, S),
+ ?line {ok, _} = eval("[{m1,f1,1}] : App", parse_error, S),
+ ?line {ok, _} = eval("[{m1,f1,1}] : Fun", [F1], S),
+ ?line {ok, _} = eval("range X", type_error, S),
+ ?line {ok, _} = eval("domain X", type_error, S),
+ ?line {ok, _} = eval("range M", type_error, S),
+ ?line {ok, _} = eval("domain M", type_error, S),
+
+ % Misc.
+ ?line {ok, _} = eval("not_a_prefix_operator m1", parse_error, S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [[F1,F6,F5]]), [m1,m3], S),
+ ?line {ok, _} = eval("(Lin) M - (Lin) m1",
+ [{F2,7},{F3,9},{F7,19},{F4,6},{F5,97},{UF2,0}], S),
+ ?line {ok, _} = eval(f("(Lin) M * (Lin) ~p", [[F1,F6]]),
+ [{F1,12},{F6,3}], S),
+
+ ?line {ok, _} = eval(f("X * ~p", [[F1, F2, F3, F4, F5]]), [F3, F4], S),
+ ?line {ok, _} = eval("X", [F6,F3,F7,F4], S),
+ ?line {ok, _} = eval("X * AM", [F6,F3,F7,F4], S),
+ ?line {ok, _} = eval("X * a2", [F3,F7], S),
+
+ ?line {ok, _} = eval("L * r1", [F1,F2], S),
+ ?line {ok, _} = eval("U", [UF1, UF2], S),
+ ?line {ok, _} = eval("U * AM", [UF1], S),
+ ?line {ok, _} = eval("U * UM", [UF2], S),
+ ?line {ok, _} = eval("XU * [m1, m2]", [F6,F3,F7,UF1], S),
+ ?line {ok, _} = eval("LU * [m3, m4]", [F5], S),
+ ?line {ok, _} = eval("UU", [F1,F2], S),
+
+ ?line {ok, _} = eval("XC | m1", [E1,E2,E4], S),
+ ?line {ok, _} = eval(f("XC | ~p", [F1]), [E1,E4], S),
+ ?line {ok, _} = eval(f("(XXL) (Lin) (XC | ~p)", [F1]),
+ [{{D1,D3},[13]},{{D1,D4},[7]}],S),
+ ?line {ok, _} = eval(f("XC | (~p + ~p)", [F1, F2]), [E1,E4,E3,UE1], S),
+ ?line {ok, _} = eval(f("(XXL) (Lin) (XC | ~p)", [F1]),
+ [{{D1,D3},[13]},{{D1,D4},[7]}], S),
+ ?line {ok, _} = eval("LC | m3", [E5], S),
+ ?line {ok, _} = eval(f("LC | ~p", [F1]), [E7], S),
+ ?line {ok, _} = eval(f("LC | (~p + ~p)", [F1, F4]), [E7, E5], S),
+ ?line {ok, _} = eval("E | m1", [E1,E2,E4,E7], S),
+ ?line {ok, _} = eval(f("E | ~p", [F1]), [E1,E7,E4], S),
+ ?line {ok, _} = eval(f("E | (~p + ~p)", [F1, F2]), [E1,E7,E4,E3,UE1], S),
+
+ ?line {ok, _} = eval("XC || m1", [E3,UE2], S),
+ ?line {ok, _} = eval(f("XC || ~p", [F6]), [E3], S),
+ ?line {ok, _} = eval(f("XC || (~p + ~p)", [F4, UF2]), [UE1,E4,E6], S),
+ ?line {ok, _} = eval("LC || m3", [E5], S),
+ ?line {ok, _} = eval(f("LC || ~p", [F1]), [], S),
+ ?line {ok, _} = eval(f("LC || ~p", [F6]), [E7], S),
+ ?line {ok, _} = eval(f("LC || (~p + ~p)", [F5, F6]), [E7,E5], S),
+ ?line {ok, _} = eval("E || m1", [E3,UE2,E7], S),
+ ?line {ok, _} = eval(f("E || ~p", [F6]), [E3,E7], S),
+ ?line {ok, _} = eval(f("E || (~p + ~p)", [F3,F4]), [E1,E4,E6], S),
+
+ ?line {ok, _} = eval(f("~p + ~p", [F1,F2]), [F1,F2], S),
+ ?line {ok, _} = eval(f("~p * ~p", [m1,[F1,F6,F2]]), [F1,F6], S),
+ ?line {ok, _} = eval(f("~p * ~p", [F1,F2]), [], S),
+
+ %% range, domain
+ ?line {ok, _} = eval("range (E || m1)", [F6,UF1], S),
+ ?line {ok, _} = eval("domain (E || m1)", [F1,F2,F5], S),
+ ?line {ok, _} = eval(f("E | domain ~p", [[E1, {F2,F4}]]),
+ [E1,E7,E4,E3,UE1], S),
+
+ %% components, condensation, use, call
+ ?line {ok, _} = eval("(Lin) components E", type_error, S),
+ ?line {ok, _} = eval("components (Lin) E", type_error, S),
+ ?line {ok, _} = eval("components V", type_error, S),
+ ?line {ok, _} = eval("components E + components E", type_error, S),
+
+ ?line {ok, _} = eval(f("range (closure E | ~p)", [[F1,F2]]),
+ [F6,F3,F7,F4,F5,UF1,UF2], S),
+ ?line {ok, _} =
+ eval(f("domain (closure E || ~p)", [[UF2,F7]]), [F1,F2,F6], S),
+ ?line {ok, _} = eval("components E", [], S),
+ ?line {ok, _} = eval("components (Mod) E", [[m1,m2,m3]], S),
+ ?line {ok, _} = eval("components closure (Mod) E", [[m1,m2,m3]], S),
+ ?line {ok, _} = eval("condensation (Mod) E",
+ [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]}], S),
+ ?line {ok, _} = eval("condensation closure (Mod) E",
+ [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]}], S),
+ ?line {ok, _} = eval("condensation closure closure closure (Mod) E",
+ [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]}], S),
+ ?line {ok, _} = eval("weak condensation (Mod) E",
+ [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]},{[m17],[m17]}], S),
+ ?line {ok, _} = eval("strict condensation (Mod) E",
+ [{[m1,m2,m3],[m17]}], S),
+ ?line {ok, _} = eval("range condensation (Mod) E",
+ [[m1,m2,m3],[m17]], S),
+ ?line {ok, _} = eval("domain condensation (Mod) E",
+ [[m1,m2,m3]], S),
+
+ %% |, ||, |||
+ ?line {ok, _} = eval("(Lin) E || V", type_error, S),
+ ?line {ok, _} = eval("E ||| (Lin) V", type_error, S),
+ ?line {ok, _} = eval("E ||| m1", [E7], S),
+ ?line {ok, _} = eval("closure E ||| m1", [E7,{F1,UF1},{F6,UF1}], S),
+ ?line {ok, _} = eval("closure E ||| [m1,m2]",
+ [{F1,UF1},{F2,F7},{F1,F7},{F6,UF1},{F2,UF1},{F7,UF1},E7,E1,E2,E3], S),
+ ?line {ok, _} = eval("AE | a1", [{a1,a1},{a1,a2},{a1,a3}], S),
+
+ %% path ('of')
+ ?line {ok, _} = eval("(Lin) {m1,m2} of E", type_error, S),
+ ?line {ok, _} = eval("{m1,m2} of (Lin) E", type_error, S),
+ ?line [m1,m2] = eval("{m1,m2} of {m1,m2}", S),
+ ?line {ok, _} = eval("{m1,m2} of m1", type_error, S),
+ ?line {ok, _} = eval("{a3,m1} of ME", type_mismatch, S),
+ ?line [m1,m1] = eval("{m1} of ME", S),
+ ?line [m1,m1] = eval("{m1} of closure closure ME", S),
+ ?line false = eval("{m17} of ME", S),
+ ?line [m2,m1,m2] = eval("{m2} : Mod of ME", S),
+ ?line [m1,m2,m17] = eval("{m1, m17} of ME", S),
+ ?line [m1,m2,m17] = eval("m1 -> m17 of ME", S),
+ ?line {ok, _} = eval("[m1->m17,m17->m1] of ME", type_error, S),
+ ?line case eval(f("~p of E", [{F1,F7,UF1}]), S) of
+ [F1,F6,F7,F4,F5,UF1] -> ok
+ end,
+ ?line [a2,a1,a2] = eval("{a2} of AE", S),
+
+ %% weak/strict
+ ?line {ok, _} = eval("weak {m1,m2}", [{m1,m1},{m1,m2},{m2,m2}], S),
+ ?line {ok, _} = eval("strict [{m1,m1},{m1,m2},{m2,m2}]", [{m1,m2}], S),
+ ?line {ok, _} = eval("range weak [{m1,m2}] : Mod", [m1,m2], S),
+ ?line {ok, _} = eval("domain strict [{m1,m1},{m1,m2},{m2,m2}]", [m1], S),
+
+ %% #, number of
+ ?line {ok, _} = eval("# [{r1,r2}] : Rel", 1, S),
+ ?line {ok, _} = eval("# [{a3,a1}] : App", 1, S),
+ ?line {ok, _} = eval("# AE", 7, S),
+ ?line {ok, _} = eval("# ME", 8, S),
+ ?line {ok, _} = eval("# AE + # ME", 15, S),
+ ?line {ok, _} = eval("# AE * # ME", 56, S),
+ ?line {ok, _} = eval("# AE - # ME", -1, S),
+ ?line {ok, _} = eval("# E", 9, S),
+ ?line {ok, _} = eval("# V", 9, S),
+ ?line {ok, _} = eval("# (Lin) E", 9, S),
+ ?line {ok, _} = eval("# (ELin) E", 7, S),
+ ?line {ok, _} = eval("# closure E", type_error, S),
+ ?line {ok, _} = eval("# weak {m1,m2}", 3, S),
+ ?line {ok, _} = eval("#strict condensation (Mod) E", 1, S),
+ ?line {ok, _} = eval("#components closure (Mod) E", 1, S),
+ ?line {ok, _} = eval("# range strict condensation (Mod) E", 1, S),
+ ok.
+
+md(suite) -> [];
+md(doc) -> ["The xref:m() and xref:d() functions"];
+md(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"md"),
+ X = fname(Dir, "x__x.erl"),
+ Y = fname(Dir, "y__y.erl"),
+ Xbeam = fname(Dir, "x__x.beam"),
+ Ybeam = fname(Dir, "y__y.beam"),
+
+ ?line {error, _, {invalid_filename,{foo,bar}}} = xref:m({foo,bar}),
+ ?line {error, _, {invalid_filename,{foo,bar}}} = xref:d({foo,bar}),
+
+ ?line {ok, x__x} = compile:file(X, [debug_info, {outdir,Dir}]),
+ ?line {ok, y__y} = compile:file(Y, [debug_info, {outdir,Dir}]),
+
+ ?line {error, _, {no_such_module, foo_bar}} = xref:m(foo_bar),
+ ?line OldPath = code:get_path(),
+ ?line true = code:set_path([Dir | OldPath]),
+ ?line MInfo = xref:m(x__x),
+ ?line [{{x__x,t,1},{y__y,t,2}}] = info_tag(MInfo, undefined),
+ ?line [] = info_tag(MInfo, unused),
+ ?line [] = info_tag(MInfo, deprecated),
+ ?line DInfo = xref:d(Dir),
+ ?line [{{x__x,t,1},{y__y,t,2}}] = info_tag(DInfo, undefined),
+ ?line [{y__y,l,0},{y__y,l1,0}] = info_tag(DInfo, unused),
+ ?line [] = info_tag(MInfo, deprecated),
+
+ %% Switch from 'functions' mode to 'modules' mode.
+ ?line {ok, x__x} = compile:file(X, [no_debug_info, {outdir,Dir}]),
+ ?line {ok, y__y} = compile:file(Y, [no_debug_info, {outdir,Dir}]),
+ ?line MInfoMod = xref:m(x__x),
+ ?line [{y__y,t,2}] = info_tag(MInfoMod, undefined),
+ ?line [] = info_tag(MInfo, deprecated),
+ ?line DInfoMod = xref:d(Dir),
+ ?line [{y__y,t,2}] = info_tag(DInfoMod, undefined),
+ ?line [] = info_tag(MInfo, deprecated),
+
+ ?line true = code:set_path(OldPath),
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+ ok.
+
+q(suite) -> [];
+q(doc) -> ["User queries"];
+q(Conf) when is_list(Conf) ->
+ ?line S0 = new(),
+ ?line {ok, _} = eval("'foo", parse_error, S0),
+ ?line {ok, _} = eval("TT = E, TT = V", variable_reassigned, S0),
+ ?line {ok, _} = eval("TT = E, TTT", unknown_variable, S0),
+ ?line {ok, S} = eval("TT := E", [], S0),
+ ?line {ok, S1} = eval("TT * TT * TT", [], S),
+ ?line {ok, _S2} = xref_base:forget(S1, 'TT'),
+ ok.
+
+variables(suite) -> [];
+variables(doc) -> ["Setting and getting values of query variables"];
+variables(Conf) when is_list(Conf) ->
+ ?line Sa = new(),
+ ?line {{error, _, {invalid_options,[not_an_option]}}, _} =
+ xref_base:variables(Sa, [not_an_option]),
+ ?line {error, _, {not_user_variable,foo}} = xref_base:forget(Sa, foo),
+ ?line Sa1 = set_up(Sa),
+ ?line {error, _, {not_user_variable,foo}} = xref_base:forget(Sa1, foo),
+ ?line ok = xref_base:delete(Sa1),
+
+ ?line S0 = new(),
+
+ F1 = {m1,f1,1},
+ F2 = {m2,f1,2},
+ Lib = {lib1,f1,1}, % undefined
+
+ E1 = {F1,F2},
+ E2 = {F2,F1},
+ E3 = {F1,Lib},
+
+ D1 = {F1,12},
+ DefAt_m1 = [D1],
+ X_m1 = [F1],
+ % L_m1 = [],
+ XC_m1 = [E1,E3],
+ LC_m1 = [],
+ LCallAt_m1 = [],
+ XCallAt_m1 = [{E1,13},{E3,17}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ D2 = {F2,7},
+ DefAt_m2 = [D2],
+ X_m2 = [F2],
+ % L_m2 = [],
+ XC_m2 = [E2],
+ LC_m2 = [],
+ LCallAt_m2 = [],
+ XCallAt_m2 = [{E2,96}],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ ?line S = set_up(S2),
+
+ ?line eval("T1=E, T2=E*T1, T3 = T2*T2, T4=range T3, T5=T3|T4, T5",
+ [E1,E2,E3], S),
+ ?line eval("((E*E)*(E*E)) | (range ((E*E)*(E*E)))",
+ [E1,E2,E3], S),
+ ?line eval("T1=V*V,T2=T1*V,T3=V*V*V,T3",
+ [F1,F2,Lib], S),
+ ?line eval("T1=V*V, T2=V*V, T1*T2",
+ [F1,F2,Lib], S),
+
+ ?line {ok, S100} = eval("T0 := E", [E1, E2, E3], S),
+ ?line {ok, S101} = eval("T1 := E | m1", [E1, E3], S100),
+ ?line {ok, S102} = eval("T2 := E | m2", [E2], S101),
+ ?line {{ok, [{user, ['T0', 'T1', 'T2']}]}, _} = xref_base:variables(S102),
+ ?line {ok, S103} = xref_base:forget(S102, 'T0'),
+ ?line {{ok, [{user, ['T1', 'T2']}]}, S104} =
+ xref_base:variables(S103, [user]),
+ ?line {ok, S105} = xref_base:forget(S104),
+ ?line {{ok, [{user, []}]}, S106} = xref_base:variables(S105),
+ ?line {{ok, [{predefined,_}]}, S107_0} =
+ xref_base:variables(S106, [predefined]),
+
+ ?line {ok, S107_1} =
+ eval("TT := E, TT2 := V, TT1 := TT * TT", [E1,E2,E3], S107_0),
+ ?line {{ok, [{user, ['TT', 'TT1', 'TT2']}]}, _} =
+ xref_base:variables(S107_1),
+ ?line {ok, S107} = xref_base:forget(S107_1),
+
+ CopyDir = ?copydir,
+ ?line Dir = fname(CopyDir,"lib_test"),
+ Beam = fname(Dir, "lib1.beam"),
+
+ ?line copy_file(fname(Dir, "lib1.erl"), Beam),
+ ?line {ok, S108} =
+ xref_base:set_library_path(S107, [Dir], [{verbose,false}]),
+ ?line {{error, _, _}, _} = xref_base:variables(S108, [{verbose,false}]),
+ ?line {ok, S109} = xref_base:set_library_path(S108, [], [{verbose,false}]),
+
+ ?line Tabs = length(ets:all()),
+
+ ?line {ok, S110} = eval("Eplus := closure E, TT := Eplus",
+ 'closure()', S109),
+ ?line {{ok, [{user, ['Eplus','TT']}]}, S111} = xref_base:variables(S110),
+ ?line {ok, S112} = xref_base:forget(S111, ['TT','Eplus']),
+ ?line true = Tabs =:= length(ets:all()),
+
+ ?line {ok, NS0} = eval("Eplus := closure E", 'closure()', S112),
+ ?line {{ok, [{user, ['Eplus']}]}, NS} = xref_base:variables(NS0),
+ ?line ok = xref_base:delete(NS),
+ ?line true = Tabs =:= length(ets:all()),
+
+ ?line ok = file:delete(Beam),
+ ok.
+
+unused_locals(suite) -> [];
+unused_locals(doc) -> ["OTP-5071. Too many unused functions."];
+unused_locals(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+
+ File1 = fname(Dir, "a.erl"),
+ MFile1 = fname(Dir, "a"),
+ Beam1 = fname(Dir, "a.beam"),
+ Test1 = <<"-module(a).
+ -export([f/1, g/2]).
+
+ f(X) ->
+ Y = b:f(X),
+ Z = b:g(Y),
+ start(b, h, [Z]).
+
+ g(X, Y) ->
+ ok.
+
+ start(M, F, A) ->
+ spawn(M, F, A).
+ ">>,
+ ?line ok = file:write_file(File1, Test1),
+ ?line {ok, a} = compile:file(File1, [debug_info,{outdir,Dir}]),
+
+ File2 = fname(Dir, "b.erl"),
+ MFile2 = fname(Dir, "b"),
+ Beam2 = fname(Dir, "b.beam"),
+ Test2 = <<"-module(b).
+ -export([f/1, g/2]).
+
+ f(X) ->
+ io:write(\"~w\", [X]),
+ a:start(timer, sleep, [1000]).
+
+ g(X, Y) ->
+ apply(a, g, [X, Y]).
+ ">>,
+
+ ?line ok = file:write_file(File2, Test2),
+ ?line {ok, b} = compile:file(File2, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, a} = xref:add_module(s, MFile1),
+ ?line {ok, b} = xref:add_module(s, MFile2),
+ ?line {ok, []} = xref:analyse(s, locals_not_used),
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File1),
+ ?line ok = file:delete(Beam1),
+ ?line ok = file:delete(File2),
+ ?line ok = file:delete(Beam2),
+ ok.
+
+misc(suite) ->
+ [format_error, otp_7423, otp_7831].
+
+format_error(suite) -> [];
+format_error(doc) -> ["Format error messages"];
+format_error(Conf) when is_list(Conf) ->
+ ?line {ok, _Pid} = start(s),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+
+ %% Parse error messages.
+ ?line 'Invalid regular expression "add(": unterminated \`(\'\n'
+ = fatom(xref:q(s,'"add("')),
+ ?line 'Invalid operator foo\n' =
+ fatom(xref:q(s,'foo E')),
+ ?line 'Invalid wildcard variable \'_Var\' (only \'_\' is allowed)\n'
+ = fatom(xref:q(s,"module:function/_Var")),
+ ?line 'Missing type of regular expression ".*"\n'
+ = fatom(xref:q(s,'".*"')),
+ ?line 'Type does not match structure of constant: \'M\' : Fun\n'
+ = fatom(xref:q(s,"'M' : Fun")),
+ ?line 'Type does not match structure of constant: ".*" : Fun\n'
+ = fatom(xref:q(s,'".*" : Fun')),
+ ?line 'Type does not match structure of constant: [m:f/1, m1:f2/3] : App\n'
+ = fatom(xref:q(s,"[m:f/1,m1:f2/3] : App")),
+ ?line 'Parse error on line 1: syntax error before: \'-\'\n' =
+ fatom(xref:q(s,"E + -")),
+ ?line "Parse error on line 1: unterminated atom starting with 'foo'\n"
+ = flatten(xref:format_error(xref:q(s,"'foo"))),
+ ?line 'Parse error at end of string: syntax error before: \n' =
+ fatom(xref:q(s,"E +")),
+ ?line 'Parse error on line 1: syntax error before: \'Lin\'\n' =
+ fatom(xref:q(s,"Lin")),
+
+ %% Other messages
+ ?line 'Variable \'QQ\' used before set\n' =
+ fatom(xref:q(s,"QQ")),
+ ?line 'Unknown constant a\n' =
+ fatom(xref:q(s,"{a} of E")),
+
+ %% Testing xref_parser:t2s/1.
+ ?line 'Variable assigned more than once: E := E + E\n' =
+ fatom(xref:q(s,"E:=E + E")),
+ ?line 'Variable assigned more than once: E = E + E\n' =
+ fatom(xref:q(s,"E=E + E")),
+ ?line "Operator applied to argument(s) of different or invalid type(s): "
+ "E + V * V\n" =
+ flatten(xref:format_error(xref:q(s,"E + (V * V)"))),
+ ?line {error,xref_compiler,{type_error,"(V + V) * E"}} =
+ xref:q(s,"(V + V) * E"),
+ ?line "Type does not match structure of constant: [m:f/3 -> g:h/17] : "
+ "App\n" =
+ flatten(xref:format_error(xref:q(s,"[{{m,f,3},{g,h,17}}] : App"))),
+ ?line 'Type does not match structure of constant: [m -> f, g -> h] : Fun\n'
+ = fatom(xref:q(s,"[{m,f},g->h] : Fun")),
+ ?line 'Type does not match structure of constant: {m, n, o} : Fun\n' =
+ fatom(xref:q(s,"{m,n,o} : Fun")),
+ ?line {error,xref_compiler,{type_error,"range (Lin) V"}} =
+ xref:q(s,"range ((Lin) V)"),
+ ?line {error,xref_compiler,{type_error,"condensation range E"}} =
+ xref:q(s,"condensation (range E)"),
+ ?line {error,xref_compiler,{type_error,"condensation (# E + # V)"}} =
+ xref:q(s,"condensation (# E + # V)"),
+ ?line {error,xref_compiler,{type_error,"range (# E + # E)"}} =
+ xref:q(s,"range (#E + #E)"),
+ ?line {error,xref_compiler,{type_error,"range (# E)"}} =
+ xref:q(s,"range #E"), % Hm...
+ ?line {error,xref_compiler,{type_error,"E + # E"}} =
+ xref:q(s,"E + #E + #E"), % Hm...
+ ?line {error,xref_compiler,{type_error,"V * E || V | V"}} =
+ xref:q(s,"V * (E || V) | V"),
+ ?line {error,xref_compiler,{type_error,"E || (E | V)"}} =
+ xref:q(s,"V * E || (E | V)"),
+ ?line {error,xref_compiler,{type_error,"E * \"m\" : Mod"}} =
+ xref:q(s,'E * "m" : Mod'),
+ ?line {error,xref_compiler,{type_error,"E * (\"m\":f/_ + m:\"f\"/3)"}} =
+ xref:q(s,'E * ("m":f/_ + m:"f"/3)'),
+
+ ?line xref:stop(s),
+ ok.
+
+otp_7423(suite) -> [];
+otp_7423(doc) -> ["OTP-7423. Xref scanner bug."];
+otp_7423(Conf) when is_list(Conf) ->
+ ?line {ok, _Pid} = start(s),
+ S = "E | [compiler] : App || [{erlang,
+ size,
+ 1}] : Fun",
+ ?line {error,xref_compiler,{unknown_constant,"compiler"}} = xref:q(s,S),
+ ?line xref:stop(s),
+ ok.
+
+otp_7831(suite) -> [];
+otp_7831(doc) -> ["OTP-7831. Allow anonymous Xref processes."];
+otp_7831(Conf) when is_list(Conf) ->
+ ?line {ok, Pid1} = xref:start([]),
+ ?line xref:stop(Pid1),
+ ?line {ok, Pid2} = xref:start([{xref_mode, modules}]),
+ ?line xref:stop(Pid2),
+ ok.
+
+%%%
+%%% Utilities
+%%%
+
+copy_file(Src, Dest) ->
+ file:copy(Src, Dest).
+
+fname(N) ->
+ filename:join(N).
+
+fname(Dir, Basename) ->
+ filename:join(Dir, Basename).
+
+new() ->
+ ?line {ok, S} = xref_base:new(),
+ S.
+
+set_up(S) ->
+ ?line {ok, S1} = xref_base:set_up(S, [{verbose, false}]),
+ S1.
+
+eval(Query, E, S) ->
+ ?format("------------------------------~n", []),
+ ?format("Evaluating ~p~n", [Query]),
+ ?line {Answer, NewState} = xref_base:q(S, Query, [{verbose, false}]),
+ {Reply, Expected} =
+ case Answer of
+ {ok, R} when is_list(E) ->
+ {unsetify(R), sort(E)};
+ {ok, R} ->
+ {unsetify(R), E};
+ {error, _Module, Reason} ->
+ {element(1, Reason), E}
+ end,
+ if
+ Reply =:= Expected ->
+ ?format("As expected, got ~n~p~n", [Expected]),
+ {ok, NewState};
+ true ->
+ ?format("Expected ~n~p~nbut got ~n~p~n", [Expected, Reply]),
+ not_ok
+ end.
+
+analyze(Query, E, S) ->
+ ?format("------------------------------~n", []),
+ ?format("Evaluating ~p~n", [Query]),
+ ?line {{ok, L}, NewState} =
+ xref_base:analyze(S, Query, [{verbose, false}]),
+ case {unsetify(L), sort(E)} of
+ {X,X} ->
+ ?format("As was expected, got ~n~p~n", [X]),
+ {ok, NewState};
+ {_R,_X} ->
+ ?format("Expected ~n~p~nbut got ~n~p~n", [_X, _R]),
+ not_ok
+ end.
+
+unsetify(S) ->
+ case is_sofs_set(S) of
+ true -> to_external(S);
+ false -> S
+ end.
+
+%% Note: assumes S has been set up; the new state is not returned
+eval(Query, S) ->
+ ?line {{ok, Answer}, _NewState} =
+ xref_base:q(S, Query, [{verbose, false}]),
+ unsetify(Answer).
+
+add_module(S, XMod, DefAt, X, LCallAt, XCallAt, XC, LC) ->
+ Attr = {[], [], []},
+ Depr0 = {[], [], [], []},
+ DBad = [],
+ Depr = {Depr0,DBad},
+ Data = {DefAt, LCallAt, XCallAt, LC, XC, X, Attr, Depr},
+ Unres = [],
+ ?line {ok, _Module, _Bad, State} =
+ xref_base:do_add_module(S, XMod, Unres, Data),
+ State.
+
+add_application(S, XApp) ->
+ ?line xref_base:do_add_application(S, XApp).
+
+add_release(S, XRel) ->
+ ?line xref_base:do_add_release(S, XRel).
+
+remove_module(S, M) ->
+ ?line xref_base:do_remove_module(S, M).
+
+info_tag(Info, Tag) ->
+ {value, {_Tag, Value}} = lists:keysearch(Tag, 1, Info),
+ Value.
+
+make_ufile(FileName) ->
+ ?line ok = file:write_file(FileName, term_to_binary(foo)),
+ ?line hide_file(FileName).
+
+make_udir(Dir) ->
+ ?line ok = file:make_dir(Dir),
+ ?line hide_file(Dir).
+
+hide_file(FileName) ->
+ ?line {ok, FileInfo} = file:read_file_info(FileName),
+ ?line NewFileInfo = FileInfo#file_info{mode = 0},
+ ?line ok = file:write_file_info(FileName, NewFileInfo).
+
+%% Note that S has to be set up before calling this checking function.
+check_state(S) ->
+ ?line Info = xref:info(S),
+
+ ?line modules_mode_check(S, Info),
+ case info(Info, mode) of
+ modules ->
+ ok;
+ functions ->
+ functions_mode_check(S, Info)
+ end.
+
+%% The manual mentions some facts that should always hold.
+%% Here they are again.
+functions_mode_check(S, Info) ->
+ %% F = L + X,
+ ?line {ok, F} = xref:q(S, "F"),
+ ?line {ok, F} = xref:q(S, "L + X"),
+
+ %% V = X + L + B + U,
+ ?line {ok, V} = xref:q(S, "V"),
+ ?line {ok, V} = xref:q(S, "X + L + B + U"),
+
+ %% X, L, B and U are disjoint.
+ ?line {ok, []} =
+ xref:q(S, "X * L + X * B + X * U + L * B + L * U + B * U"),
+
+ %% V = UU + XU + LU,
+ ?line {ok, V} = xref:q(S, "UU + XU + LU"),
+
+ %% E = LC + XC
+ ?line {ok, E} = xref:q(S, "E"),
+ ?line {ok, E} = xref:q(S, "LC + XC"),
+
+ %% U subset of XU,
+ ?line {ok, []} = xref:q(S, "U - XU"),
+
+ %% LU = range LC
+ ?line {ok, []} = xref:q(S, "(LU - range LC) + (range LC - LU)"),
+
+ %% XU = range XC
+ ?line {ok, []} = xref:q(S, "(XU - range XC) + (range XC - XU)"),
+
+ %% LU subset F
+ ?line {ok, []} = xref:q(S, "LU - F"),
+
+ %% UU subset F
+ ?line {ok, []} = xref:q(S, "UU - F"),
+
+ %% ME = (Mod) E
+ ?line {ok, ME} = xref:q(S, "ME"),
+ ?line {ok, ME} = xref:q(S, "(Mod) E"),
+
+ %% AE = (App) E
+ ?line {ok, AE} = xref:q(S, "AE"),
+ ?line {ok, AE} = xref:q(S, "(App) E"),
+
+ %% RE = (Rel) E
+ ?line {ok, RE} = xref:q(S, "RE"),
+ ?line {ok, RE} = xref:q(S, "(Rel) E"),
+
+ %% (Mod) V subset of M
+ ?line {ok, []} = xref:q(S, "(Mod) V - M"),
+
+ %% range UC subset of U
+ ?line {ok, []} = xref:q(S, "range UC - U"),
+
+ %% Some checks on the numbers returned by the info functions.
+
+ ?line {Resolved, Unresolved} = info(Info, no_calls),
+ ?line AllCalls = Resolved + Unresolved,
+ ?line {ok, AllCalls} = xref:q(S, "# (XLin) E + # (LLin) E"),
+
+ ?line {Local, Exported} = info(Info, no_functions),
+ ?line LX = Local+Exported,
+ ?line {ok, LXs} = xref:q(S, 'Extra = _:module_info/"(0|1)" + LM,
+ # (F - Extra)'),
+ ?line true = LX =:= LXs,
+
+ ?line {LocalCalls, ExternalCalls, UnresCalls} =
+ info(Info, no_function_calls),
+ ?line LEU = LocalCalls + ExternalCalls + UnresCalls,
+ ?line {ok, LEU} = xref:q(S, "# LC + # XC"),
+
+ ?line InterFunctionCalls = info(Info, no_inter_function_calls),
+ ?line {ok, InterFunctionCalls} = xref:q(S, "# EE"),
+
+ %% And some more checks on counters...
+ ?line check_count(S),
+
+ %% ... and more
+ ?line {ok, []} = xref:q(S, "LM - X - U - B"),
+
+ ok.
+
+modules_mode_check(S, Info) ->
+ %% B subset of XU,
+ ?line {ok, []} = xref:q(S, "B - XU"),
+
+ %% M = AM + LM + UM
+ ?line {ok, M} = xref:q(S, "M"),
+ ?line {ok, M} = xref:q(S, "AM + LM + UM"),
+
+ %% DF is a subset of X U B, etc.
+ ?line {ok, []} = xref:q(S, "DF - X - B"),
+ ?line {ok, []} = xref:q(S, "DF_3 - DF"),
+ ?line {ok, []} = xref:q(S, "DF_2 - DF_3"),
+ ?line {ok, []} = xref:q(S, "DF_1 - DF_2"),
+
+ %% AM, LM and UM are disjoint.
+ ?line {ok, []} = xref:q(S, "AM * LM + AM * UM + LM * UM"),
+
+ %% (App) M subset of A
+ ?line {ok, []} = xref:q(S, "(App) M - A"),
+
+ ?line AM = info(Info, no_analyzed_modules),
+ ?line {ok, AM} = xref:q(S, "# AM"),
+
+ ?line A = info(Info, no_applications),
+ ?line {ok, A} = xref:q(S, "# A"),
+
+ ?line NoR = info(Info, no_releases),
+ ?line {ok, NoR} = xref:q(S, "# R"),
+
+ ok.
+
+%% Checks the counters of some of the overall and modules info functions.
+%% (Applications and releases are not checked.)
+check_count(S) ->
+ %%{ok, R} = xref:q(S, 'R'),
+ %% {ok, A} = xref:q(S, 'A'),
+ {ok, M} = xref:q(S, 'AM'),
+
+ {ok, _} = xref:q(S,
+ "Extra := _:module_info/\"(0|1)\" + LM"),
+
+ %% info/1:
+ {ok, NoR} = xref:q(S, '# R'),
+ {ok, NoA} = xref:q(S, '# A'),
+ {ok, NoM} = xref:q(S, '# AM'),
+ {ok, NoCalls} = xref:q(S, '# (XLin) E + # (LLin) E'),
+ {ok, NoFunCalls} = xref:q(S, '# E'),
+ {ok, NoXCalls} = xref:q(S, '# XC'),
+ {ok, NoLCalls} = xref:q(S, '# LC'),
+ {ok, NoLXCalls} = xref:q(S, '# (XC * LC)'),
+ NoAllCalls = NoXCalls + NoLCalls,
+ {ok, NoFun} = xref:q(S, '# (F - Extra)'),
+ {ok, NoICalls} = xref:q(S, '# EE'),
+
+ Info = xref:info(S),
+ NoR = info(Info, no_releases),
+ NoA = info(Info, no_applications),
+ NoM = info(Info, no_analyzed_modules),
+ {NoResolved, NoUC} = info(Info, no_calls),
+ NoCalls = NoResolved + NoUC,
+ {NoLocal, NoExternal, NoUnres} = info(Info, no_function_calls),
+ NoAllCalls = NoLocal + NoExternal + NoUnres,
+ NoAllCalls = NoFunCalls + NoLXCalls,
+ {NoLocalFuns, NoExportedFuns} = info(Info, no_functions),
+ NoFun = NoLocalFuns + NoExportedFuns,
+ NoICalls = info(Info, no_inter_function_calls),
+
+ %% per module
+ info_module(M, S),
+
+ ok.
+
+info_module([M | Ms], S) ->
+ {ok, NoCalls} = per_module("T = (E | ~p : Mod), # (XLin) T + # (LLin) T",
+ M, S),
+ {ok, NoFunCalls} = per_module("# (E | ~p : Mod)", M, S),
+ {ok, NoXCalls} = per_module("# (XC | ~p : Mod)", M, S),
+ {ok, NoLCalls} = per_module("# (LC | ~p : Mod)", M, S),
+ {ok, NoLXCalls} = per_module("# ((XC * LC) | ~p : Mod)", M, S),
+ NoAllCalls = NoXCalls + NoLCalls,
+ {ok, NoFun} = per_module("# (F * ~p : Mod - Extra)", M, S),
+ {ok, NoICalls} = per_module("# (EE | ~p : Mod)", M, S),
+
+ [{_M,Info}] = xref:info(S, modules, M),
+ {NoResolved, NoUC} = info(Info, no_calls),
+ NoCalls = NoResolved + NoUC,
+ {NoLocal, NoExternal, NoUnres} = info(Info, no_function_calls),
+ NoAllCalls = NoLocal + NoExternal + NoUnres,
+ NoAllCalls = NoFunCalls + NoLXCalls,
+ {NoLocalFuns, NoExportedFuns} = info(Info, no_functions),
+ NoFun = NoLocalFuns + NoExportedFuns,
+ NoICalls = info(Info, no_inter_function_calls),
+
+ info_module(Ms, S);
+info_module([], _S) ->
+ ok.
+
+per_module(Q, M, S) ->
+ xref:q(S, f(Q, [M])).
+
+info(Info, What) ->
+ {value, {What, Value}} = lists:keysearch(What, 1, Info),
+ Value.
+
+f(S, A) ->
+ flatten(io_lib:format(S, A)).
+
+fatom(R) ->
+ list_to_atom(flatten(xref:format_error(R))).
+
+start(Server) ->
+ ?line case xref:start(Server) of
+ {error, {already_started, _Pid}} ->
+ ?line xref:stop(Server),
+ ?line xref:start(Server);
+ R -> R
+ end.
+
+add_erts_code_path(KernelPath) ->
+ VersionDirs =
+ filelib:is_dir(
+ filename:join(
+ [code:lib_dir(),
+ lists:flatten(
+ ["kernel-",
+ [X ||
+ {kernel,_,X} <-
+ application_controller:which_applications()]])])),
+ case VersionDirs of
+ true ->
+ case code:lib_dir(erts) of
+ String when is_list(String) ->
+ [KernelPath, fname(String,"ebin")];
+ _Other1 ->
+ [KernelPath]
+ end;
+ false ->
+ % Clearcase?
+ PrelPath = filename:join([code:lib_dir(),"..","erts","preloaded"]),
+ case filelib:is_dir(PrelPath) of
+ true ->
+ [KernelPath, fname(PrelPath,"ebin")];
+ false ->
+ [KernelPath]
+ end
+ end.
+
+
diff --git a/lib/tools/test/xref_SUITE_data/depr_r9c.beam b/lib/tools/test/xref_SUITE_data/depr_r9c.beam
new file mode 100644
index 0000000000..82f0eef5a1
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/depr_r9c.beam
Binary files differ
diff --git a/lib/tools/test/xref_SUITE_data/dir/dir/dummy b/lib/tools/test/xref_SUITE_data/dir/dir/dummy
new file mode 100644
index 0000000000..7f62a93220
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/dir/dir/dummy
@@ -0,0 +1,2 @@
+This directory is not empty.
+Prevents winzip from removing the directory.
diff --git a/lib/tools/test/xref_SUITE_data/dir/jam/x.jam b/lib/tools/test/xref_SUITE_data/dir/jam/x.jam
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/dir/jam/x.jam
diff --git a/lib/tools/test/xref_SUITE_data/lib_test/cp.erl b/lib/tools/test/xref_SUITE_data/lib_test/cp.erl
new file mode 100644
index 0000000000..efe5d77854
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/lib_test/cp.erl
@@ -0,0 +1,6 @@
+-module(cp).
+
+-export([t/0]).
+
+t() ->
+ lists:sort(a).
diff --git a/lib/tools/test/xref_SUITE_data/lib_test/lib1.erl b/lib/tools/test/xref_SUITE_data/lib_test/lib1.erl
new file mode 100644
index 0000000000..7d50fcb1af
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/lib_test/lib1.erl
@@ -0,0 +1,6 @@
+-module(lib1).
+
+-export([f/0]).
+
+f() ->
+ true.
diff --git a/lib/tools/test/xref_SUITE_data/lib_test/lib2.erl b/lib/tools/test/xref_SUITE_data/lib_test/lib2.erl
new file mode 100644
index 0000000000..ca505dfd4f
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/lib_test/lib2.erl
@@ -0,0 +1,14 @@
+-module(lib2).
+
+-export([f/0, g/0]).
+
+-deprecated({f,0,next_major_release}).
+
+f() ->
+ local().
+
+g() ->
+ true.
+
+local() ->
+ true.
diff --git a/lib/tools/test/xref_SUITE_data/lib_test/lib3.erl b/lib/tools/test/xref_SUITE_data/lib_test/lib3.erl
new file mode 100644
index 0000000000..8a900f8040
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/lib_test/lib3.erl
@@ -0,0 +1,11 @@
+-module(lib3).
+
+-export([f/0, g/0]).
+
+-deprecated(module).
+
+f() ->
+ true.
+
+g() ->
+ true.
diff --git a/lib/tools/test/xref_SUITE_data/lib_test/t.erl b/lib/tools/test/xref_SUITE_data/lib_test/t.erl
new file mode 100644
index 0000000000..d2bd81110e
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/lib_test/t.erl
@@ -0,0 +1,14 @@
+-module(t).
+
+-export([t/0]).
+
+t() ->
+ %% lib1: only unknown functions used
+ %% lib2: one known used, one unknown function used, one local used
+ %% lib3: one known function used
+ lib1:unknown(),
+ lib2:f(), %% known, g/0 not used
+ lib2:unknown(),
+ lib2:local(),
+ lib3:f(),
+ unknown:unknown().
diff --git a/lib/tools/test/xref_SUITE_data/md/x__x.erl b/lib/tools/test/xref_SUITE_data/md/x__x.erl
new file mode 100644
index 0000000000..83234e1d3f
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/md/x__x.erl
@@ -0,0 +1,7 @@
+-module(x__x).
+
+-export([t/1]).
+
+t(A) ->
+ y__y:t(A),
+ y__y:t(A,A).
diff --git a/lib/tools/test/xref_SUITE_data/md/y__y.erl b/lib/tools/test/xref_SUITE_data/md/y__y.erl
new file mode 100644
index 0000000000..b2bb783fd8
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/md/y__y.erl
@@ -0,0 +1,12 @@
+-module(y__y).
+
+-export([t/1]).
+
+t(A) ->
+ x__x:t(A).
+
+l() ->
+ l1().
+
+l1() ->
+ l().
diff --git a/lib/tools/test/xref_SUITE_data/read/read.beam.v1 b/lib/tools/test/xref_SUITE_data/read/read.beam.v1
new file mode 100644
index 0000000000..3b8e9c4c38
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/read/read.beam.v1
Binary files differ
diff --git a/lib/tools/test/xref_SUITE_data/read/read.erl b/lib/tools/test/xref_SUITE_data/read/read.erl
new file mode 100644
index 0000000000..4a0cc280c3
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/read/read.erl
@@ -0,0 +1,175 @@
+-module(read).
+
+-export([lc/0, funfuns/0, bi/0]).
+
+-xref({xx,ff,22}).
+-xref({{all,0},{no,0}}).
+-xref([{{all,0},{i,0}},{{all,0},{x2,5}}]).
+-xref([apa]).
+-xref({all,0}).
+-xref([{{{all},0},{no,0}},{{all,0},{m,x2,5}}]).
+-xref([{{a,14},{q,f,17}}]).
+-xref({{i,f,17},{g,18}}).
+-xref({{j,f,17},{i,g,18}}).
+
+-xref({{funfuns,0},{'$F_EXPR',177}}).
+-xref({{funfuns,0},{?MODULE,'$F_EXPR',178}}).
+-xref({{funfuns,0},{modul,'$F_EXPR',179}}).
+
+lc() ->
+ Tab = ets:new(),
+ [Mt||{_M,Mt} <- ets:tab2list(Tab)].
+
+funfuns() ->
+ A = variable,
+
+ %% Spawn...
+
+ %% Recognized. POS1=28.
+ spawn(fun() -> mod17:fun17() end),
+ spawn(fun local/0),
+ spawn(fun binary_to_term/1), % builtin, not collected
+ spawn({dist,func}),
+ spawn({dist,A}), % {dist,'$F_EXPR',0}
+ spawn_link(fun() -> mod17:fun17() end),
+ spawn_link({dist,func}),
+ spawn_link({dist,A}), % {dist,'$F_EXPR',0}
+
+ %% POS2=POS1+10
+ spawn({dist,func}(arg1,arg2), {d,f}),
+ spawn({dist,func}(arg1,arg2), fun() -> mod42:func() end),
+ spawn_link({dist,func}(arg1,arg2), {d,f}),
+ spawn_link({dist,func}(arg1,arg2), fun() -> mod42:func() end),
+
+ %% POS3=POS2+6
+ spawn(dist, func, [arg1,arg2]), % spawn/3 is builtin
+ spawn(expr, A, [arg1]), % {expr,'$F_EXPR',1}
+ spawn_link(dist, func, [arg1,arg2]), % spawn_link/3 is builtin
+ spawn_link(expr, A, [arg1,arg2]), % {expr,'$F_EXPR',2}
+
+ %% POS4=POS3+6
+ spawn(node, modul, function, []),
+ spawn(node, modul, A, [a]), % {modul,'$F_EXPR',1}
+ spawn({dist,func}(arg1,arg2), spm, spf, [a,b]),
+ spawn({dist,func}(arg1,arg2), spm, A, [a]), % {spm,'$F_EXPR',1}
+ spawn_link({dist,func}(arg1,arg2), spm, spf, [a,b]),
+ spawn_link({dist,func}(arg1,arg2), spm, A, [a]), % {spm,'$F_EXPR',1}
+ spawn_opt(spm, spf, [arg3, arg4], [opt1, bi()]),
+ spawn_opt(spm, A, [a], [opt1, bi()]), % {spm,'$F_EXPR',1}
+
+ %% Not recognized or invalid. POS5=POS4+10
+ spawn(A), % {'$M_EXPR','$F_EXPR',0}
+ spawn(17), % {'$M_EXPR','$F_EXPR',0}
+ spawn_link(A), % {'$M_EXPR','$F_EXPR',0}
+
+ %% POS6=POS5+5
+ spawn({a,b},[1008]), % {'$M_EXPR','$F_EXPR',0}
+ spawn_link({a,b},[1008]), % {'$M_EXPR','$F_EXPR',0}
+
+ spawn(n, A, A), % {n,'$F_EXPR',-1}
+
+ %% POS7=POS6+6
+ spawn(n, A,f,[1007]), % {'$M_EXPR',f,1}, spawn/3 is builtin
+ spawn_opt(A,f,[1007],[]), % {'$M_EXPR',f,1}
+
+ %% Apply...
+
+ %% Recognized. POS8=POS7+6
+ {hej,san}(1002),
+ {hej,A}(1002), % {hej,'$F_EXPR',1}
+ t:A(1003), % {t,'$F_EXPR',1}
+ apply({a,b},[1005]),
+ apply({a,A},[1005]), % {a,'$F_EXPR',1}
+ apply(m,f,[100011]),
+ apply(m,A,[100011]), % {m,'$F_EXPR',1}
+ %% POS9=POS8+8
+ apply(A, f, [bi()]), % {'$M_EXPR',f,1}
+ {erlang,apply}({a,b},[8888]),
+ {erlang,apply}({a,A},[8888]), % {a,'$F_EXPR',1}
+ {erlang,apply}({erlang,apply},[{erlang,not_a_function},[7777]]),
+ apply(erlang, apply, [erlang, apply, [mod, func, [atom77,tjohej]]]),
+ erlang:apply(foo), % not an apply, but an unknown function
+ apply(fun(X) -> math:add3(X) end, [7]),
+ (fun(X) -> q:f(X) end)(3008),
+
+ %% Not recognized or invalid. POS10=POS9+10
+ A:foo(1000), % {'$M_EXPR',foo,1}
+ A(17), % {'$M_EXPR','$F_EXPR',1}
+ A(17,[one,two]), % {'$M_EXPR','$F_EXPR',2}
+ apply(apa,[1001]), % {'$M_EXPR','$F_EXPR',1}
+ {mod1:fun1(hej),san}(1017), % {'$M_EXPR',san,1}
+ A:A(1004), % {'$M_EXPR','$F_EXPR',1}
+ %% POS11=POS10+7
+ apply(A,A,[1006]), % {'$M_EXPR','$F_EXPR',1}
+ apply(A,A,[1009 | 10010]), % {'$M_EXPR','$F_EXPR',-1}
+ apply(m,f,[10000 | 9999]), % {m,f,-1}
+ apply(m,f,a), % {m,f,-1}
+ 3(a), % {'$M_EXPR','$F_EXPR',1}
+ apply(3,[a]), % {'$M_EXPR','$F_EXPR',1}
+
+ %% POS12=POS11+8
+ apply(A, A), % number of arguments is not known, {'$M_EXPR','$F_EXPR',-1}
+ Args0 = [list],
+ Args = [a | Args0], % number of arguments is known
+ apply(A, Args), % {'$M_EXPR','$F_EXPR',2}
+ apply(m3, f3, Args), %
+ NotArgs = [is_not, a | list], % number of arguments is not known
+ apply(A, NotArgs), % {'$M_EXPR','$F_EXPR',-1}
+ apply(m4, f4, NotArgs), % {m4,f4,-1}
+
+ %% OTP Internal. POS13=POS12+10
+ erts_debug:apply(dm, df, [17], foobar),
+ erts_debug:apply(debug, A, [], A), % {debug,'$F_EXPR',0}
+ erts_debug:apply(A, A, A, A). % {'$M_EXPR','$F_EXPR',-1}
+
+bi() when length([]) > 17 ->
+ foo:module_info(),
+ module_info(),
+ A = tjo,
+ t:foo(A),
+ case true of
+ true when integer(1) ->
+ X = foo;
+ false ->
+ X = flopp
+ end,
+ X == A;
+bi() ->
+ %% POS14=POS13+18
+ Z = fun(Y) -> Y end,
+ case true of
+ true when length([a,b]) > 4 ->
+ F = fun(X) -> X end,
+ F(3);
+ false ->
+ F = 17,
+ F(3) % {'$M_EXPR','$F_EXPR',1}
+ end,
+ Z(apa),
+ erlang:module_info();
+bi() ->
+ Bin11 = <<1, 17, 42>>,
+ Bin12 = <<"abc">>,
+ false = (Bin11 == Bin12),
+ A = 1, B = 17,
+ Bin3 = <<A, B, (bi()):16>>,
+ <<D:16, E, F/binary>> = Bin3,
+ X = 9, <<(X+1):8>>,
+ _Fyy = <<X:4/little-signed-integer-unit:8>>,
+ D + E + F.
+%bi() ->
+% %% POS15=POS14+13
+% try
+% foo:t(),
+% bar:t()
+% of
+% {v,1} ->
+% local();
+% {v,2} ->
+% foo:t()
+% catch
+% {'EXIT',_} -> bar:t()
+% end.
+
+local() ->
+ true.
diff --git a/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.0/ebin/dummy b/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.0/ebin/dummy
new file mode 100644
index 0000000000..7f62a93220
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.0/ebin/dummy
@@ -0,0 +1,2 @@
+This directory is not empty.
+Prevents winzip from removing the directory.
diff --git a/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.1/ebin/dummy b/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.1/ebin/dummy
new file mode 100644
index 0000000000..7f62a93220
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.1/ebin/dummy
@@ -0,0 +1,2 @@
+This directory is not empty.
+Prevents winzip from removing the directory.
diff --git a/lib/tools/test/xref_SUITE_data/rel2/lib/app2-1.1/ebin/dummy b/lib/tools/test/xref_SUITE_data/rel2/lib/app2-1.1/ebin/dummy
new file mode 100644
index 0000000000..7f62a93220
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/rel2/lib/app2-1.1/ebin/dummy
@@ -0,0 +1,2 @@
+This directory is not empty.
+Prevents winzip from removing the directory.
diff --git a/lib/tools/test/xref_SUITE_data/rel2/x.erl b/lib/tools/test/xref_SUITE_data/rel2/x.erl
new file mode 100644
index 0000000000..2125760776
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/rel2/x.erl
@@ -0,0 +1,16 @@
+-module(x).
+
+-export([t/0, xx/0]).
+-deprecated({t,0,eventually}).
+
+t() ->
+ true.
+
+xx() ->
+ x:undef().
+
+l() ->
+ l1().
+
+l1() ->
+ l().
diff --git a/lib/tools/test/xref_SUITE_data/rel2/y.erl b/lib/tools/test/xref_SUITE_data/rel2/y.erl
new file mode 100644
index 0000000000..2a6e65e78f
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/rel2/y.erl
@@ -0,0 +1,6 @@
+-module(y).
+
+-export([t/0]).
+
+t() ->
+ x:t().
diff --git a/lib/tools/test/xref_SUITE_data/update/x.erl.1 b/lib/tools/test/xref_SUITE_data/update/x.erl.1
new file mode 100644
index 0000000000..6af13329a2
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/update/x.erl.1
@@ -0,0 +1,6 @@
+-module(x).
+
+-export([t/0]).
+
+t() ->
+ erlang:atom_to_list(tjohoo).
diff --git a/lib/tools/test/xref_SUITE_data/update/x.erl.2 b/lib/tools/test/xref_SUITE_data/update/x.erl.2
new file mode 100644
index 0000000000..e303a758d2
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/update/x.erl.2
@@ -0,0 +1,6 @@
+-module(x).
+
+-export([t/0]).
+
+t() ->
+ erlang:list_to_atom("tjohoo").
diff --git a/lib/wx/api_gen/wx_gen.erl b/lib/wx/api_gen/wx_gen.erl
index 50dd2d6f51..780bb2e741 100644
--- a/lib/wx/api_gen/wx_gen.erl
+++ b/lib/wx/api_gen/wx_gen.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Api wrapper generator
@@ -699,10 +699,12 @@ parse_type2([N="wxArrayInt"|R],Info,Opts,T) ->
parse_type2(R,Info,Opts,T#type{name=N,base=int,single=array});
parse_type2([N="wxArrayDouble"|R],Info,Opts,T) ->
parse_type2(R,Info,Opts,T#type{name=N,base=double,single=array});
-parse_type2([N="wxTreeItemId"|R],Info,Opts,T) ->
- parse_type2(R,Info,Opts,T#type{name=N,base={ref,N}});
+parse_type2([N="wxTreeItemId"|R],Info,Opts,T) -> %% Use Pointer as Ids
+ parse_type2(R,Info,Opts,T#type{name=N,base=int64});
+parse_type2([N="wxTreeItemIdValue"|R],Info,Opts,T) -> %% Use Pointer as Ids
+ parse_type2(R,Info,Opts,T#type{name=N,base=int64});
parse_type2([N="wxArrayTreeItemIds"|R],Info,Opts,T) ->
- parse_type2(R,Info,Opts,T#type{name=N,base={ref,"wxTreeItemId"},single=array});
+ parse_type2(R,Info,Opts,T#type{name=N,base=int64,single=array});
parse_type2([N="wxTreeItemData"|R],Info,Opts,T) ->
parse_type2(R,Info,Opts,T#type{name="wxETreeItemData",base={term,N}});
parse_type2([N="wxClientData"|R],Info,Opts,T) ->
@@ -1082,6 +1084,7 @@ type_foot_print(#type{base=long}) -> int;
type_foot_print(#type{base=binary}) -> binary;
type_foot_print(#type{base={binary,_}}) -> binary;
type_foot_print(#type{base=int}) -> int;
+type_foot_print(#type{base=int64}) -> int;
type_foot_print(#type{base=bool}) -> bool;
%%type_foot_print(#type{base=datetime}) -> datetime;
type_foot_print(#type{base=float}) -> float;
diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl
index fd0bea04ae..423dcd0179 100644
--- a/lib/wx/api_gen/wx_gen_cpp.erl
+++ b/lib/wx/api_gen/wx_gen_cpp.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%%-------------------------------------------------------------------
@@ -309,6 +309,8 @@ declare_type(N,false,_,#type{name="wxArrayTreeItemIds",ref=reference}) ->
w(" wxArrayTreeItemIds ~s;~n", [N]);
declare_type(N,false,_,#type{name="wxDateTime"}) ->
w(" wxDateTime ~s;~n", [N]);
+declare_type(N,false,_,#type{name=Type, base=int64, ref=reference}) ->
+ w(" ~s ~s;~n", [Type,N]);
declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=true})
when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
w(" ~s ~s=~s;~n", [Type,N,Def]);
@@ -478,9 +480,13 @@ decode_arg(N,#type{base={comp,_,List},single=true,name=Type,ref=Ref},Arg,A0) ->
{double, _} -> 0
end;
-decode_arg(N,#type{name=Class,base={ref,"wxTreeItemId"},single=true},Arg,A0) ->
- A = align(A0,32),
- wa(" ~s ",[Class],"~s = wxTreeItemId(getPtr(bp,memenv)); bp += 4;~n",[N],Arg),
+decode_arg(N,#type{name=Class="wxTreeItemId",single=true},Arg,A0) ->
+ A = align(A0,64),
+ wa(" ~s ",[Class],"~s = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;~n",[N],Arg),
+ A;
+decode_arg(N,#type{name=Class="wxTreeItemIdValue",single=true},Arg,A0) ->
+ A = align(A0,64),
+ wa(" ~s ",[Class],"~s = (~s) * (wxUint64 *) bp; bp += 8;~n",[N,Class],Arg),
A;
decode_arg(N,#type{name="wxChar", single=S},Arg,A0)
when S =/= true ->
@@ -851,8 +857,10 @@ build_ret_types(Type,Ps) ->
build_ret(Name,_,#type{base={class,Class},single=true}) ->
w(" rt.addRef(getRef((void *)~s,memenv), \"~s\");~n",[Name,Class]);
-build_ret(Name,_,#type{base={ref,"wxTreeItemId"=Class},single=true}) ->
- w(" rt.addRef(getRef((void *)~s.m_pItem,memenv), \"~s\");~n",[Name,Class]);
+build_ret(Name,_,#type{name="wxTreeItemId",single=true}) ->
+ w(" rt.add((wxUIntPtr *) ~s.m_pItem);~n",[Name]);
+build_ret(Name,_,#type{name="wxTreeItemIdValue",single=true}) ->
+ w(" rt.add((wxUIntPtr *) ~s);~n",[Name]);
build_ret(Name,_,#type{base={term,_},single=true}) ->
w(" rt.addExt2Term(~s);~n", [Name]);
build_ret(Name,_,#type{base={binary,Size},single=true}) ->
@@ -897,7 +905,7 @@ build_ret(Name,_,#type{name=List,single=list,base={class,Class}}) ->
build_ret(Name,_,#type{name="wxArrayTreeItemIds"}) ->
w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
- w(" rt.addRef(getRef((void *)~s[i].m_pItem,memenv), \"wxTreeItemId\");}~n",[Name]),
+ w(" rt.add((wxUIntPtr *)~s[i].m_pItem);}~n",[Name]),
w(" rt.endList(~s.GetCount());~n",[Name]);
build_ret(Name,_,#type{base=float,single=true}) ->
diff --git a/lib/wx/api_gen/wx_gen_erl.erl b/lib/wx/api_gen/wx_gen_erl.erl
index 64c11baec1..c31d7d2a92 100644
--- a/lib/wx/api_gen/wx_gen_erl.erl
+++ b/lib/wx/api_gen/wx_gen_erl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%%-------------------------------------------------------------------
@@ -575,6 +575,8 @@ guard_test(#param{name=Name,type=#type{single=Single}})
"is_list(" ++ erl_arg_name(Name) ++ ")";
guard_test(#param{name=N,type=#type{base=int}}) ->
"is_integer(" ++ erl_arg_name(N) ++ ")";
+guard_test(#param{name=N,type=#type{base=int64}}) ->
+ "is_integer(" ++ erl_arg_name(N) ++ ")";
guard_test(#param{name=N,type=#type{base=long}}) ->
"is_integer(" ++ erl_arg_name(N) ++ ")";
guard_test(#param{name=N,type=#type{base=float}}) ->
@@ -603,6 +605,7 @@ guard_test(#param{name=N,type=#type{base={comp,"wxColour",_Tup}}}) ->
"tuple_size(" ++ erl_arg_name(N) ++ ") =:= 3; tuple_size(" ++ erl_arg_name(N) ++ ") =:= 4";
guard_test(#param{name=N,type=#type{base={comp,_,Tup}}}) ->
Doc = fun({int,V}) -> "is_integer("++erl_arg_name(N)++V ++")";
+ ({int64,V}) -> "is_integer("++erl_arg_name(N)++V ++")";
({double,V}) -> "is_number("++erl_arg_name(N)++V ++")"
end,
args(Doc, ",", Tup);
@@ -768,7 +771,9 @@ doc_arg_type3(#type{name="wxArrayString"}) -> "[string()]";
doc_arg_type3(#type{name="wxDateTime"}) -> "wx:datetime()";
doc_arg_type3(#type{name="wxArtClient"}) -> "string()";
doc_arg_type3(#type{base=int}) -> "integer()";
+doc_arg_type3(#type{base=int64}) -> "integer()";
doc_arg_type3(#type{base=long}) -> "integer()";
+doc_arg_type3(#type{name="wxTreeItemId"}) -> "wxTreeCtrl:treeItemId()";
doc_arg_type3(#type{base=bool}) -> "bool()";
doc_arg_type3(#type{base=float}) -> "float()";
doc_arg_type3(#type{base=double}) -> "float()";
@@ -851,7 +856,7 @@ doc_enum_desc([{Enum,Vs}|R]) ->
doc_enum_desc(R).
%% Misc functions prefixed with wx
-erl_func_name("wx" ++ Name, undefined) -> check_name(lowercase(Name));
+erl_func_name("wx" ++ Name, undefined) -> check_name(lowercase(Name));
erl_func_name(Name, undefined) -> check_name(lowercase(Name));
erl_func_name(_, Alias) -> check_name(lowercase(Alias)).
@@ -926,6 +931,8 @@ marshal_arg(#type{single=true,base=float}, Name, Align) ->
align(32, Align, Name ++ ":32/?F");
marshal_arg(#type{single=true,base=double}, Name, Align) ->
align(64, Align, Name ++ ":64/?F");
+marshal_arg(#type{single=true,base=int64}, Name, Align) ->
+ align(64, Align, Name ++ ":64/?UI");
marshal_arg(#type{single=true,base=int}, Name, Align) ->
align(32, Align, Name ++ ":32/?UI");
marshal_arg(#type{single=true,base={enum,_Enum}}, Name, Align) ->
diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf
index 4a646650ea..4bb358ebc9 100644
--- a/lib/wx/api_gen/wxapi.conf
+++ b/lib/wx/api_gen/wxapi.conf
@@ -1,20 +1,20 @@
%% -*- erlang -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%
%% Api defs file, defines the classes and members we want.
@@ -889,7 +889,12 @@
{enum, wxTreeItemIcon, "wxTreeItemIcon_"}.
-{class, wxTreeCtrl, wxControl, [],
+{class, wxTreeCtrl, wxControl,
+ [{doc,
+ "Note: The representation of treeItemId() have changed "
+ "from the original class implementation to be an semi-opaque type,"
+ "Equality between TreeItemId's can be tested and zero means that the TreeItem is invalid."
+ }],
['wxTreeCtrl','~wxTreeCtrl','AddRoot','AppendItem',
%% Not on Windows 'AssignButtonsImageList','GetButtonsImageList','SetButtonsImageList'
'AssignImageList','AssignStateImageList','Collapse','CollapseAndReset',
@@ -897,10 +902,10 @@
%'EndEditLabel',
'EnsureVisible','Expand','GetBoundingRect',
'GetChildrenCount','GetCount','GetEditControl',
- %'GetFirstChild',
+ {'GetFirstChild',[{"cookie", out}]}, {'GetNextChild',[{"cookie", [both]}]},
'GetFirstVisibleItem',{'GetImageList',0},'GetIndent',
'GetItemBackgroundColour','GetItemData','GetItemFont','GetItemImage',
- 'GetItemText','GetItemTextColour','GetLastChild', % 'GetNextChild',
+ 'GetItemText','GetItemTextColour','GetLastChild',
'GetNextSibling','GetNextVisible','GetItemParent',%'GetParent',
'GetPrevSibling','GetPrevVisible','GetRootItem',
'GetSelection',{'GetSelections', [{return, nowhere},{"val",out}]},
diff --git a/lib/wx/c_src/gen/gl_fdefs.h b/lib/wx/c_src/gen/gl_fdefs.h
index 5fcd2d8e9b..f8851ddb83 100644
--- a/lib/wx/c_src/gen/gl_fdefs.h
+++ b/lib/wx/c_src/gen/gl_fdefs.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/***** This file is generated do not edit ****/
diff --git a/lib/wx/c_src/gen/gl_finit.h b/lib/wx/c_src/gen/gl_finit.h
index dac74ca7b6..a22192d06a 100644
--- a/lib/wx/c_src/gen/gl_finit.h
+++ b/lib/wx/c_src/gen/gl_finit.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/***** This file is generated do not edit ****/
diff --git a/lib/wx/c_src/gen/gl_funcs.cpp b/lib/wx/c_src/gen/gl_funcs.cpp
index 784731f02c..41a5524891 100644
--- a/lib/wx/c_src/gen/gl_funcs.cpp
+++ b/lib/wx/c_src/gen/gl_funcs.cpp
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/***** This file is generated do not edit ****/
diff --git a/lib/wx/c_src/gen/glu_finit.h b/lib/wx/c_src/gen/glu_finit.h
index 7135c53243..2f0e2d15e4 100644
--- a/lib/wx/c_src/gen/glu_finit.h
+++ b/lib/wx/c_src/gen/glu_finit.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/***** This file is generated do not edit ****/
diff --git a/lib/wx/c_src/gen/wxe_derived_dest.h b/lib/wx/c_src/gen/wxe_derived_dest.h
index ec56df7d4e..b8ff8519f1 100644
--- a/lib/wx/c_src/gen/wxe_derived_dest.h
+++ b/lib/wx/c_src/gen/wxe_derived_dest.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp
index f15754a072..de55f9d8da 100644
--- a/lib/wx/c_src/gen/wxe_events.cpp
+++ b/lib/wx/c_src/gen/wxe_events.cpp
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -740,8 +740,8 @@ case 208: {// wxTreeEvent
evClass = (char*)"wxTreeEvent";
rt.addAtom((char*)"wxTree");
rt.addAtom(Etype->eName);
- rt.addRef(getRef((void *)ev->GetItem().m_pItem,memenv), "wxTreeItemId");
- rt.addRef(getRef((void *)ev->GetOldItem().m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) ev->GetItem().m_pItem);
+ rt.add((wxUIntPtr *) ev->GetOldItem().m_pItem);
rt.add(ev->GetPoint());
rt.addTupleCount(5);
break;
diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp
index ccbacce9b9..532fee24b2 100644
--- a/lib/wx/c_src/gen/wxe_funcs.cpp
+++ b/lib/wx/c_src/gen/wxe_funcs.cpp
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -14763,7 +14763,7 @@ case wxGenericDirCtrl_GetRootId: { // wxGenericDirCtrl::GetRootId
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetRootId();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxGenericDirCtrl_GetTreeCtrl: { // wxGenericDirCtrl::GetTreeCtrl
@@ -18376,7 +18376,7 @@ case wxTreeCtrl_AddRoot: { // wxTreeCtrl::AddRoot
}};
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->AddRoot(text,image,selectedImage,data);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_AppendItem: { // wxTreeCtrl::AppendItem
@@ -18384,7 +18384,8 @@ case wxTreeCtrl_AppendItem: { // wxTreeCtrl::AppendItem
int selectedImage=-1;
wxETreeItemData * data= NULL;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId parent = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId parent = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
@@ -18402,7 +18403,7 @@ case wxTreeCtrl_AppendItem: { // wxTreeCtrl::AppendItem
}};
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->AppendItem(parent,text,image,selectedImage,data);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_AssignImageList: { // wxTreeCtrl::AssignImageList
@@ -18421,14 +18422,16 @@ case wxTreeCtrl_AssignStateImageList: { // wxTreeCtrl::AssignStateImageList
}
case wxTreeCtrl_Collapse: { // wxTreeCtrl::Collapse
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->Collapse(item);
break;
}
case wxTreeCtrl_CollapseAndReset: { // wxTreeCtrl::CollapseAndReset
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->CollapseAndReset(item);
break;
@@ -18471,7 +18474,8 @@ validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
}
case wxTreeCtrl_Delete: { // wxTreeCtrl::Delete
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->Delete(item);
break;
@@ -18484,21 +18488,24 @@ case wxTreeCtrl_DeleteAllItems: { // wxTreeCtrl::DeleteAllItems
}
case wxTreeCtrl_DeleteChildren: { // wxTreeCtrl::DeleteChildren
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->DeleteChildren(item);
break;
}
case wxTreeCtrl_EnsureVisible: { // wxTreeCtrl::EnsureVisible
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->EnsureVisible(item);
break;
}
case wxTreeCtrl_Expand: { // wxTreeCtrl::Expand
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->Expand(item);
break;
@@ -18506,7 +18513,8 @@ case wxTreeCtrl_Expand: { // wxTreeCtrl::Expand
case wxTreeCtrl_GetBoundingRect: { // wxTreeCtrl::GetBoundingRect
bool textOnly=false;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
int * rectW = (int *) bp; bp += 4;
@@ -18525,7 +18533,8 @@ case wxTreeCtrl_GetBoundingRect: { // wxTreeCtrl::GetBoundingRect
case wxTreeCtrl_GetChildrenCount: { // wxTreeCtrl::GetChildrenCount
bool recursively=true;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
recursively = *(bool *) bp; bp += 4;
@@ -18550,11 +18559,35 @@ case wxTreeCtrl_GetEditControl: { // wxTreeCtrl::GetEditControl
rt.addRef(getRef((void *)Result,memenv), "wxTextCtrl");
break;
}
+case wxTreeCtrl_GetFirstChild: { // wxTreeCtrl::GetFirstChild
+ wxTreeItemIdValue cookie;
+ wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ if(!This) throw wxe_badarg(0);
+ wxTreeItemId Result = This->GetFirstChild(item,cookie);
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ rt.add((wxUIntPtr *) cookie);
+ rt.addTupleCount(2);
+ break;
+}
+case wxTreeCtrl_GetNextChild: { // wxTreeCtrl::GetNextChild
+ wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ wxTreeItemIdValue cookie = (wxTreeItemIdValue) * (wxUint64 *) bp; bp += 8;
+ if(!This) throw wxe_badarg(0);
+ wxTreeItemId Result = This->GetNextChild(item,cookie);
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ rt.add((wxUIntPtr *) cookie);
+ rt.addTupleCount(2);
+ break;
+}
case wxTreeCtrl_GetFirstVisibleItem: { // wxTreeCtrl::GetFirstVisibleItem
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetFirstVisibleItem();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_GetImageList: { // wxTreeCtrl::GetImageList
@@ -18573,7 +18606,8 @@ case wxTreeCtrl_GetIndent: { // wxTreeCtrl::GetIndent
}
case wxTreeCtrl_GetItemBackgroundColour: { // wxTreeCtrl::GetItemBackgroundColour
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetItemBackgroundColour(item);
rt.add(Result);
@@ -18581,7 +18615,8 @@ case wxTreeCtrl_GetItemBackgroundColour: { // wxTreeCtrl::GetItemBackgroundColou
}
case wxTreeCtrl_GetItemData: { // wxTreeCtrl::GetItemData
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxETreeItemData * Result = (wxETreeItemData*)This->GetItemData(item);
rt.addExt2Term(Result);
@@ -18589,7 +18624,8 @@ case wxTreeCtrl_GetItemData: { // wxTreeCtrl::GetItemData
}
case wxTreeCtrl_GetItemFont: { // wxTreeCtrl::GetItemFont
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetItemFont(item)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
@@ -18597,7 +18633,8 @@ case wxTreeCtrl_GetItemFont: { // wxTreeCtrl::GetItemFont
}
case wxTreeCtrl_GetItemImage_1: { // wxTreeCtrl::GetItemImage
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
int Result = This->GetItemImage(item);
rt.addInt(Result);
@@ -18606,7 +18643,8 @@ case wxTreeCtrl_GetItemImage_1: { // wxTreeCtrl::GetItemImage
case wxTreeCtrl_GetItemImage_2: { // wxTreeCtrl::GetItemImage
wxTreeItemIcon which=wxTreeItemIcon_Normal;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
which = *(wxTreeItemIcon *) bp; bp += 4;;
@@ -18619,7 +18657,8 @@ which = *(wxTreeItemIcon *) bp; bp += 4;;
}
case wxTreeCtrl_GetItemText: { // wxTreeCtrl::GetItemText
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetItemText(item);
rt.add(Result);
@@ -18627,7 +18666,8 @@ case wxTreeCtrl_GetItemText: { // wxTreeCtrl::GetItemText
}
case wxTreeCtrl_GetItemTextColour: { // wxTreeCtrl::GetItemTextColour
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetItemTextColour(item);
rt.add(Result);
@@ -18635,64 +18675,70 @@ case wxTreeCtrl_GetItemTextColour: { // wxTreeCtrl::GetItemTextColour
}
case wxTreeCtrl_GetLastChild: { // wxTreeCtrl::GetLastChild
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetLastChild(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_GetNextSibling: { // wxTreeCtrl::GetNextSibling
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetNextSibling(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_GetNextVisible: { // wxTreeCtrl::GetNextVisible
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetNextVisible(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_GetItemParent: { // wxTreeCtrl::GetItemParent
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetItemParent(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_GetPrevSibling: { // wxTreeCtrl::GetPrevSibling
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetPrevSibling(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_GetPrevVisible: { // wxTreeCtrl::GetPrevVisible
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetPrevVisible(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_GetRootItem: { // wxTreeCtrl::GetRootItem
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetRootItem();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_GetSelection: { // wxTreeCtrl::GetSelection
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetSelection();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_GetSelections: { // wxTreeCtrl::GetSelections
@@ -18702,7 +18748,7 @@ case wxTreeCtrl_GetSelections: { // wxTreeCtrl::GetSelections
size_t Result = This->GetSelections(val);
rt.addInt(Result);
for(unsigned int i=0; i < val.GetCount(); i++) {
- rt.addRef(getRef((void *)val[i].m_pItem,memenv), "wxTreeItemId");}
+ rt.add((wxUIntPtr *)val[i].m_pItem);}
rt.endList(val.GetCount());
rt.addTupleCount(2);
break;
@@ -18721,42 +18767,16 @@ case wxTreeCtrl_HitTest: { // wxTreeCtrl::HitTest
wxPoint point = wxPoint(*pointX,*pointY);
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->HitTest(point);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
-}
-case wxTreeCtrl_InsertItem_4_1: { // wxTreeCtrl::InsertItem
- int image=-1;
- int selectedImage=-1;
- wxETreeItemData * data= NULL;
- wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId parent = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- wxTreeItemId idPrevious = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- int * textLen = (int *) bp; bp += 4;
- wxString text = wxString(bp, wxConvUTF8);
- bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
- case 1: {bp += 4;
- image = (int)*(int *) bp; bp += 4;
- } break;
- case 2: {bp += 4;
- selectedImage = (int)*(int *) bp; bp += 4;
- } break;
- case 3: {bp += 4;
- data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
- bp += 4; /* Align */
- } break;
- }};
- if(!This) throw wxe_badarg(0);
- wxTreeItemId Result = This->InsertItem(parent,idPrevious,text,image,selectedImage,data);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
-case wxTreeCtrl_InsertItem_4_0: { // wxTreeCtrl::InsertItem
+case wxTreeCtrl_InsertItem: { // wxTreeCtrl::InsertItem
int image=-1;
int selImage=-1;
wxETreeItemData * data= NULL;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId parent = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId parent = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * pos = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
@@ -18775,12 +18795,13 @@ case wxTreeCtrl_InsertItem_4_0: { // wxTreeCtrl::InsertItem
}};
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->InsertItem(parent,(size_t) *pos,text,image,selImage,data);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_IsBold: { // wxTreeCtrl::IsBold
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
bool Result = This->IsBold(item);
rt.addBool(Result);
@@ -18788,7 +18809,8 @@ case wxTreeCtrl_IsBold: { // wxTreeCtrl::IsBold
}
case wxTreeCtrl_IsExpanded: { // wxTreeCtrl::IsExpanded
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
bool Result = This->IsExpanded(item);
rt.addBool(Result);
@@ -18796,7 +18818,8 @@ case wxTreeCtrl_IsExpanded: { // wxTreeCtrl::IsExpanded
}
case wxTreeCtrl_IsSelected: { // wxTreeCtrl::IsSelected
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSelected(item);
rt.addBool(Result);
@@ -18804,7 +18827,8 @@ case wxTreeCtrl_IsSelected: { // wxTreeCtrl::IsSelected
}
case wxTreeCtrl_IsVisible: { // wxTreeCtrl::IsVisible
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
bool Result = This->IsVisible(item);
rt.addBool(Result);
@@ -18812,7 +18836,8 @@ case wxTreeCtrl_IsVisible: { // wxTreeCtrl::IsVisible
}
case wxTreeCtrl_ItemHasChildren: { // wxTreeCtrl::ItemHasChildren
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
bool Result = This->ItemHasChildren(item);
rt.addBool(Result);
@@ -18823,7 +18848,8 @@ case wxTreeCtrl_PrependItem: { // wxTreeCtrl::PrependItem
int selectedImage=-1;
wxETreeItemData * data= NULL;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId parent = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId parent = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
@@ -18841,19 +18867,21 @@ case wxTreeCtrl_PrependItem: { // wxTreeCtrl::PrependItem
}};
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->PrependItem(parent,text,image,selectedImage,data);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeCtrl_ScrollTo: { // wxTreeCtrl::ScrollTo
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->ScrollTo(item);
break;
}
case wxTreeCtrl_SelectItem_1: { // wxTreeCtrl::SelectItem
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->SelectItem(item);
break;
@@ -18861,7 +18889,8 @@ case wxTreeCtrl_SelectItem_1: { // wxTreeCtrl::SelectItem
case wxTreeCtrl_SelectItem_2: { // wxTreeCtrl::SelectItem
bool select=true;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
select = *(bool *) bp; bp += 4;
@@ -18887,7 +18916,8 @@ case wxTreeCtrl_SetImageList: { // wxTreeCtrl::SetImageList
}
case wxTreeCtrl_SetItemBackgroundColour: { // wxTreeCtrl::SetItemBackgroundColour
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
int * colB = (int *) bp; bp += 4;
@@ -18900,7 +18930,8 @@ case wxTreeCtrl_SetItemBackgroundColour: { // wxTreeCtrl::SetItemBackgroundColou
case wxTreeCtrl_SetItemBold: { // wxTreeCtrl::SetItemBold
bool bold=true;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bold = *(bool *) bp; bp += 4;
@@ -18912,7 +18943,8 @@ case wxTreeCtrl_SetItemBold: { // wxTreeCtrl::SetItemBold
}
case wxTreeCtrl_SetItemData: { // wxTreeCtrl::SetItemData
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
wxETreeItemData * data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
if(!This) throw wxe_badarg(0);
This->SetItemData(item,data);
@@ -18921,7 +18953,8 @@ case wxTreeCtrl_SetItemData: { // wxTreeCtrl::SetItemData
case wxTreeCtrl_SetItemDropHighlight: { // wxTreeCtrl::SetItemDropHighlight
bool highlight=true;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
highlight = *(bool *) bp; bp += 4;
@@ -18933,7 +18966,8 @@ case wxTreeCtrl_SetItemDropHighlight: { // wxTreeCtrl::SetItemDropHighlight
}
case wxTreeCtrl_SetItemFont: { // wxTreeCtrl::SetItemFont
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetItemFont(item,*font);
@@ -18942,7 +18976,8 @@ case wxTreeCtrl_SetItemFont: { // wxTreeCtrl::SetItemFont
case wxTreeCtrl_SetItemHasChildren: { // wxTreeCtrl::SetItemHasChildren
bool has=true;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
has = *(bool *) bp; bp += 4;
@@ -18954,7 +18989,8 @@ case wxTreeCtrl_SetItemHasChildren: { // wxTreeCtrl::SetItemHasChildren
}
case wxTreeCtrl_SetItemImage_2: { // wxTreeCtrl::SetItemImage
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * image = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetItemImage(item,(int) *image);
@@ -18963,7 +18999,8 @@ case wxTreeCtrl_SetItemImage_2: { // wxTreeCtrl::SetItemImage
case wxTreeCtrl_SetItemImage_3: { // wxTreeCtrl::SetItemImage
wxTreeItemIcon which=wxTreeItemIcon_Normal;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * image = (int *) bp; bp += 4;
bp += 4; /* Align */
while( * (int*) bp) { switch (* (int*) bp) {
@@ -18977,7 +19014,8 @@ which = *(wxTreeItemIcon *) bp; bp += 4;;
}
case wxTreeCtrl_SetItemText: { // wxTreeCtrl::SetItemText
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
@@ -18987,7 +19025,8 @@ case wxTreeCtrl_SetItemText: { // wxTreeCtrl::SetItemText
}
case wxTreeCtrl_SetItemTextColour: { // wxTreeCtrl::SetItemTextColour
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
int * colB = (int *) bp; bp += 4;
@@ -19013,21 +19052,24 @@ case wxTreeCtrl_SetWindowStyle: { // wxTreeCtrl::SetWindowStyle
}
case wxTreeCtrl_SortChildren: { // wxTreeCtrl::SortChildren
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->SortChildren(item);
break;
}
case wxTreeCtrl_Toggle: { // wxTreeCtrl::Toggle
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->Toggle(item);
break;
}
case wxTreeCtrl_ToggleItemSelection: { // wxTreeCtrl::ToggleItemSelection
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->ToggleItemSelection(item);
break;
@@ -19046,7 +19088,8 @@ case wxTreeCtrl_UnselectAll: { // wxTreeCtrl::UnselectAll
}
case wxTreeCtrl_UnselectItem: { // wxTreeCtrl::UnselectItem
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->UnselectItem(item);
break;
@@ -30146,7 +30189,7 @@ case wxTreeEvent_GetItem: { // wxTreeEvent::GetItem
wxTreeEvent *This = (wxTreeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetItem();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeEvent_GetKeyEvent: { // wxTreeEvent::GetKeyEvent
@@ -30167,7 +30210,7 @@ case wxTreeEvent_GetOldItem: { // wxTreeEvent::GetOldItem
wxTreeEvent *This = (wxTreeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetOldItem();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) Result.m_pItem);
break;
}
case wxTreeEvent_GetPoint: { // wxTreeEvent::GetPoint
diff --git a/lib/wx/c_src/gen/wxe_init.cpp b/lib/wx/c_src/gen/wxe_init.cpp
index c69f853203..96c775c4c0 100644
--- a/lib/wx/c_src/gen/wxe_init.cpp
+++ b/lib/wx/c_src/gen/wxe_init.cpp
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/* This file is also generated */
diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h
index 5e4b4deb9c..74d82a54f3 100644
--- a/lib/wx/c_src/gen/wxe_macros.h
+++ b/lib/wx/c_src/gen/wxe_macros.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
#include <wx/caret.h>
@@ -1882,1437 +1882,1438 @@
#define wxTreeCtrl_GetChildrenCount 2015
#define wxTreeCtrl_GetCount 2016
#define wxTreeCtrl_GetEditControl 2017
-#define wxTreeCtrl_GetFirstVisibleItem 2018
-#define wxTreeCtrl_GetImageList 2019
-#define wxTreeCtrl_GetIndent 2020
-#define wxTreeCtrl_GetItemBackgroundColour 2021
-#define wxTreeCtrl_GetItemData 2022
-#define wxTreeCtrl_GetItemFont 2023
-#define wxTreeCtrl_GetItemImage_1 2024
-#define wxTreeCtrl_GetItemImage_2 2025
-#define wxTreeCtrl_GetItemText 2026
-#define wxTreeCtrl_GetItemTextColour 2027
-#define wxTreeCtrl_GetLastChild 2028
-#define wxTreeCtrl_GetNextSibling 2029
-#define wxTreeCtrl_GetNextVisible 2030
-#define wxTreeCtrl_GetItemParent 2031
-#define wxTreeCtrl_GetPrevSibling 2032
-#define wxTreeCtrl_GetPrevVisible 2033
-#define wxTreeCtrl_GetRootItem 2034
-#define wxTreeCtrl_GetSelection 2035
-#define wxTreeCtrl_GetSelections 2036
-#define wxTreeCtrl_GetStateImageList 2037
-#define wxTreeCtrl_HitTest 2038
-#define wxTreeCtrl_InsertItem_4_1 2039
-#define wxTreeCtrl_InsertItem_4_0 2040
-#define wxTreeCtrl_IsBold 2041
-#define wxTreeCtrl_IsExpanded 2042
-#define wxTreeCtrl_IsSelected 2043
-#define wxTreeCtrl_IsVisible 2044
-#define wxTreeCtrl_ItemHasChildren 2045
-#define wxTreeCtrl_PrependItem 2046
-#define wxTreeCtrl_ScrollTo 2047
-#define wxTreeCtrl_SelectItem_1 2048
-#define wxTreeCtrl_SelectItem_2 2049
-#define wxTreeCtrl_SetIndent 2050
-#define wxTreeCtrl_SetImageList 2051
-#define wxTreeCtrl_SetItemBackgroundColour 2052
-#define wxTreeCtrl_SetItemBold 2053
-#define wxTreeCtrl_SetItemData 2054
-#define wxTreeCtrl_SetItemDropHighlight 2055
-#define wxTreeCtrl_SetItemFont 2056
-#define wxTreeCtrl_SetItemHasChildren 2057
-#define wxTreeCtrl_SetItemImage_2 2058
-#define wxTreeCtrl_SetItemImage_3 2059
-#define wxTreeCtrl_SetItemText 2060
-#define wxTreeCtrl_SetItemTextColour 2061
-#define wxTreeCtrl_SetStateImageList 2062
-#define wxTreeCtrl_SetWindowStyle 2063
-#define wxTreeCtrl_SortChildren 2064
-#define wxTreeCtrl_Toggle 2065
-#define wxTreeCtrl_ToggleItemSelection 2066
-#define wxTreeCtrl_Unselect 2067
-#define wxTreeCtrl_UnselectAll 2068
-#define wxTreeCtrl_UnselectItem 2069
-#define wxScrollBar_new_0 2070
-#define wxScrollBar_new_3 2071
-#define wxScrollBar_destruct 2072
-#define wxScrollBar_Create 2073
-#define wxScrollBar_GetRange 2074
-#define wxScrollBar_GetPageSize 2075
-#define wxScrollBar_GetThumbPosition 2076
-#define wxScrollBar_GetThumbSize 2077
-#define wxScrollBar_SetThumbPosition 2078
-#define wxScrollBar_SetScrollbar 2079
-#define wxSpinButton_new_2 2081
-#define wxSpinButton_new_0 2082
-#define wxSpinButton_Create 2083
-#define wxSpinButton_GetMax 2084
-#define wxSpinButton_GetMin 2085
-#define wxSpinButton_GetValue 2086
-#define wxSpinButton_SetRange 2087
-#define wxSpinButton_SetValue 2088
-#define wxSpinButton_destroy 2089
-#define wxSpinCtrl_new_0 2090
-#define wxSpinCtrl_new_2 2091
-#define wxSpinCtrl_Create 2093
-#define wxSpinCtrl_SetValue_1_1 2096
-#define wxSpinCtrl_SetValue_1_0 2097
-#define wxSpinCtrl_GetValue 2099
-#define wxSpinCtrl_SetRange 2101
-#define wxSpinCtrl_SetSelection 2102
-#define wxSpinCtrl_GetMin 2104
-#define wxSpinCtrl_GetMax 2106
-#define wxSpinCtrl_destroy 2107
-#define wxStaticText_new_0 2108
-#define wxStaticText_new_4 2109
-#define wxStaticText_Create 2110
-#define wxStaticText_GetLabel 2111
-#define wxStaticText_SetLabel 2112
-#define wxStaticText_Wrap 2113
-#define wxStaticText_destroy 2114
-#define wxStaticBitmap_new_0 2115
-#define wxStaticBitmap_new_4 2116
-#define wxStaticBitmap_Create 2117
-#define wxStaticBitmap_GetBitmap 2118
-#define wxStaticBitmap_SetBitmap 2119
-#define wxStaticBitmap_destroy 2120
-#define wxRadioBox_new 2121
-#define wxRadioBox_destruct 2123
-#define wxRadioBox_Create 2124
-#define wxRadioBox_Enable_2 2125
-#define wxRadioBox_Enable_1 2126
-#define wxRadioBox_GetSelection 2127
-#define wxRadioBox_GetString 2128
-#define wxRadioBox_SetSelection 2129
-#define wxRadioBox_Show_2 2130
-#define wxRadioBox_Show_1 2131
-#define wxRadioBox_GetColumnCount 2132
-#define wxRadioBox_GetItemHelpText 2133
-#define wxRadioBox_GetItemToolTip 2134
-#define wxRadioBox_GetItemFromPoint 2136
-#define wxRadioBox_GetRowCount 2137
-#define wxRadioBox_IsItemEnabled 2138
-#define wxRadioBox_IsItemShown 2139
-#define wxRadioBox_SetItemHelpText 2140
-#define wxRadioBox_SetItemToolTip 2141
-#define wxRadioButton_new_0 2142
-#define wxRadioButton_new_4 2143
-#define wxRadioButton_Create 2144
-#define wxRadioButton_GetValue 2145
-#define wxRadioButton_SetValue 2146
-#define wxRadioButton_destroy 2147
-#define wxSlider_new_6 2149
-#define wxSlider_new_0 2150
-#define wxSlider_Create 2151
-#define wxSlider_GetLineSize 2152
-#define wxSlider_GetMax 2153
-#define wxSlider_GetMin 2154
-#define wxSlider_GetPageSize 2155
-#define wxSlider_GetThumbLength 2156
-#define wxSlider_GetValue 2157
-#define wxSlider_SetLineSize 2158
-#define wxSlider_SetPageSize 2159
-#define wxSlider_SetRange 2160
-#define wxSlider_SetThumbLength 2161
-#define wxSlider_SetValue 2162
-#define wxSlider_destroy 2163
-#define wxDialog_new_4 2165
-#define wxDialog_new_0 2166
-#define wxDialog_destruct 2168
-#define wxDialog_Create 2169
-#define wxDialog_CreateButtonSizer 2170
-#define wxDialog_CreateStdDialogButtonSizer 2171
-#define wxDialog_EndModal 2172
-#define wxDialog_GetAffirmativeId 2173
-#define wxDialog_GetReturnCode 2174
-#define wxDialog_IsModal 2175
-#define wxDialog_SetAffirmativeId 2176
-#define wxDialog_SetReturnCode 2177
-#define wxDialog_Show 2178
-#define wxDialog_ShowModal 2179
-#define wxColourDialog_new_0 2180
-#define wxColourDialog_new_2 2181
-#define wxColourDialog_destruct 2182
-#define wxColourDialog_Create 2183
-#define wxColourDialog_GetColourData 2184
-#define wxColourData_new_0 2185
-#define wxColourData_new_1 2186
-#define wxColourData_destruct 2187
-#define wxColourData_GetChooseFull 2188
-#define wxColourData_GetColour 2189
-#define wxColourData_GetCustomColour 2191
-#define wxColourData_SetChooseFull 2192
-#define wxColourData_SetColour 2193
-#define wxColourData_SetCustomColour 2194
-#define wxPalette_new_0 2195
-#define wxPalette_new_4 2196
-#define wxPalette_destruct 2198
-#define wxPalette_Create 2199
-#define wxPalette_GetColoursCount 2200
-#define wxPalette_GetPixel 2201
-#define wxPalette_GetRGB 2202
-#define wxPalette_IsOk 2203
-#define wxDirDialog_new 2207
-#define wxDirDialog_destruct 2208
-#define wxDirDialog_GetPath 2209
-#define wxDirDialog_GetMessage 2210
-#define wxDirDialog_SetMessage 2211
-#define wxDirDialog_SetPath 2212
-#define wxFileDialog_new 2216
-#define wxFileDialog_destruct 2217
-#define wxFileDialog_GetDirectory 2218
-#define wxFileDialog_GetFilename 2219
-#define wxFileDialog_GetFilenames 2220
-#define wxFileDialog_GetFilterIndex 2221
-#define wxFileDialog_GetMessage 2222
-#define wxFileDialog_GetPath 2223
-#define wxFileDialog_GetPaths 2224
-#define wxFileDialog_GetWildcard 2225
-#define wxFileDialog_SetDirectory 2226
-#define wxFileDialog_SetFilename 2227
-#define wxFileDialog_SetFilterIndex 2228
-#define wxFileDialog_SetMessage 2229
-#define wxFileDialog_SetPath 2230
-#define wxFileDialog_SetWildcard 2231
-#define wxPickerBase_SetInternalMargin 2232
-#define wxPickerBase_GetInternalMargin 2233
-#define wxPickerBase_SetTextCtrlProportion 2234
-#define wxPickerBase_SetPickerCtrlProportion 2235
-#define wxPickerBase_GetTextCtrlProportion 2236
-#define wxPickerBase_GetPickerCtrlProportion 2237
-#define wxPickerBase_HasTextCtrl 2238
-#define wxPickerBase_GetTextCtrl 2239
-#define wxPickerBase_IsTextCtrlGrowable 2240
-#define wxPickerBase_SetPickerCtrlGrowable 2241
-#define wxPickerBase_SetTextCtrlGrowable 2242
-#define wxPickerBase_IsPickerCtrlGrowable 2243
-#define wxFilePickerCtrl_new_0 2244
-#define wxFilePickerCtrl_new_3 2245
-#define wxFilePickerCtrl_Create 2246
-#define wxFilePickerCtrl_GetPath 2247
-#define wxFilePickerCtrl_SetPath 2248
-#define wxFilePickerCtrl_destroy 2249
-#define wxDirPickerCtrl_new_0 2250
-#define wxDirPickerCtrl_new_3 2251
-#define wxDirPickerCtrl_Create 2252
-#define wxDirPickerCtrl_GetPath 2253
-#define wxDirPickerCtrl_SetPath 2254
-#define wxDirPickerCtrl_destroy 2255
-#define wxColourPickerCtrl_new_0 2256
-#define wxColourPickerCtrl_new_3 2257
-#define wxColourPickerCtrl_Create 2258
-#define wxColourPickerCtrl_GetColour 2259
-#define wxColourPickerCtrl_SetColour_1_1 2260
-#define wxColourPickerCtrl_SetColour_1_0 2261
-#define wxColourPickerCtrl_destroy 2262
-#define wxDatePickerCtrl_new_0 2263
-#define wxDatePickerCtrl_new_3 2264
-#define wxDatePickerCtrl_GetRange 2265
-#define wxDatePickerCtrl_GetValue 2266
-#define wxDatePickerCtrl_SetRange 2267
-#define wxDatePickerCtrl_SetValue 2268
-#define wxDatePickerCtrl_destroy 2269
-#define wxFontPickerCtrl_new_0 2270
-#define wxFontPickerCtrl_new_3 2271
-#define wxFontPickerCtrl_Create 2272
-#define wxFontPickerCtrl_GetSelectedFont 2273
-#define wxFontPickerCtrl_SetSelectedFont 2274
-#define wxFontPickerCtrl_GetMaxPointSize 2275
-#define wxFontPickerCtrl_SetMaxPointSize 2276
-#define wxFontPickerCtrl_destroy 2277
-#define wxFindReplaceDialog_new_0 2280
-#define wxFindReplaceDialog_new_4 2281
-#define wxFindReplaceDialog_destruct 2282
-#define wxFindReplaceDialog_Create 2283
-#define wxFindReplaceDialog_GetData 2284
-#define wxFindReplaceData_new_0 2285
-#define wxFindReplaceData_new_1 2286
-#define wxFindReplaceData_GetFindString 2287
-#define wxFindReplaceData_GetReplaceString 2288
-#define wxFindReplaceData_GetFlags 2289
-#define wxFindReplaceData_SetFlags 2290
-#define wxFindReplaceData_SetFindString 2291
-#define wxFindReplaceData_SetReplaceString 2292
-#define wxFindReplaceData_destroy 2293
-#define wxMultiChoiceDialog_new_0 2294
-#define wxMultiChoiceDialog_new_5 2296
-#define wxMultiChoiceDialog_GetSelections 2297
-#define wxMultiChoiceDialog_SetSelections 2298
-#define wxMultiChoiceDialog_destroy 2299
-#define wxSingleChoiceDialog_new_0 2300
-#define wxSingleChoiceDialog_new_5 2302
-#define wxSingleChoiceDialog_GetSelection 2303
-#define wxSingleChoiceDialog_GetStringSelection 2304
-#define wxSingleChoiceDialog_SetSelection 2305
-#define wxSingleChoiceDialog_destroy 2306
-#define wxTextEntryDialog_new 2307
-#define wxTextEntryDialog_GetValue 2308
-#define wxTextEntryDialog_SetValue 2309
-#define wxTextEntryDialog_destroy 2310
-#define wxPasswordEntryDialog_new 2311
-#define wxPasswordEntryDialog_destroy 2312
-#define wxFontData_new_0 2313
-#define wxFontData_new_1 2314
-#define wxFontData_destruct 2315
-#define wxFontData_EnableEffects 2316
-#define wxFontData_GetAllowSymbols 2317
-#define wxFontData_GetColour 2318
-#define wxFontData_GetChosenFont 2319
-#define wxFontData_GetEnableEffects 2320
-#define wxFontData_GetInitialFont 2321
-#define wxFontData_GetShowHelp 2322
-#define wxFontData_SetAllowSymbols 2323
-#define wxFontData_SetChosenFont 2324
-#define wxFontData_SetColour 2325
-#define wxFontData_SetInitialFont 2326
-#define wxFontData_SetRange 2327
-#define wxFontData_SetShowHelp 2328
-#define wxFontDialog_new_0 2332
-#define wxFontDialog_new_2 2334
-#define wxFontDialog_Create 2336
-#define wxFontDialog_GetFontData 2337
-#define wxFontDialog_destroy 2339
-#define wxProgressDialog_new 2340
-#define wxProgressDialog_destruct 2341
-#define wxProgressDialog_Resume 2342
-#define wxProgressDialog_Update_2 2343
-#define wxProgressDialog_Update_0 2344
-#define wxMessageDialog_new 2345
-#define wxMessageDialog_destruct 2346
-#define wxPageSetupDialog_new 2347
-#define wxPageSetupDialog_destruct 2348
-#define wxPageSetupDialog_GetPageSetupData 2349
-#define wxPageSetupDialog_ShowModal 2350
-#define wxPageSetupDialogData_new_0 2351
-#define wxPageSetupDialogData_new_1_0 2352
-#define wxPageSetupDialogData_new_1_1 2353
-#define wxPageSetupDialogData_destruct 2354
-#define wxPageSetupDialogData_EnableHelp 2355
-#define wxPageSetupDialogData_EnableMargins 2356
-#define wxPageSetupDialogData_EnableOrientation 2357
-#define wxPageSetupDialogData_EnablePaper 2358
-#define wxPageSetupDialogData_EnablePrinter 2359
-#define wxPageSetupDialogData_GetDefaultMinMargins 2360
-#define wxPageSetupDialogData_GetEnableMargins 2361
-#define wxPageSetupDialogData_GetEnableOrientation 2362
-#define wxPageSetupDialogData_GetEnablePaper 2363
-#define wxPageSetupDialogData_GetEnablePrinter 2364
-#define wxPageSetupDialogData_GetEnableHelp 2365
-#define wxPageSetupDialogData_GetDefaultInfo 2366
-#define wxPageSetupDialogData_GetMarginTopLeft 2367
-#define wxPageSetupDialogData_GetMarginBottomRight 2368
-#define wxPageSetupDialogData_GetMinMarginTopLeft 2369
-#define wxPageSetupDialogData_GetMinMarginBottomRight 2370
-#define wxPageSetupDialogData_GetPaperId 2371
-#define wxPageSetupDialogData_GetPaperSize 2372
-#define wxPageSetupDialogData_GetPrintData 2374
-#define wxPageSetupDialogData_IsOk 2375
-#define wxPageSetupDialogData_SetDefaultInfo 2376
-#define wxPageSetupDialogData_SetDefaultMinMargins 2377
-#define wxPageSetupDialogData_SetMarginTopLeft 2378
-#define wxPageSetupDialogData_SetMarginBottomRight 2379
-#define wxPageSetupDialogData_SetMinMarginTopLeft 2380
-#define wxPageSetupDialogData_SetMinMarginBottomRight 2381
-#define wxPageSetupDialogData_SetPaperId 2382
-#define wxPageSetupDialogData_SetPaperSize_1_1 2383
-#define wxPageSetupDialogData_SetPaperSize_1_0 2384
-#define wxPageSetupDialogData_SetPrintData 2385
-#define wxPrintDialog_new_2_0 2386
-#define wxPrintDialog_new_2_1 2387
-#define wxPrintDialog_destruct 2388
-#define wxPrintDialog_GetPrintDialogData 2389
-#define wxPrintDialog_GetPrintDC 2390
-#define wxPrintDialogData_new_0 2391
-#define wxPrintDialogData_new_1_1 2392
-#define wxPrintDialogData_new_1_0 2393
-#define wxPrintDialogData_destruct 2394
-#define wxPrintDialogData_EnableHelp 2395
-#define wxPrintDialogData_EnablePageNumbers 2396
-#define wxPrintDialogData_EnablePrintToFile 2397
-#define wxPrintDialogData_EnableSelection 2398
-#define wxPrintDialogData_GetAllPages 2399
-#define wxPrintDialogData_GetCollate 2400
-#define wxPrintDialogData_GetFromPage 2401
-#define wxPrintDialogData_GetMaxPage 2402
-#define wxPrintDialogData_GetMinPage 2403
-#define wxPrintDialogData_GetNoCopies 2404
-#define wxPrintDialogData_GetPrintData 2405
-#define wxPrintDialogData_GetPrintToFile 2406
-#define wxPrintDialogData_GetSelection 2407
-#define wxPrintDialogData_GetToPage 2408
-#define wxPrintDialogData_IsOk 2409
-#define wxPrintDialogData_SetCollate 2410
-#define wxPrintDialogData_SetFromPage 2411
-#define wxPrintDialogData_SetMaxPage 2412
-#define wxPrintDialogData_SetMinPage 2413
-#define wxPrintDialogData_SetNoCopies 2414
-#define wxPrintDialogData_SetPrintData 2415
-#define wxPrintDialogData_SetPrintToFile 2416
-#define wxPrintDialogData_SetSelection 2417
-#define wxPrintDialogData_SetToPage 2418
-#define wxPrintData_new_0 2419
-#define wxPrintData_new_1 2420
-#define wxPrintData_destruct 2421
-#define wxPrintData_GetCollate 2422
-#define wxPrintData_GetBin 2423
-#define wxPrintData_GetColour 2424
-#define wxPrintData_GetDuplex 2425
-#define wxPrintData_GetNoCopies 2426
-#define wxPrintData_GetOrientation 2427
-#define wxPrintData_GetPaperId 2428
-#define wxPrintData_GetPrinterName 2429
-#define wxPrintData_GetQuality 2430
-#define wxPrintData_IsOk 2431
-#define wxPrintData_SetBin 2432
-#define wxPrintData_SetCollate 2433
-#define wxPrintData_SetColour 2434
-#define wxPrintData_SetDuplex 2435
-#define wxPrintData_SetNoCopies 2436
-#define wxPrintData_SetOrientation 2437
-#define wxPrintData_SetPaperId 2438
-#define wxPrintData_SetPrinterName 2439
-#define wxPrintData_SetQuality 2440
-#define wxPrintPreview_new_2 2443
-#define wxPrintPreview_new_3 2444
-#define wxPrintPreview_destruct 2446
-#define wxPrintPreview_GetCanvas 2447
-#define wxPrintPreview_GetCurrentPage 2448
-#define wxPrintPreview_GetFrame 2449
-#define wxPrintPreview_GetMaxPage 2450
-#define wxPrintPreview_GetMinPage 2451
-#define wxPrintPreview_GetPrintout 2452
-#define wxPrintPreview_GetPrintoutForPrinting 2453
-#define wxPrintPreview_IsOk 2454
-#define wxPrintPreview_PaintPage 2455
-#define wxPrintPreview_Print 2456
-#define wxPrintPreview_RenderPage 2457
-#define wxPrintPreview_SetCanvas 2458
-#define wxPrintPreview_SetCurrentPage 2459
-#define wxPrintPreview_SetFrame 2460
-#define wxPrintPreview_SetPrintout 2461
-#define wxPrintPreview_SetZoom 2462
-#define wxPreviewFrame_new 2463
-#define wxPreviewFrame_destruct 2464
-#define wxPreviewFrame_CreateControlBar 2465
-#define wxPreviewFrame_CreateCanvas 2466
-#define wxPreviewFrame_Initialize 2467
-#define wxPreviewFrame_OnCloseWindow 2468
-#define wxPreviewControlBar_new 2469
-#define wxPreviewControlBar_destruct 2470
-#define wxPreviewControlBar_CreateButtons 2471
-#define wxPreviewControlBar_GetPrintPreview 2472
-#define wxPreviewControlBar_GetZoomControl 2473
-#define wxPreviewControlBar_SetZoomControl 2474
-#define wxPrinter_new 2476
-#define wxPrinter_CreateAbortWindow 2477
-#define wxPrinter_GetAbort 2478
-#define wxPrinter_GetLastError 2479
-#define wxPrinter_GetPrintDialogData 2480
-#define wxPrinter_Print 2481
-#define wxPrinter_PrintDialog 2482
-#define wxPrinter_ReportError 2483
-#define wxPrinter_Setup 2484
-#define wxPrinter_destroy 2485
-#define wxXmlResource_new_1 2486
-#define wxXmlResource_new_2 2487
-#define wxXmlResource_destruct 2488
-#define wxXmlResource_AttachUnknownControl 2489
-#define wxXmlResource_ClearHandlers 2490
-#define wxXmlResource_CompareVersion 2491
-#define wxXmlResource_Get 2492
-#define wxXmlResource_GetFlags 2493
-#define wxXmlResource_GetVersion 2494
-#define wxXmlResource_GetXRCID 2495
-#define wxXmlResource_InitAllHandlers 2496
-#define wxXmlResource_Load 2497
-#define wxXmlResource_LoadBitmap 2498
-#define wxXmlResource_LoadDialog_2 2499
-#define wxXmlResource_LoadDialog_3 2500
-#define wxXmlResource_LoadFrame_2 2501
-#define wxXmlResource_LoadFrame_3 2502
-#define wxXmlResource_LoadIcon 2503
-#define wxXmlResource_LoadMenu 2504
-#define wxXmlResource_LoadMenuBar_2 2505
-#define wxXmlResource_LoadMenuBar_1 2506
-#define wxXmlResource_LoadPanel_2 2507
-#define wxXmlResource_LoadPanel_3 2508
-#define wxXmlResource_LoadToolBar 2509
-#define wxXmlResource_Set 2510
-#define wxXmlResource_SetFlags 2511
-#define wxXmlResource_Unload 2512
-#define wxXmlResource_xrcctrl 2513
-#define wxHtmlEasyPrinting_new 2514
-#define wxHtmlEasyPrinting_destruct 2515
-#define wxHtmlEasyPrinting_GetPrintData 2516
-#define wxHtmlEasyPrinting_GetPageSetupData 2517
-#define wxHtmlEasyPrinting_PreviewFile 2518
-#define wxHtmlEasyPrinting_PreviewText 2519
-#define wxHtmlEasyPrinting_PrintFile 2520
-#define wxHtmlEasyPrinting_PrintText 2521
-#define wxHtmlEasyPrinting_PageSetup 2522
-#define wxHtmlEasyPrinting_SetFonts 2523
-#define wxHtmlEasyPrinting_SetHeader 2524
-#define wxHtmlEasyPrinting_SetFooter 2525
-#define wxGLCanvas_new_2 2527
-#define wxGLCanvas_new_3_1 2528
-#define wxGLCanvas_new_3_0 2529
-#define wxGLCanvas_GetContext 2530
-#define wxGLCanvas_SetCurrent 2532
-#define wxGLCanvas_SwapBuffers 2533
-#define wxGLCanvas_destroy 2534
-#define wxAuiManager_new 2535
-#define wxAuiManager_destruct 2536
-#define wxAuiManager_AddPane_2_1 2537
-#define wxAuiManager_AddPane_3 2538
-#define wxAuiManager_AddPane_2_0 2539
-#define wxAuiManager_DetachPane 2540
-#define wxAuiManager_GetAllPanes 2541
-#define wxAuiManager_GetArtProvider 2542
-#define wxAuiManager_GetDockSizeConstraint 2543
-#define wxAuiManager_GetFlags 2544
-#define wxAuiManager_GetManagedWindow 2545
-#define wxAuiManager_GetManager 2546
-#define wxAuiManager_GetPane_1_1 2547
-#define wxAuiManager_GetPane_1_0 2548
-#define wxAuiManager_HideHint 2549
-#define wxAuiManager_InsertPane 2550
-#define wxAuiManager_LoadPaneInfo 2551
-#define wxAuiManager_LoadPerspective 2552
-#define wxAuiManager_SavePaneInfo 2553
-#define wxAuiManager_SavePerspective 2554
-#define wxAuiManager_SetArtProvider 2555
-#define wxAuiManager_SetDockSizeConstraint 2556
-#define wxAuiManager_SetFlags 2557
-#define wxAuiManager_SetManagedWindow 2558
-#define wxAuiManager_ShowHint 2559
-#define wxAuiManager_UnInit 2560
-#define wxAuiManager_Update 2561
-#define wxAuiPaneInfo_new_0 2562
-#define wxAuiPaneInfo_new_1 2563
-#define wxAuiPaneInfo_destruct 2564
-#define wxAuiPaneInfo_BestSize_1 2565
-#define wxAuiPaneInfo_BestSize_2 2566
-#define wxAuiPaneInfo_Bottom 2567
-#define wxAuiPaneInfo_BottomDockable 2568
-#define wxAuiPaneInfo_Caption 2569
-#define wxAuiPaneInfo_CaptionVisible 2570
-#define wxAuiPaneInfo_Centre 2571
-#define wxAuiPaneInfo_CentrePane 2572
-#define wxAuiPaneInfo_CloseButton 2573
-#define wxAuiPaneInfo_DefaultPane 2574
-#define wxAuiPaneInfo_DestroyOnClose 2575
-#define wxAuiPaneInfo_Direction 2576
-#define wxAuiPaneInfo_Dock 2577
-#define wxAuiPaneInfo_Dockable 2578
-#define wxAuiPaneInfo_Fixed 2579
-#define wxAuiPaneInfo_Float 2580
-#define wxAuiPaneInfo_Floatable 2581
-#define wxAuiPaneInfo_FloatingPosition_1 2582
-#define wxAuiPaneInfo_FloatingPosition_2 2583
-#define wxAuiPaneInfo_FloatingSize_1 2584
-#define wxAuiPaneInfo_FloatingSize_2 2585
-#define wxAuiPaneInfo_Gripper 2586
-#define wxAuiPaneInfo_GripperTop 2587
-#define wxAuiPaneInfo_HasBorder 2588
-#define wxAuiPaneInfo_HasCaption 2589
-#define wxAuiPaneInfo_HasCloseButton 2590
-#define wxAuiPaneInfo_HasFlag 2591
-#define wxAuiPaneInfo_HasGripper 2592
-#define wxAuiPaneInfo_HasGripperTop 2593
-#define wxAuiPaneInfo_HasMaximizeButton 2594
-#define wxAuiPaneInfo_HasMinimizeButton 2595
-#define wxAuiPaneInfo_HasPinButton 2596
-#define wxAuiPaneInfo_Hide 2597
-#define wxAuiPaneInfo_IsBottomDockable 2598
-#define wxAuiPaneInfo_IsDocked 2599
-#define wxAuiPaneInfo_IsFixed 2600
-#define wxAuiPaneInfo_IsFloatable 2601
-#define wxAuiPaneInfo_IsFloating 2602
-#define wxAuiPaneInfo_IsLeftDockable 2603
-#define wxAuiPaneInfo_IsMovable 2604
-#define wxAuiPaneInfo_IsOk 2605
-#define wxAuiPaneInfo_IsResizable 2606
-#define wxAuiPaneInfo_IsRightDockable 2607
-#define wxAuiPaneInfo_IsShown 2608
-#define wxAuiPaneInfo_IsToolbar 2609
-#define wxAuiPaneInfo_IsTopDockable 2610
-#define wxAuiPaneInfo_Layer 2611
-#define wxAuiPaneInfo_Left 2612
-#define wxAuiPaneInfo_LeftDockable 2613
-#define wxAuiPaneInfo_MaxSize_1 2614
-#define wxAuiPaneInfo_MaxSize_2 2615
-#define wxAuiPaneInfo_MaximizeButton 2616
-#define wxAuiPaneInfo_MinSize_1 2617
-#define wxAuiPaneInfo_MinSize_2 2618
-#define wxAuiPaneInfo_MinimizeButton 2619
-#define wxAuiPaneInfo_Movable 2620
-#define wxAuiPaneInfo_Name 2621
-#define wxAuiPaneInfo_PaneBorder 2622
-#define wxAuiPaneInfo_PinButton 2623
-#define wxAuiPaneInfo_Position 2624
-#define wxAuiPaneInfo_Resizable 2625
-#define wxAuiPaneInfo_Right 2626
-#define wxAuiPaneInfo_RightDockable 2627
-#define wxAuiPaneInfo_Row 2628
-#define wxAuiPaneInfo_SafeSet 2629
-#define wxAuiPaneInfo_SetFlag 2630
-#define wxAuiPaneInfo_Show 2631
-#define wxAuiPaneInfo_ToolbarPane 2632
-#define wxAuiPaneInfo_Top 2633
-#define wxAuiPaneInfo_TopDockable 2634
-#define wxAuiPaneInfo_Window 2635
-#define wxAuiNotebook_new_0 2636
-#define wxAuiNotebook_new_2 2637
-#define wxAuiNotebook_AddPage 2638
-#define wxAuiNotebook_Create 2639
-#define wxAuiNotebook_DeletePage 2640
-#define wxAuiNotebook_GetArtProvider 2641
-#define wxAuiNotebook_GetPage 2642
-#define wxAuiNotebook_GetPageBitmap 2643
-#define wxAuiNotebook_GetPageCount 2644
-#define wxAuiNotebook_GetPageIndex 2645
-#define wxAuiNotebook_GetPageText 2646
-#define wxAuiNotebook_GetSelection 2647
-#define wxAuiNotebook_InsertPage 2648
-#define wxAuiNotebook_RemovePage 2649
-#define wxAuiNotebook_SetArtProvider 2650
-#define wxAuiNotebook_SetFont 2651
-#define wxAuiNotebook_SetPageBitmap 2652
-#define wxAuiNotebook_SetPageText 2653
-#define wxAuiNotebook_SetSelection 2654
-#define wxAuiNotebook_SetTabCtrlHeight 2655
-#define wxAuiNotebook_SetUniformBitmapSize 2656
-#define wxAuiNotebook_destroy 2657
-#define wxMDIParentFrame_new_0 2658
-#define wxMDIParentFrame_new_4 2659
-#define wxMDIParentFrame_destruct 2660
-#define wxMDIParentFrame_ActivateNext 2661
-#define wxMDIParentFrame_ActivatePrevious 2662
-#define wxMDIParentFrame_ArrangeIcons 2663
-#define wxMDIParentFrame_Cascade 2664
-#define wxMDIParentFrame_Create 2665
-#define wxMDIParentFrame_GetActiveChild 2666
-#define wxMDIParentFrame_GetClientWindow 2667
-#define wxMDIParentFrame_Tile 2668
-#define wxMDIChildFrame_new_0 2669
-#define wxMDIChildFrame_new_4 2670
-#define wxMDIChildFrame_destruct 2671
-#define wxMDIChildFrame_Activate 2672
-#define wxMDIChildFrame_Create 2673
-#define wxMDIChildFrame_Maximize 2674
-#define wxMDIChildFrame_Restore 2675
-#define wxMDIClientWindow_new_0 2676
-#define wxMDIClientWindow_new_2 2677
-#define wxMDIClientWindow_destruct 2678
-#define wxMDIClientWindow_CreateClient 2679
-#define wxLayoutAlgorithm_new 2680
-#define wxLayoutAlgorithm_LayoutFrame 2681
-#define wxLayoutAlgorithm_LayoutMDIFrame 2682
-#define wxLayoutAlgorithm_LayoutWindow 2683
-#define wxLayoutAlgorithm_destroy 2684
-#define wxEvent_GetId 2685
-#define wxEvent_GetSkipped 2686
-#define wxEvent_GetTimestamp 2687
-#define wxEvent_IsCommandEvent 2688
-#define wxEvent_ResumePropagation 2689
-#define wxEvent_ShouldPropagate 2690
-#define wxEvent_Skip 2691
-#define wxEvent_StopPropagation 2692
-#define wxCommandEvent_getClientData 2693
-#define wxCommandEvent_GetExtraLong 2694
-#define wxCommandEvent_GetInt 2695
-#define wxCommandEvent_GetSelection 2696
-#define wxCommandEvent_GetString 2697
-#define wxCommandEvent_IsChecked 2698
-#define wxCommandEvent_IsSelection 2699
-#define wxCommandEvent_SetInt 2700
-#define wxCommandEvent_SetString 2701
-#define wxScrollEvent_GetOrientation 2702
-#define wxScrollEvent_GetPosition 2703
-#define wxScrollWinEvent_GetOrientation 2704
-#define wxScrollWinEvent_GetPosition 2705
-#define wxMouseEvent_AltDown 2706
-#define wxMouseEvent_Button 2707
-#define wxMouseEvent_ButtonDClick 2708
-#define wxMouseEvent_ButtonDown 2709
-#define wxMouseEvent_ButtonUp 2710
-#define wxMouseEvent_CmdDown 2711
-#define wxMouseEvent_ControlDown 2712
-#define wxMouseEvent_Dragging 2713
-#define wxMouseEvent_Entering 2714
-#define wxMouseEvent_GetButton 2715
-#define wxMouseEvent_GetPosition 2718
-#define wxMouseEvent_GetLogicalPosition 2719
-#define wxMouseEvent_GetLinesPerAction 2720
-#define wxMouseEvent_GetWheelRotation 2721
-#define wxMouseEvent_GetWheelDelta 2722
-#define wxMouseEvent_GetX 2723
-#define wxMouseEvent_GetY 2724
-#define wxMouseEvent_IsButton 2725
-#define wxMouseEvent_IsPageScroll 2726
-#define wxMouseEvent_Leaving 2727
-#define wxMouseEvent_LeftDClick 2728
-#define wxMouseEvent_LeftDown 2729
-#define wxMouseEvent_LeftIsDown 2730
-#define wxMouseEvent_LeftUp 2731
-#define wxMouseEvent_MetaDown 2732
-#define wxMouseEvent_MiddleDClick 2733
-#define wxMouseEvent_MiddleDown 2734
-#define wxMouseEvent_MiddleIsDown 2735
-#define wxMouseEvent_MiddleUp 2736
-#define wxMouseEvent_Moving 2737
-#define wxMouseEvent_RightDClick 2738
-#define wxMouseEvent_RightDown 2739
-#define wxMouseEvent_RightIsDown 2740
-#define wxMouseEvent_RightUp 2741
-#define wxMouseEvent_ShiftDown 2742
-#define wxSetCursorEvent_GetCursor 2743
-#define wxSetCursorEvent_GetX 2744
-#define wxSetCursorEvent_GetY 2745
-#define wxSetCursorEvent_HasCursor 2746
-#define wxSetCursorEvent_SetCursor 2747
-#define wxKeyEvent_AltDown 2748
-#define wxKeyEvent_CmdDown 2749
-#define wxKeyEvent_ControlDown 2750
-#define wxKeyEvent_GetKeyCode 2751
-#define wxKeyEvent_GetModifiers 2752
-#define wxKeyEvent_GetPosition 2755
-#define wxKeyEvent_GetRawKeyCode 2756
-#define wxKeyEvent_GetRawKeyFlags 2757
-#define wxKeyEvent_GetUnicodeKey 2758
-#define wxKeyEvent_GetX 2759
-#define wxKeyEvent_GetY 2760
-#define wxKeyEvent_HasModifiers 2761
-#define wxKeyEvent_MetaDown 2762
-#define wxKeyEvent_ShiftDown 2763
-#define wxSizeEvent_GetSize 2764
-#define wxMoveEvent_GetPosition 2765
-#define wxEraseEvent_GetDC 2766
-#define wxFocusEvent_GetWindow 2767
-#define wxChildFocusEvent_GetWindow 2768
-#define wxMenuEvent_GetMenu 2769
-#define wxMenuEvent_GetMenuId 2770
-#define wxMenuEvent_IsPopup 2771
-#define wxCloseEvent_CanVeto 2772
-#define wxCloseEvent_GetLoggingOff 2773
-#define wxCloseEvent_SetCanVeto 2774
-#define wxCloseEvent_SetLoggingOff 2775
-#define wxCloseEvent_Veto 2776
-#define wxShowEvent_SetShow 2777
-#define wxShowEvent_GetShow 2778
-#define wxIconizeEvent_Iconized 2779
-#define wxJoystickEvent_ButtonDown 2780
-#define wxJoystickEvent_ButtonIsDown 2781
-#define wxJoystickEvent_ButtonUp 2782
-#define wxJoystickEvent_GetButtonChange 2783
-#define wxJoystickEvent_GetButtonState 2784
-#define wxJoystickEvent_GetJoystick 2785
-#define wxJoystickEvent_GetPosition 2786
-#define wxJoystickEvent_GetZPosition 2787
-#define wxJoystickEvent_IsButton 2788
-#define wxJoystickEvent_IsMove 2789
-#define wxJoystickEvent_IsZMove 2790
-#define wxUpdateUIEvent_CanUpdate 2791
-#define wxUpdateUIEvent_Check 2792
-#define wxUpdateUIEvent_Enable 2793
-#define wxUpdateUIEvent_Show 2794
-#define wxUpdateUIEvent_GetChecked 2795
-#define wxUpdateUIEvent_GetEnabled 2796
-#define wxUpdateUIEvent_GetShown 2797
-#define wxUpdateUIEvent_GetSetChecked 2798
-#define wxUpdateUIEvent_GetSetEnabled 2799
-#define wxUpdateUIEvent_GetSetShown 2800
-#define wxUpdateUIEvent_GetSetText 2801
-#define wxUpdateUIEvent_GetText 2802
-#define wxUpdateUIEvent_GetMode 2803
-#define wxUpdateUIEvent_GetUpdateInterval 2804
-#define wxUpdateUIEvent_ResetUpdateTime 2805
-#define wxUpdateUIEvent_SetMode 2806
-#define wxUpdateUIEvent_SetText 2807
-#define wxUpdateUIEvent_SetUpdateInterval 2808
-#define wxMouseCaptureChangedEvent_GetCapturedWindow 2809
-#define wxPaletteChangedEvent_SetChangedWindow 2810
-#define wxPaletteChangedEvent_GetChangedWindow 2811
-#define wxQueryNewPaletteEvent_SetPaletteRealized 2812
-#define wxQueryNewPaletteEvent_GetPaletteRealized 2813
-#define wxNavigationKeyEvent_GetDirection 2814
-#define wxNavigationKeyEvent_SetDirection 2815
-#define wxNavigationKeyEvent_IsWindowChange 2816
-#define wxNavigationKeyEvent_SetWindowChange 2817
-#define wxNavigationKeyEvent_IsFromTab 2818
-#define wxNavigationKeyEvent_SetFromTab 2819
-#define wxNavigationKeyEvent_GetCurrentFocus 2820
-#define wxNavigationKeyEvent_SetCurrentFocus 2821
-#define wxHelpEvent_GetOrigin 2822
-#define wxHelpEvent_GetPosition 2823
-#define wxHelpEvent_SetOrigin 2824
-#define wxHelpEvent_SetPosition 2825
-#define wxContextMenuEvent_GetPosition 2826
-#define wxContextMenuEvent_SetPosition 2827
-#define wxIdleEvent_CanSend 2828
-#define wxIdleEvent_GetMode 2829
-#define wxIdleEvent_RequestMore 2830
-#define wxIdleEvent_MoreRequested 2831
-#define wxIdleEvent_SetMode 2832
-#define wxGridEvent_AltDown 2833
-#define wxGridEvent_ControlDown 2834
-#define wxGridEvent_GetCol 2835
-#define wxGridEvent_GetPosition 2836
-#define wxGridEvent_GetRow 2837
-#define wxGridEvent_MetaDown 2838
-#define wxGridEvent_Selecting 2839
-#define wxGridEvent_ShiftDown 2840
-#define wxNotifyEvent_Allow 2841
-#define wxNotifyEvent_IsAllowed 2842
-#define wxNotifyEvent_Veto 2843
-#define wxSashEvent_GetEdge 2844
-#define wxSashEvent_GetDragRect 2845
-#define wxSashEvent_GetDragStatus 2846
-#define wxListEvent_GetCacheFrom 2847
-#define wxListEvent_GetCacheTo 2848
-#define wxListEvent_GetKeyCode 2849
-#define wxListEvent_GetIndex 2850
-#define wxListEvent_GetColumn 2851
-#define wxListEvent_GetPoint 2852
-#define wxListEvent_GetLabel 2853
-#define wxListEvent_GetText 2854
-#define wxListEvent_GetImage 2855
-#define wxListEvent_GetData 2856
-#define wxListEvent_GetMask 2857
-#define wxListEvent_GetItem 2858
-#define wxListEvent_IsEditCancelled 2859
-#define wxDateEvent_GetDate 2860
-#define wxCalendarEvent_GetWeekDay 2861
-#define wxFileDirPickerEvent_GetPath 2862
-#define wxColourPickerEvent_GetColour 2863
-#define wxFontPickerEvent_GetFont 2864
-#define wxStyledTextEvent_GetPosition 2865
-#define wxStyledTextEvent_GetKey 2866
-#define wxStyledTextEvent_GetModifiers 2867
-#define wxStyledTextEvent_GetModificationType 2868
-#define wxStyledTextEvent_GetText 2869
-#define wxStyledTextEvent_GetLength 2870
-#define wxStyledTextEvent_GetLinesAdded 2871
-#define wxStyledTextEvent_GetLine 2872
-#define wxStyledTextEvent_GetFoldLevelNow 2873
-#define wxStyledTextEvent_GetFoldLevelPrev 2874
-#define wxStyledTextEvent_GetMargin 2875
-#define wxStyledTextEvent_GetMessage 2876
-#define wxStyledTextEvent_GetWParam 2877
-#define wxStyledTextEvent_GetLParam 2878
-#define wxStyledTextEvent_GetListType 2879
-#define wxStyledTextEvent_GetX 2880
-#define wxStyledTextEvent_GetY 2881
-#define wxStyledTextEvent_GetDragText 2882
-#define wxStyledTextEvent_GetDragAllowMove 2883
-#define wxStyledTextEvent_GetDragResult 2884
-#define wxStyledTextEvent_GetShift 2885
-#define wxStyledTextEvent_GetControl 2886
-#define wxStyledTextEvent_GetAlt 2887
-#define utils_wxGetKeyState 2888
-#define utils_wxGetMousePosition 2889
-#define utils_wxGetMouseState 2890
-#define utils_wxSetDetectableAutoRepeat 2891
-#define utils_wxBell 2892
-#define utils_wxFindMenuItemId 2893
-#define utils_wxGenericFindWindowAtPoint 2894
-#define utils_wxFindWindowAtPoint 2895
-#define utils_wxBeginBusyCursor 2896
-#define utils_wxEndBusyCursor 2897
-#define utils_wxIsBusy 2898
-#define utils_wxShutdown 2899
-#define utils_wxShell 2900
-#define utils_wxLaunchDefaultBrowser 2901
-#define utils_wxGetEmailAddress 2902
-#define utils_wxGetUserId 2903
-#define utils_wxGetHomeDir 2904
-#define utils_wxNewId 2905
-#define utils_wxRegisterId 2906
-#define utils_wxGetCurrentId 2907
-#define utils_wxGetOsDescription 2908
-#define utils_wxIsPlatformLittleEndian 2909
-#define utils_wxIsPlatform64Bit 2910
-#define wxPrintout_new 2911
-#define wxPrintout_destruct 2912
-#define wxPrintout_GetDC 2913
-#define wxPrintout_GetPageSizeMM 2914
-#define wxPrintout_GetPageSizePixels 2915
-#define wxPrintout_GetPaperRectPixels 2916
-#define wxPrintout_GetPPIPrinter 2917
-#define wxPrintout_GetPPIScreen 2918
-#define wxPrintout_GetTitle 2919
-#define wxPrintout_IsPreview 2920
-#define wxPrintout_FitThisSizeToPaper 2921
-#define wxPrintout_FitThisSizeToPage 2922
-#define wxPrintout_FitThisSizeToPageMargins 2923
-#define wxPrintout_MapScreenSizeToPaper 2924
-#define wxPrintout_MapScreenSizeToPage 2925
-#define wxPrintout_MapScreenSizeToPageMargins 2926
-#define wxPrintout_MapScreenSizeToDevice 2927
-#define wxPrintout_GetLogicalPaperRect 2928
-#define wxPrintout_GetLogicalPageRect 2929
-#define wxPrintout_GetLogicalPageMarginsRect 2930
-#define wxPrintout_SetLogicalOrigin 2931
-#define wxPrintout_OffsetLogicalOrigin 2932
-#define wxStyledTextCtrl_new_2 2933
-#define wxStyledTextCtrl_new_0 2934
-#define wxStyledTextCtrl_destruct 2935
-#define wxStyledTextCtrl_Create 2936
-#define wxStyledTextCtrl_AddText 2937
-#define wxStyledTextCtrl_AddStyledText 2938
-#define wxStyledTextCtrl_InsertText 2939
-#define wxStyledTextCtrl_ClearAll 2940
-#define wxStyledTextCtrl_ClearDocumentStyle 2941
-#define wxStyledTextCtrl_GetLength 2942
-#define wxStyledTextCtrl_GetCharAt 2943
-#define wxStyledTextCtrl_GetCurrentPos 2944
-#define wxStyledTextCtrl_GetAnchor 2945
-#define wxStyledTextCtrl_GetStyleAt 2946
-#define wxStyledTextCtrl_Redo 2947
-#define wxStyledTextCtrl_SetUndoCollection 2948
-#define wxStyledTextCtrl_SelectAll 2949
-#define wxStyledTextCtrl_SetSavePoint 2950
-#define wxStyledTextCtrl_GetStyledText 2951
-#define wxStyledTextCtrl_CanRedo 2952
-#define wxStyledTextCtrl_MarkerLineFromHandle 2953
-#define wxStyledTextCtrl_MarkerDeleteHandle 2954
-#define wxStyledTextCtrl_GetUndoCollection 2955
-#define wxStyledTextCtrl_GetViewWhiteSpace 2956
-#define wxStyledTextCtrl_SetViewWhiteSpace 2957
-#define wxStyledTextCtrl_PositionFromPoint 2958
-#define wxStyledTextCtrl_PositionFromPointClose 2959
-#define wxStyledTextCtrl_GotoLine 2960
-#define wxStyledTextCtrl_GotoPos 2961
-#define wxStyledTextCtrl_SetAnchor 2962
-#define wxStyledTextCtrl_GetCurLine 2963
-#define wxStyledTextCtrl_GetEndStyled 2964
-#define wxStyledTextCtrl_ConvertEOLs 2965
-#define wxStyledTextCtrl_GetEOLMode 2966
-#define wxStyledTextCtrl_SetEOLMode 2967
-#define wxStyledTextCtrl_StartStyling 2968
-#define wxStyledTextCtrl_SetStyling 2969
-#define wxStyledTextCtrl_GetBufferedDraw 2970
-#define wxStyledTextCtrl_SetBufferedDraw 2971
-#define wxStyledTextCtrl_SetTabWidth 2972
-#define wxStyledTextCtrl_GetTabWidth 2973
-#define wxStyledTextCtrl_SetCodePage 2974
-#define wxStyledTextCtrl_MarkerDefine 2975
-#define wxStyledTextCtrl_MarkerSetForeground 2976
-#define wxStyledTextCtrl_MarkerSetBackground 2977
-#define wxStyledTextCtrl_MarkerAdd 2978
-#define wxStyledTextCtrl_MarkerDelete 2979
-#define wxStyledTextCtrl_MarkerDeleteAll 2980
-#define wxStyledTextCtrl_MarkerGet 2981
-#define wxStyledTextCtrl_MarkerNext 2982
-#define wxStyledTextCtrl_MarkerPrevious 2983
-#define wxStyledTextCtrl_MarkerDefineBitmap 2984
-#define wxStyledTextCtrl_MarkerAddSet 2985
-#define wxStyledTextCtrl_MarkerSetAlpha 2986
-#define wxStyledTextCtrl_SetMarginType 2987
-#define wxStyledTextCtrl_GetMarginType 2988
-#define wxStyledTextCtrl_SetMarginWidth 2989
-#define wxStyledTextCtrl_GetMarginWidth 2990
-#define wxStyledTextCtrl_SetMarginMask 2991
-#define wxStyledTextCtrl_GetMarginMask 2992
-#define wxStyledTextCtrl_SetMarginSensitive 2993
-#define wxStyledTextCtrl_GetMarginSensitive 2994
-#define wxStyledTextCtrl_StyleClearAll 2995
-#define wxStyledTextCtrl_StyleSetForeground 2996
-#define wxStyledTextCtrl_StyleSetBackground 2997
-#define wxStyledTextCtrl_StyleSetBold 2998
-#define wxStyledTextCtrl_StyleSetItalic 2999
-#define wxStyledTextCtrl_StyleSetSize 3000
-#define wxStyledTextCtrl_StyleSetFaceName 3001
-#define wxStyledTextCtrl_StyleSetEOLFilled 3002
-#define wxStyledTextCtrl_StyleResetDefault 3003
-#define wxStyledTextCtrl_StyleSetUnderline 3004
-#define wxStyledTextCtrl_StyleSetCase 3005
-#define wxStyledTextCtrl_StyleSetHotSpot 3006
-#define wxStyledTextCtrl_SetSelForeground 3007
-#define wxStyledTextCtrl_SetSelBackground 3008
-#define wxStyledTextCtrl_GetSelAlpha 3009
-#define wxStyledTextCtrl_SetSelAlpha 3010
-#define wxStyledTextCtrl_SetCaretForeground 3011
-#define wxStyledTextCtrl_CmdKeyAssign 3012
-#define wxStyledTextCtrl_CmdKeyClear 3013
-#define wxStyledTextCtrl_CmdKeyClearAll 3014
-#define wxStyledTextCtrl_SetStyleBytes 3015
-#define wxStyledTextCtrl_StyleSetVisible 3016
-#define wxStyledTextCtrl_GetCaretPeriod 3017
-#define wxStyledTextCtrl_SetCaretPeriod 3018
-#define wxStyledTextCtrl_SetWordChars 3019
-#define wxStyledTextCtrl_BeginUndoAction 3020
-#define wxStyledTextCtrl_EndUndoAction 3021
-#define wxStyledTextCtrl_IndicatorSetStyle 3022
-#define wxStyledTextCtrl_IndicatorGetStyle 3023
-#define wxStyledTextCtrl_IndicatorSetForeground 3024
-#define wxStyledTextCtrl_IndicatorGetForeground 3025
-#define wxStyledTextCtrl_SetWhitespaceForeground 3026
-#define wxStyledTextCtrl_SetWhitespaceBackground 3027
-#define wxStyledTextCtrl_GetStyleBits 3028
-#define wxStyledTextCtrl_SetLineState 3029
-#define wxStyledTextCtrl_GetLineState 3030
-#define wxStyledTextCtrl_GetMaxLineState 3031
-#define wxStyledTextCtrl_GetCaretLineVisible 3032
-#define wxStyledTextCtrl_SetCaretLineVisible 3033
-#define wxStyledTextCtrl_GetCaretLineBackground 3034
-#define wxStyledTextCtrl_SetCaretLineBackground 3035
-#define wxStyledTextCtrl_AutoCompShow 3036
-#define wxStyledTextCtrl_AutoCompCancel 3037
-#define wxStyledTextCtrl_AutoCompActive 3038
-#define wxStyledTextCtrl_AutoCompPosStart 3039
-#define wxStyledTextCtrl_AutoCompComplete 3040
-#define wxStyledTextCtrl_AutoCompStops 3041
-#define wxStyledTextCtrl_AutoCompSetSeparator 3042
-#define wxStyledTextCtrl_AutoCompGetSeparator 3043
-#define wxStyledTextCtrl_AutoCompSelect 3044
-#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3045
-#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3046
-#define wxStyledTextCtrl_AutoCompSetFillUps 3047
-#define wxStyledTextCtrl_AutoCompSetChooseSingle 3048
-#define wxStyledTextCtrl_AutoCompGetChooseSingle 3049
-#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3050
-#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3051
-#define wxStyledTextCtrl_UserListShow 3052
-#define wxStyledTextCtrl_AutoCompSetAutoHide 3053
-#define wxStyledTextCtrl_AutoCompGetAutoHide 3054
-#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3055
-#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3056
-#define wxStyledTextCtrl_RegisterImage 3057
-#define wxStyledTextCtrl_ClearRegisteredImages 3058
-#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3059
-#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3060
-#define wxStyledTextCtrl_AutoCompSetMaxWidth 3061
-#define wxStyledTextCtrl_AutoCompGetMaxWidth 3062
-#define wxStyledTextCtrl_AutoCompSetMaxHeight 3063
-#define wxStyledTextCtrl_AutoCompGetMaxHeight 3064
-#define wxStyledTextCtrl_SetIndent 3065
-#define wxStyledTextCtrl_GetIndent 3066
-#define wxStyledTextCtrl_SetUseTabs 3067
-#define wxStyledTextCtrl_GetUseTabs 3068
-#define wxStyledTextCtrl_SetLineIndentation 3069
-#define wxStyledTextCtrl_GetLineIndentation 3070
-#define wxStyledTextCtrl_GetLineIndentPosition 3071
-#define wxStyledTextCtrl_GetColumn 3072
-#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3073
-#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3074
-#define wxStyledTextCtrl_SetIndentationGuides 3075
-#define wxStyledTextCtrl_GetIndentationGuides 3076
-#define wxStyledTextCtrl_SetHighlightGuide 3077
-#define wxStyledTextCtrl_GetHighlightGuide 3078
-#define wxStyledTextCtrl_GetLineEndPosition 3079
-#define wxStyledTextCtrl_GetCodePage 3080
-#define wxStyledTextCtrl_GetCaretForeground 3081
-#define wxStyledTextCtrl_GetReadOnly 3082
-#define wxStyledTextCtrl_SetCurrentPos 3083
-#define wxStyledTextCtrl_SetSelectionStart 3084
-#define wxStyledTextCtrl_GetSelectionStart 3085
-#define wxStyledTextCtrl_SetSelectionEnd 3086
-#define wxStyledTextCtrl_GetSelectionEnd 3087
-#define wxStyledTextCtrl_SetPrintMagnification 3088
-#define wxStyledTextCtrl_GetPrintMagnification 3089
-#define wxStyledTextCtrl_SetPrintColourMode 3090
-#define wxStyledTextCtrl_GetPrintColourMode 3091
-#define wxStyledTextCtrl_FindText 3092
-#define wxStyledTextCtrl_FormatRange 3093
-#define wxStyledTextCtrl_GetFirstVisibleLine 3094
-#define wxStyledTextCtrl_GetLine 3095
-#define wxStyledTextCtrl_GetLineCount 3096
-#define wxStyledTextCtrl_SetMarginLeft 3097
-#define wxStyledTextCtrl_GetMarginLeft 3098
-#define wxStyledTextCtrl_SetMarginRight 3099
-#define wxStyledTextCtrl_GetMarginRight 3100
-#define wxStyledTextCtrl_GetModify 3101
-#define wxStyledTextCtrl_SetSelection 3102
-#define wxStyledTextCtrl_GetSelectedText 3103
-#define wxStyledTextCtrl_GetTextRange 3104
-#define wxStyledTextCtrl_HideSelection 3105
-#define wxStyledTextCtrl_LineFromPosition 3106
-#define wxStyledTextCtrl_PositionFromLine 3107
-#define wxStyledTextCtrl_LineScroll 3108
-#define wxStyledTextCtrl_EnsureCaretVisible 3109
-#define wxStyledTextCtrl_ReplaceSelection 3110
-#define wxStyledTextCtrl_SetReadOnly 3111
-#define wxStyledTextCtrl_CanPaste 3112
-#define wxStyledTextCtrl_CanUndo 3113
-#define wxStyledTextCtrl_EmptyUndoBuffer 3114
-#define wxStyledTextCtrl_Undo 3115
-#define wxStyledTextCtrl_Cut 3116
-#define wxStyledTextCtrl_Copy 3117
-#define wxStyledTextCtrl_Paste 3118
-#define wxStyledTextCtrl_Clear 3119
-#define wxStyledTextCtrl_SetText 3120
-#define wxStyledTextCtrl_GetText 3121
-#define wxStyledTextCtrl_GetTextLength 3122
-#define wxStyledTextCtrl_GetOvertype 3123
-#define wxStyledTextCtrl_SetCaretWidth 3124
-#define wxStyledTextCtrl_GetCaretWidth 3125
-#define wxStyledTextCtrl_SetTargetStart 3126
-#define wxStyledTextCtrl_GetTargetStart 3127
-#define wxStyledTextCtrl_SetTargetEnd 3128
-#define wxStyledTextCtrl_GetTargetEnd 3129
-#define wxStyledTextCtrl_ReplaceTarget 3130
-#define wxStyledTextCtrl_SearchInTarget 3131
-#define wxStyledTextCtrl_SetSearchFlags 3132
-#define wxStyledTextCtrl_GetSearchFlags 3133
-#define wxStyledTextCtrl_CallTipShow 3134
-#define wxStyledTextCtrl_CallTipCancel 3135
-#define wxStyledTextCtrl_CallTipActive 3136
-#define wxStyledTextCtrl_CallTipPosAtStart 3137
-#define wxStyledTextCtrl_CallTipSetHighlight 3138
-#define wxStyledTextCtrl_CallTipSetBackground 3139
-#define wxStyledTextCtrl_CallTipSetForeground 3140
-#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3141
-#define wxStyledTextCtrl_CallTipUseStyle 3142
-#define wxStyledTextCtrl_VisibleFromDocLine 3143
-#define wxStyledTextCtrl_DocLineFromVisible 3144
-#define wxStyledTextCtrl_WrapCount 3145
-#define wxStyledTextCtrl_SetFoldLevel 3146
-#define wxStyledTextCtrl_GetFoldLevel 3147
-#define wxStyledTextCtrl_GetLastChild 3148
-#define wxStyledTextCtrl_GetFoldParent 3149
-#define wxStyledTextCtrl_ShowLines 3150
-#define wxStyledTextCtrl_HideLines 3151
-#define wxStyledTextCtrl_GetLineVisible 3152
-#define wxStyledTextCtrl_SetFoldExpanded 3153
-#define wxStyledTextCtrl_GetFoldExpanded 3154
-#define wxStyledTextCtrl_ToggleFold 3155
-#define wxStyledTextCtrl_EnsureVisible 3156
-#define wxStyledTextCtrl_SetFoldFlags 3157
-#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3158
-#define wxStyledTextCtrl_SetTabIndents 3159
-#define wxStyledTextCtrl_GetTabIndents 3160
-#define wxStyledTextCtrl_SetBackSpaceUnIndents 3161
-#define wxStyledTextCtrl_GetBackSpaceUnIndents 3162
-#define wxStyledTextCtrl_SetMouseDwellTime 3163
-#define wxStyledTextCtrl_GetMouseDwellTime 3164
-#define wxStyledTextCtrl_WordStartPosition 3165
-#define wxStyledTextCtrl_WordEndPosition 3166
-#define wxStyledTextCtrl_SetWrapMode 3167
-#define wxStyledTextCtrl_GetWrapMode 3168
-#define wxStyledTextCtrl_SetWrapVisualFlags 3169
-#define wxStyledTextCtrl_GetWrapVisualFlags 3170
-#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3171
-#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3172
-#define wxStyledTextCtrl_SetWrapStartIndent 3173
-#define wxStyledTextCtrl_GetWrapStartIndent 3174
-#define wxStyledTextCtrl_SetLayoutCache 3175
-#define wxStyledTextCtrl_GetLayoutCache 3176
-#define wxStyledTextCtrl_SetScrollWidth 3177
-#define wxStyledTextCtrl_GetScrollWidth 3178
-#define wxStyledTextCtrl_TextWidth 3179
-#define wxStyledTextCtrl_GetEndAtLastLine 3180
-#define wxStyledTextCtrl_TextHeight 3181
-#define wxStyledTextCtrl_SetUseVerticalScrollBar 3182
-#define wxStyledTextCtrl_GetUseVerticalScrollBar 3183
-#define wxStyledTextCtrl_AppendText 3184
-#define wxStyledTextCtrl_GetTwoPhaseDraw 3185
-#define wxStyledTextCtrl_SetTwoPhaseDraw 3186
-#define wxStyledTextCtrl_TargetFromSelection 3187
-#define wxStyledTextCtrl_LinesJoin 3188
-#define wxStyledTextCtrl_LinesSplit 3189
-#define wxStyledTextCtrl_SetFoldMarginColour 3190
-#define wxStyledTextCtrl_SetFoldMarginHiColour 3191
-#define wxStyledTextCtrl_LineDown 3192
-#define wxStyledTextCtrl_LineDownExtend 3193
-#define wxStyledTextCtrl_LineUp 3194
-#define wxStyledTextCtrl_LineUpExtend 3195
-#define wxStyledTextCtrl_CharLeft 3196
-#define wxStyledTextCtrl_CharLeftExtend 3197
-#define wxStyledTextCtrl_CharRight 3198
-#define wxStyledTextCtrl_CharRightExtend 3199
-#define wxStyledTextCtrl_WordLeft 3200
-#define wxStyledTextCtrl_WordLeftExtend 3201
-#define wxStyledTextCtrl_WordRight 3202
-#define wxStyledTextCtrl_WordRightExtend 3203
-#define wxStyledTextCtrl_Home 3204
-#define wxStyledTextCtrl_HomeExtend 3205
-#define wxStyledTextCtrl_LineEnd 3206
-#define wxStyledTextCtrl_LineEndExtend 3207
-#define wxStyledTextCtrl_DocumentStart 3208
-#define wxStyledTextCtrl_DocumentStartExtend 3209
-#define wxStyledTextCtrl_DocumentEnd 3210
-#define wxStyledTextCtrl_DocumentEndExtend 3211
-#define wxStyledTextCtrl_PageUp 3212
-#define wxStyledTextCtrl_PageUpExtend 3213
-#define wxStyledTextCtrl_PageDown 3214
-#define wxStyledTextCtrl_PageDownExtend 3215
-#define wxStyledTextCtrl_EditToggleOvertype 3216
-#define wxStyledTextCtrl_Cancel 3217
-#define wxStyledTextCtrl_DeleteBack 3218
-#define wxStyledTextCtrl_Tab 3219
-#define wxStyledTextCtrl_BackTab 3220
-#define wxStyledTextCtrl_NewLine 3221
-#define wxStyledTextCtrl_FormFeed 3222
-#define wxStyledTextCtrl_VCHome 3223
-#define wxStyledTextCtrl_VCHomeExtend 3224
-#define wxStyledTextCtrl_ZoomIn 3225
-#define wxStyledTextCtrl_ZoomOut 3226
-#define wxStyledTextCtrl_DelWordLeft 3227
-#define wxStyledTextCtrl_DelWordRight 3228
-#define wxStyledTextCtrl_LineCut 3229
-#define wxStyledTextCtrl_LineDelete 3230
-#define wxStyledTextCtrl_LineTranspose 3231
-#define wxStyledTextCtrl_LineDuplicate 3232
-#define wxStyledTextCtrl_LowerCase 3233
-#define wxStyledTextCtrl_UpperCase 3234
-#define wxStyledTextCtrl_LineScrollDown 3235
-#define wxStyledTextCtrl_LineScrollUp 3236
-#define wxStyledTextCtrl_DeleteBackNotLine 3237
-#define wxStyledTextCtrl_HomeDisplay 3238
-#define wxStyledTextCtrl_HomeDisplayExtend 3239
-#define wxStyledTextCtrl_LineEndDisplay 3240
-#define wxStyledTextCtrl_LineEndDisplayExtend 3241
-#define wxStyledTextCtrl_HomeWrapExtend 3242
-#define wxStyledTextCtrl_LineEndWrap 3243
-#define wxStyledTextCtrl_LineEndWrapExtend 3244
-#define wxStyledTextCtrl_VCHomeWrap 3245
-#define wxStyledTextCtrl_VCHomeWrapExtend 3246
-#define wxStyledTextCtrl_LineCopy 3247
-#define wxStyledTextCtrl_MoveCaretInsideView 3248
-#define wxStyledTextCtrl_LineLength 3249
-#define wxStyledTextCtrl_BraceHighlight 3250
-#define wxStyledTextCtrl_BraceBadLight 3251
-#define wxStyledTextCtrl_BraceMatch 3252
-#define wxStyledTextCtrl_GetViewEOL 3253
-#define wxStyledTextCtrl_SetViewEOL 3254
-#define wxStyledTextCtrl_SetModEventMask 3255
-#define wxStyledTextCtrl_GetEdgeColumn 3256
-#define wxStyledTextCtrl_SetEdgeColumn 3257
-#define wxStyledTextCtrl_GetEdgeMode 3258
-#define wxStyledTextCtrl_GetEdgeColour 3259
-#define wxStyledTextCtrl_SetEdgeColour 3260
-#define wxStyledTextCtrl_SearchAnchor 3261
-#define wxStyledTextCtrl_SearchNext 3262
-#define wxStyledTextCtrl_SearchPrev 3263
-#define wxStyledTextCtrl_LinesOnScreen 3264
-#define wxStyledTextCtrl_UsePopUp 3265
-#define wxStyledTextCtrl_SelectionIsRectangle 3266
-#define wxStyledTextCtrl_SetZoom 3267
-#define wxStyledTextCtrl_GetZoom 3268
-#define wxStyledTextCtrl_GetModEventMask 3269
-#define wxStyledTextCtrl_SetSTCFocus 3270
-#define wxStyledTextCtrl_GetSTCFocus 3271
-#define wxStyledTextCtrl_SetStatus 3272
-#define wxStyledTextCtrl_GetStatus 3273
-#define wxStyledTextCtrl_SetMouseDownCaptures 3274
-#define wxStyledTextCtrl_GetMouseDownCaptures 3275
-#define wxStyledTextCtrl_SetSTCCursor 3276
-#define wxStyledTextCtrl_GetSTCCursor 3277
-#define wxStyledTextCtrl_SetControlCharSymbol 3278
-#define wxStyledTextCtrl_GetControlCharSymbol 3279
-#define wxStyledTextCtrl_WordPartLeft 3280
-#define wxStyledTextCtrl_WordPartLeftExtend 3281
-#define wxStyledTextCtrl_WordPartRight 3282
-#define wxStyledTextCtrl_WordPartRightExtend 3283
-#define wxStyledTextCtrl_SetVisiblePolicy 3284
-#define wxStyledTextCtrl_DelLineLeft 3285
-#define wxStyledTextCtrl_DelLineRight 3286
-#define wxStyledTextCtrl_GetXOffset 3287
-#define wxStyledTextCtrl_ChooseCaretX 3288
-#define wxStyledTextCtrl_SetXCaretPolicy 3289
-#define wxStyledTextCtrl_SetYCaretPolicy 3290
-#define wxStyledTextCtrl_GetPrintWrapMode 3291
-#define wxStyledTextCtrl_SetHotspotActiveForeground 3292
-#define wxStyledTextCtrl_SetHotspotActiveBackground 3293
-#define wxStyledTextCtrl_SetHotspotActiveUnderline 3294
-#define wxStyledTextCtrl_SetHotspotSingleLine 3295
-#define wxStyledTextCtrl_ParaDownExtend 3296
-#define wxStyledTextCtrl_ParaUp 3297
-#define wxStyledTextCtrl_ParaUpExtend 3298
-#define wxStyledTextCtrl_PositionBefore 3299
-#define wxStyledTextCtrl_PositionAfter 3300
-#define wxStyledTextCtrl_CopyRange 3301
-#define wxStyledTextCtrl_CopyText 3302
-#define wxStyledTextCtrl_SetSelectionMode 3303
-#define wxStyledTextCtrl_GetSelectionMode 3304
-#define wxStyledTextCtrl_LineDownRectExtend 3305
-#define wxStyledTextCtrl_LineUpRectExtend 3306
-#define wxStyledTextCtrl_CharLeftRectExtend 3307
-#define wxStyledTextCtrl_CharRightRectExtend 3308
-#define wxStyledTextCtrl_HomeRectExtend 3309
-#define wxStyledTextCtrl_VCHomeRectExtend 3310
-#define wxStyledTextCtrl_LineEndRectExtend 3311
-#define wxStyledTextCtrl_PageUpRectExtend 3312
-#define wxStyledTextCtrl_PageDownRectExtend 3313
-#define wxStyledTextCtrl_StutteredPageUp 3314
-#define wxStyledTextCtrl_StutteredPageUpExtend 3315
-#define wxStyledTextCtrl_StutteredPageDown 3316
-#define wxStyledTextCtrl_StutteredPageDownExtend 3317
-#define wxStyledTextCtrl_WordLeftEnd 3318
-#define wxStyledTextCtrl_WordLeftEndExtend 3319
-#define wxStyledTextCtrl_WordRightEnd 3320
-#define wxStyledTextCtrl_WordRightEndExtend 3321
-#define wxStyledTextCtrl_SetWhitespaceChars 3322
-#define wxStyledTextCtrl_SetCharsDefault 3323
-#define wxStyledTextCtrl_AutoCompGetCurrent 3324
-#define wxStyledTextCtrl_Allocate 3325
-#define wxStyledTextCtrl_FindColumn 3326
-#define wxStyledTextCtrl_GetCaretSticky 3327
-#define wxStyledTextCtrl_SetCaretSticky 3328
-#define wxStyledTextCtrl_ToggleCaretSticky 3329
-#define wxStyledTextCtrl_SetPasteConvertEndings 3330
-#define wxStyledTextCtrl_GetPasteConvertEndings 3331
-#define wxStyledTextCtrl_SelectionDuplicate 3332
-#define wxStyledTextCtrl_SetCaretLineBackAlpha 3333
-#define wxStyledTextCtrl_GetCaretLineBackAlpha 3334
-#define wxStyledTextCtrl_StartRecord 3335
-#define wxStyledTextCtrl_StopRecord 3336
-#define wxStyledTextCtrl_SetLexer 3337
-#define wxStyledTextCtrl_GetLexer 3338
-#define wxStyledTextCtrl_Colourise 3339
-#define wxStyledTextCtrl_SetProperty 3340
-#define wxStyledTextCtrl_SetKeyWords 3341
-#define wxStyledTextCtrl_SetLexerLanguage 3342
-#define wxStyledTextCtrl_GetProperty 3343
-#define wxStyledTextCtrl_GetStyleBitsNeeded 3344
-#define wxStyledTextCtrl_GetCurrentLine 3345
-#define wxStyledTextCtrl_StyleSetSpec 3346
-#define wxStyledTextCtrl_StyleSetFont 3347
-#define wxStyledTextCtrl_StyleSetFontAttr 3348
-#define wxStyledTextCtrl_StyleSetCharacterSet 3349
-#define wxStyledTextCtrl_StyleSetFontEncoding 3350
-#define wxStyledTextCtrl_CmdKeyExecute 3351
-#define wxStyledTextCtrl_SetMargins 3352
-#define wxStyledTextCtrl_GetSelection 3353
-#define wxStyledTextCtrl_PointFromPosition 3354
-#define wxStyledTextCtrl_ScrollToLine 3355
-#define wxStyledTextCtrl_ScrollToColumn 3356
-#define wxStyledTextCtrl_SendMsg 3357
-#define wxStyledTextCtrl_SetVScrollBar 3358
-#define wxStyledTextCtrl_SetHScrollBar 3359
-#define wxStyledTextCtrl_GetLastKeydownProcessed 3360
-#define wxStyledTextCtrl_SetLastKeydownProcessed 3361
-#define wxStyledTextCtrl_SaveFile 3362
-#define wxStyledTextCtrl_LoadFile 3363
-#define wxStyledTextCtrl_DoDragOver 3364
-#define wxStyledTextCtrl_DoDropText 3365
-#define wxStyledTextCtrl_GetUseAntiAliasing 3366
-#define wxStyledTextCtrl_AddTextRaw 3367
-#define wxStyledTextCtrl_InsertTextRaw 3368
-#define wxStyledTextCtrl_GetCurLineRaw 3369
-#define wxStyledTextCtrl_GetLineRaw 3370
-#define wxStyledTextCtrl_GetSelectedTextRaw 3371
-#define wxStyledTextCtrl_GetTextRangeRaw 3372
-#define wxStyledTextCtrl_SetTextRaw 3373
-#define wxStyledTextCtrl_GetTextRaw 3374
-#define wxStyledTextCtrl_AppendTextRaw 3375
-#define wxArtProvider_GetBitmap 3376
-#define wxArtProvider_GetIcon 3377
-#define wxTreeEvent_GetKeyCode 3378
-#define wxTreeEvent_GetItem 3379
-#define wxTreeEvent_GetKeyEvent 3380
-#define wxTreeEvent_GetLabel 3381
-#define wxTreeEvent_GetOldItem 3382
-#define wxTreeEvent_GetPoint 3383
-#define wxTreeEvent_IsEditCancelled 3384
-#define wxTreeEvent_SetToolTip 3385
-#define wxNotebookEvent_GetOldSelection 3386
-#define wxNotebookEvent_GetSelection 3387
-#define wxNotebookEvent_SetOldSelection 3388
-#define wxNotebookEvent_SetSelection 3389
-#define wxFileDataObject_new 3390
-#define wxFileDataObject_AddFile 3391
-#define wxFileDataObject_GetFilenames 3392
-#define wxFileDataObject_destroy 3393
-#define wxTextDataObject_new 3394
-#define wxTextDataObject_GetTextLength 3395
-#define wxTextDataObject_GetText 3396
-#define wxTextDataObject_SetText 3397
-#define wxTextDataObject_destroy 3398
-#define wxBitmapDataObject_new_1_1 3399
-#define wxBitmapDataObject_new_1_0 3400
-#define wxBitmapDataObject_GetBitmap 3401
-#define wxBitmapDataObject_SetBitmap 3402
-#define wxBitmapDataObject_destroy 3403
-#define wxClipboard_new 3405
-#define wxClipboard_destruct 3406
-#define wxClipboard_AddData 3407
-#define wxClipboard_Clear 3408
-#define wxClipboard_Close 3409
-#define wxClipboard_Flush 3410
-#define wxClipboard_GetData 3411
-#define wxClipboard_IsOpened 3412
-#define wxClipboard_Open 3413
-#define wxClipboard_SetData 3414
-#define wxClipboard_UsePrimarySelection 3416
-#define wxClipboard_IsSupported 3417
-#define wxClipboard_Get 3418
-#define wxSpinEvent_GetPosition 3419
-#define wxSpinEvent_SetPosition 3420
-#define wxSplitterWindow_new_0 3421
-#define wxSplitterWindow_new_2 3422
-#define wxSplitterWindow_destruct 3423
-#define wxSplitterWindow_Create 3424
-#define wxSplitterWindow_GetMinimumPaneSize 3425
-#define wxSplitterWindow_GetSashGravity 3426
-#define wxSplitterWindow_GetSashPosition 3427
-#define wxSplitterWindow_GetSplitMode 3428
-#define wxSplitterWindow_GetWindow1 3429
-#define wxSplitterWindow_GetWindow2 3430
-#define wxSplitterWindow_Initialize 3431
-#define wxSplitterWindow_IsSplit 3432
-#define wxSplitterWindow_ReplaceWindow 3433
-#define wxSplitterWindow_SetSashGravity 3434
-#define wxSplitterWindow_SetSashPosition 3435
-#define wxSplitterWindow_SetSashSize 3436
-#define wxSplitterWindow_SetMinimumPaneSize 3437
-#define wxSplitterWindow_SetSplitMode 3438
-#define wxSplitterWindow_SplitHorizontally 3439
-#define wxSplitterWindow_SplitVertically 3440
-#define wxSplitterWindow_Unsplit 3441
-#define wxSplitterWindow_UpdateSize 3442
-#define wxSplitterEvent_GetSashPosition 3443
-#define wxSplitterEvent_GetX 3444
-#define wxSplitterEvent_GetY 3445
-#define wxSplitterEvent_GetWindowBeingRemoved 3446
-#define wxSplitterEvent_SetSashPosition 3447
-#define wxHtmlWindow_new_0 3448
-#define wxHtmlWindow_new_2 3449
-#define wxHtmlWindow_AppendToPage 3450
-#define wxHtmlWindow_GetOpenedAnchor 3451
-#define wxHtmlWindow_GetOpenedPage 3452
-#define wxHtmlWindow_GetOpenedPageTitle 3453
-#define wxHtmlWindow_GetRelatedFrame 3454
-#define wxHtmlWindow_HistoryBack 3455
-#define wxHtmlWindow_HistoryCanBack 3456
-#define wxHtmlWindow_HistoryCanForward 3457
-#define wxHtmlWindow_HistoryClear 3458
-#define wxHtmlWindow_HistoryForward 3459
-#define wxHtmlWindow_LoadFile 3460
-#define wxHtmlWindow_LoadPage 3461
-#define wxHtmlWindow_SelectAll 3462
-#define wxHtmlWindow_SelectionToText 3463
-#define wxHtmlWindow_SelectLine 3464
-#define wxHtmlWindow_SelectWord 3465
-#define wxHtmlWindow_SetBorders 3466
-#define wxHtmlWindow_SetFonts 3467
-#define wxHtmlWindow_SetPage 3468
-#define wxHtmlWindow_SetRelatedFrame 3469
-#define wxHtmlWindow_SetRelatedStatusBar 3470
-#define wxHtmlWindow_ToText 3471
-#define wxHtmlWindow_destroy 3472
-#define wxHtmlLinkEvent_GetLinkInfo 3473
-#define wxAuiNotebookEvent_SetSelection 3474
-#define wxAuiNotebookEvent_GetSelection 3475
-#define wxAuiNotebookEvent_SetOldSelection 3476
-#define wxAuiNotebookEvent_GetOldSelection 3477
-#define wxAuiNotebookEvent_SetDragSource 3478
-#define wxAuiNotebookEvent_GetDragSource 3479
-#define wxAuiManagerEvent_SetManager 3480
-#define wxAuiManagerEvent_GetManager 3481
-#define wxAuiManagerEvent_SetPane 3482
-#define wxAuiManagerEvent_GetPane 3483
-#define wxAuiManagerEvent_SetButton 3484
-#define wxAuiManagerEvent_GetButton 3485
-#define wxAuiManagerEvent_SetDC 3486
-#define wxAuiManagerEvent_GetDC 3487
-#define wxAuiManagerEvent_Veto 3488
-#define wxAuiManagerEvent_GetVeto 3489
-#define wxAuiManagerEvent_SetCanVeto 3490
-#define wxAuiManagerEvent_CanVeto 3491
-#define wxLogNull_new 3492
-#define wxLogNull_destroy 3493
+#define wxTreeCtrl_GetFirstChild 2018
+#define wxTreeCtrl_GetNextChild 2019
+#define wxTreeCtrl_GetFirstVisibleItem 2020
+#define wxTreeCtrl_GetImageList 2021
+#define wxTreeCtrl_GetIndent 2022
+#define wxTreeCtrl_GetItemBackgroundColour 2023
+#define wxTreeCtrl_GetItemData 2024
+#define wxTreeCtrl_GetItemFont 2025
+#define wxTreeCtrl_GetItemImage_1 2026
+#define wxTreeCtrl_GetItemImage_2 2027
+#define wxTreeCtrl_GetItemText 2028
+#define wxTreeCtrl_GetItemTextColour 2029
+#define wxTreeCtrl_GetLastChild 2030
+#define wxTreeCtrl_GetNextSibling 2031
+#define wxTreeCtrl_GetNextVisible 2032
+#define wxTreeCtrl_GetItemParent 2033
+#define wxTreeCtrl_GetPrevSibling 2034
+#define wxTreeCtrl_GetPrevVisible 2035
+#define wxTreeCtrl_GetRootItem 2036
+#define wxTreeCtrl_GetSelection 2037
+#define wxTreeCtrl_GetSelections 2038
+#define wxTreeCtrl_GetStateImageList 2039
+#define wxTreeCtrl_HitTest 2040
+#define wxTreeCtrl_InsertItem 2042
+#define wxTreeCtrl_IsBold 2043
+#define wxTreeCtrl_IsExpanded 2044
+#define wxTreeCtrl_IsSelected 2045
+#define wxTreeCtrl_IsVisible 2046
+#define wxTreeCtrl_ItemHasChildren 2047
+#define wxTreeCtrl_PrependItem 2048
+#define wxTreeCtrl_ScrollTo 2049
+#define wxTreeCtrl_SelectItem_1 2050
+#define wxTreeCtrl_SelectItem_2 2051
+#define wxTreeCtrl_SetIndent 2052
+#define wxTreeCtrl_SetImageList 2053
+#define wxTreeCtrl_SetItemBackgroundColour 2054
+#define wxTreeCtrl_SetItemBold 2055
+#define wxTreeCtrl_SetItemData 2056
+#define wxTreeCtrl_SetItemDropHighlight 2057
+#define wxTreeCtrl_SetItemFont 2058
+#define wxTreeCtrl_SetItemHasChildren 2059
+#define wxTreeCtrl_SetItemImage_2 2060
+#define wxTreeCtrl_SetItemImage_3 2061
+#define wxTreeCtrl_SetItemText 2062
+#define wxTreeCtrl_SetItemTextColour 2063
+#define wxTreeCtrl_SetStateImageList 2064
+#define wxTreeCtrl_SetWindowStyle 2065
+#define wxTreeCtrl_SortChildren 2066
+#define wxTreeCtrl_Toggle 2067
+#define wxTreeCtrl_ToggleItemSelection 2068
+#define wxTreeCtrl_Unselect 2069
+#define wxTreeCtrl_UnselectAll 2070
+#define wxTreeCtrl_UnselectItem 2071
+#define wxScrollBar_new_0 2072
+#define wxScrollBar_new_3 2073
+#define wxScrollBar_destruct 2074
+#define wxScrollBar_Create 2075
+#define wxScrollBar_GetRange 2076
+#define wxScrollBar_GetPageSize 2077
+#define wxScrollBar_GetThumbPosition 2078
+#define wxScrollBar_GetThumbSize 2079
+#define wxScrollBar_SetThumbPosition 2080
+#define wxScrollBar_SetScrollbar 2081
+#define wxSpinButton_new_2 2083
+#define wxSpinButton_new_0 2084
+#define wxSpinButton_Create 2085
+#define wxSpinButton_GetMax 2086
+#define wxSpinButton_GetMin 2087
+#define wxSpinButton_GetValue 2088
+#define wxSpinButton_SetRange 2089
+#define wxSpinButton_SetValue 2090
+#define wxSpinButton_destroy 2091
+#define wxSpinCtrl_new_0 2092
+#define wxSpinCtrl_new_2 2093
+#define wxSpinCtrl_Create 2095
+#define wxSpinCtrl_SetValue_1_1 2098
+#define wxSpinCtrl_SetValue_1_0 2099
+#define wxSpinCtrl_GetValue 2101
+#define wxSpinCtrl_SetRange 2103
+#define wxSpinCtrl_SetSelection 2104
+#define wxSpinCtrl_GetMin 2106
+#define wxSpinCtrl_GetMax 2108
+#define wxSpinCtrl_destroy 2109
+#define wxStaticText_new_0 2110
+#define wxStaticText_new_4 2111
+#define wxStaticText_Create 2112
+#define wxStaticText_GetLabel 2113
+#define wxStaticText_SetLabel 2114
+#define wxStaticText_Wrap 2115
+#define wxStaticText_destroy 2116
+#define wxStaticBitmap_new_0 2117
+#define wxStaticBitmap_new_4 2118
+#define wxStaticBitmap_Create 2119
+#define wxStaticBitmap_GetBitmap 2120
+#define wxStaticBitmap_SetBitmap 2121
+#define wxStaticBitmap_destroy 2122
+#define wxRadioBox_new 2123
+#define wxRadioBox_destruct 2125
+#define wxRadioBox_Create 2126
+#define wxRadioBox_Enable_2 2127
+#define wxRadioBox_Enable_1 2128
+#define wxRadioBox_GetSelection 2129
+#define wxRadioBox_GetString 2130
+#define wxRadioBox_SetSelection 2131
+#define wxRadioBox_Show_2 2132
+#define wxRadioBox_Show_1 2133
+#define wxRadioBox_GetColumnCount 2134
+#define wxRadioBox_GetItemHelpText 2135
+#define wxRadioBox_GetItemToolTip 2136
+#define wxRadioBox_GetItemFromPoint 2138
+#define wxRadioBox_GetRowCount 2139
+#define wxRadioBox_IsItemEnabled 2140
+#define wxRadioBox_IsItemShown 2141
+#define wxRadioBox_SetItemHelpText 2142
+#define wxRadioBox_SetItemToolTip 2143
+#define wxRadioButton_new_0 2144
+#define wxRadioButton_new_4 2145
+#define wxRadioButton_Create 2146
+#define wxRadioButton_GetValue 2147
+#define wxRadioButton_SetValue 2148
+#define wxRadioButton_destroy 2149
+#define wxSlider_new_6 2151
+#define wxSlider_new_0 2152
+#define wxSlider_Create 2153
+#define wxSlider_GetLineSize 2154
+#define wxSlider_GetMax 2155
+#define wxSlider_GetMin 2156
+#define wxSlider_GetPageSize 2157
+#define wxSlider_GetThumbLength 2158
+#define wxSlider_GetValue 2159
+#define wxSlider_SetLineSize 2160
+#define wxSlider_SetPageSize 2161
+#define wxSlider_SetRange 2162
+#define wxSlider_SetThumbLength 2163
+#define wxSlider_SetValue 2164
+#define wxSlider_destroy 2165
+#define wxDialog_new_4 2167
+#define wxDialog_new_0 2168
+#define wxDialog_destruct 2170
+#define wxDialog_Create 2171
+#define wxDialog_CreateButtonSizer 2172
+#define wxDialog_CreateStdDialogButtonSizer 2173
+#define wxDialog_EndModal 2174
+#define wxDialog_GetAffirmativeId 2175
+#define wxDialog_GetReturnCode 2176
+#define wxDialog_IsModal 2177
+#define wxDialog_SetAffirmativeId 2178
+#define wxDialog_SetReturnCode 2179
+#define wxDialog_Show 2180
+#define wxDialog_ShowModal 2181
+#define wxColourDialog_new_0 2182
+#define wxColourDialog_new_2 2183
+#define wxColourDialog_destruct 2184
+#define wxColourDialog_Create 2185
+#define wxColourDialog_GetColourData 2186
+#define wxColourData_new_0 2187
+#define wxColourData_new_1 2188
+#define wxColourData_destruct 2189
+#define wxColourData_GetChooseFull 2190
+#define wxColourData_GetColour 2191
+#define wxColourData_GetCustomColour 2193
+#define wxColourData_SetChooseFull 2194
+#define wxColourData_SetColour 2195
+#define wxColourData_SetCustomColour 2196
+#define wxPalette_new_0 2197
+#define wxPalette_new_4 2198
+#define wxPalette_destruct 2200
+#define wxPalette_Create 2201
+#define wxPalette_GetColoursCount 2202
+#define wxPalette_GetPixel 2203
+#define wxPalette_GetRGB 2204
+#define wxPalette_IsOk 2205
+#define wxDirDialog_new 2209
+#define wxDirDialog_destruct 2210
+#define wxDirDialog_GetPath 2211
+#define wxDirDialog_GetMessage 2212
+#define wxDirDialog_SetMessage 2213
+#define wxDirDialog_SetPath 2214
+#define wxFileDialog_new 2218
+#define wxFileDialog_destruct 2219
+#define wxFileDialog_GetDirectory 2220
+#define wxFileDialog_GetFilename 2221
+#define wxFileDialog_GetFilenames 2222
+#define wxFileDialog_GetFilterIndex 2223
+#define wxFileDialog_GetMessage 2224
+#define wxFileDialog_GetPath 2225
+#define wxFileDialog_GetPaths 2226
+#define wxFileDialog_GetWildcard 2227
+#define wxFileDialog_SetDirectory 2228
+#define wxFileDialog_SetFilename 2229
+#define wxFileDialog_SetFilterIndex 2230
+#define wxFileDialog_SetMessage 2231
+#define wxFileDialog_SetPath 2232
+#define wxFileDialog_SetWildcard 2233
+#define wxPickerBase_SetInternalMargin 2234
+#define wxPickerBase_GetInternalMargin 2235
+#define wxPickerBase_SetTextCtrlProportion 2236
+#define wxPickerBase_SetPickerCtrlProportion 2237
+#define wxPickerBase_GetTextCtrlProportion 2238
+#define wxPickerBase_GetPickerCtrlProportion 2239
+#define wxPickerBase_HasTextCtrl 2240
+#define wxPickerBase_GetTextCtrl 2241
+#define wxPickerBase_IsTextCtrlGrowable 2242
+#define wxPickerBase_SetPickerCtrlGrowable 2243
+#define wxPickerBase_SetTextCtrlGrowable 2244
+#define wxPickerBase_IsPickerCtrlGrowable 2245
+#define wxFilePickerCtrl_new_0 2246
+#define wxFilePickerCtrl_new_3 2247
+#define wxFilePickerCtrl_Create 2248
+#define wxFilePickerCtrl_GetPath 2249
+#define wxFilePickerCtrl_SetPath 2250
+#define wxFilePickerCtrl_destroy 2251
+#define wxDirPickerCtrl_new_0 2252
+#define wxDirPickerCtrl_new_3 2253
+#define wxDirPickerCtrl_Create 2254
+#define wxDirPickerCtrl_GetPath 2255
+#define wxDirPickerCtrl_SetPath 2256
+#define wxDirPickerCtrl_destroy 2257
+#define wxColourPickerCtrl_new_0 2258
+#define wxColourPickerCtrl_new_3 2259
+#define wxColourPickerCtrl_Create 2260
+#define wxColourPickerCtrl_GetColour 2261
+#define wxColourPickerCtrl_SetColour_1_1 2262
+#define wxColourPickerCtrl_SetColour_1_0 2263
+#define wxColourPickerCtrl_destroy 2264
+#define wxDatePickerCtrl_new_0 2265
+#define wxDatePickerCtrl_new_3 2266
+#define wxDatePickerCtrl_GetRange 2267
+#define wxDatePickerCtrl_GetValue 2268
+#define wxDatePickerCtrl_SetRange 2269
+#define wxDatePickerCtrl_SetValue 2270
+#define wxDatePickerCtrl_destroy 2271
+#define wxFontPickerCtrl_new_0 2272
+#define wxFontPickerCtrl_new_3 2273
+#define wxFontPickerCtrl_Create 2274
+#define wxFontPickerCtrl_GetSelectedFont 2275
+#define wxFontPickerCtrl_SetSelectedFont 2276
+#define wxFontPickerCtrl_GetMaxPointSize 2277
+#define wxFontPickerCtrl_SetMaxPointSize 2278
+#define wxFontPickerCtrl_destroy 2279
+#define wxFindReplaceDialog_new_0 2282
+#define wxFindReplaceDialog_new_4 2283
+#define wxFindReplaceDialog_destruct 2284
+#define wxFindReplaceDialog_Create 2285
+#define wxFindReplaceDialog_GetData 2286
+#define wxFindReplaceData_new_0 2287
+#define wxFindReplaceData_new_1 2288
+#define wxFindReplaceData_GetFindString 2289
+#define wxFindReplaceData_GetReplaceString 2290
+#define wxFindReplaceData_GetFlags 2291
+#define wxFindReplaceData_SetFlags 2292
+#define wxFindReplaceData_SetFindString 2293
+#define wxFindReplaceData_SetReplaceString 2294
+#define wxFindReplaceData_destroy 2295
+#define wxMultiChoiceDialog_new_0 2296
+#define wxMultiChoiceDialog_new_5 2298
+#define wxMultiChoiceDialog_GetSelections 2299
+#define wxMultiChoiceDialog_SetSelections 2300
+#define wxMultiChoiceDialog_destroy 2301
+#define wxSingleChoiceDialog_new_0 2302
+#define wxSingleChoiceDialog_new_5 2304
+#define wxSingleChoiceDialog_GetSelection 2305
+#define wxSingleChoiceDialog_GetStringSelection 2306
+#define wxSingleChoiceDialog_SetSelection 2307
+#define wxSingleChoiceDialog_destroy 2308
+#define wxTextEntryDialog_new 2309
+#define wxTextEntryDialog_GetValue 2310
+#define wxTextEntryDialog_SetValue 2311
+#define wxTextEntryDialog_destroy 2312
+#define wxPasswordEntryDialog_new 2313
+#define wxPasswordEntryDialog_destroy 2314
+#define wxFontData_new_0 2315
+#define wxFontData_new_1 2316
+#define wxFontData_destruct 2317
+#define wxFontData_EnableEffects 2318
+#define wxFontData_GetAllowSymbols 2319
+#define wxFontData_GetColour 2320
+#define wxFontData_GetChosenFont 2321
+#define wxFontData_GetEnableEffects 2322
+#define wxFontData_GetInitialFont 2323
+#define wxFontData_GetShowHelp 2324
+#define wxFontData_SetAllowSymbols 2325
+#define wxFontData_SetChosenFont 2326
+#define wxFontData_SetColour 2327
+#define wxFontData_SetInitialFont 2328
+#define wxFontData_SetRange 2329
+#define wxFontData_SetShowHelp 2330
+#define wxFontDialog_new_0 2334
+#define wxFontDialog_new_2 2336
+#define wxFontDialog_Create 2338
+#define wxFontDialog_GetFontData 2339
+#define wxFontDialog_destroy 2341
+#define wxProgressDialog_new 2342
+#define wxProgressDialog_destruct 2343
+#define wxProgressDialog_Resume 2344
+#define wxProgressDialog_Update_2 2345
+#define wxProgressDialog_Update_0 2346
+#define wxMessageDialog_new 2347
+#define wxMessageDialog_destruct 2348
+#define wxPageSetupDialog_new 2349
+#define wxPageSetupDialog_destruct 2350
+#define wxPageSetupDialog_GetPageSetupData 2351
+#define wxPageSetupDialog_ShowModal 2352
+#define wxPageSetupDialogData_new_0 2353
+#define wxPageSetupDialogData_new_1_0 2354
+#define wxPageSetupDialogData_new_1_1 2355
+#define wxPageSetupDialogData_destruct 2356
+#define wxPageSetupDialogData_EnableHelp 2357
+#define wxPageSetupDialogData_EnableMargins 2358
+#define wxPageSetupDialogData_EnableOrientation 2359
+#define wxPageSetupDialogData_EnablePaper 2360
+#define wxPageSetupDialogData_EnablePrinter 2361
+#define wxPageSetupDialogData_GetDefaultMinMargins 2362
+#define wxPageSetupDialogData_GetEnableMargins 2363
+#define wxPageSetupDialogData_GetEnableOrientation 2364
+#define wxPageSetupDialogData_GetEnablePaper 2365
+#define wxPageSetupDialogData_GetEnablePrinter 2366
+#define wxPageSetupDialogData_GetEnableHelp 2367
+#define wxPageSetupDialogData_GetDefaultInfo 2368
+#define wxPageSetupDialogData_GetMarginTopLeft 2369
+#define wxPageSetupDialogData_GetMarginBottomRight 2370
+#define wxPageSetupDialogData_GetMinMarginTopLeft 2371
+#define wxPageSetupDialogData_GetMinMarginBottomRight 2372
+#define wxPageSetupDialogData_GetPaperId 2373
+#define wxPageSetupDialogData_GetPaperSize 2374
+#define wxPageSetupDialogData_GetPrintData 2376
+#define wxPageSetupDialogData_IsOk 2377
+#define wxPageSetupDialogData_SetDefaultInfo 2378
+#define wxPageSetupDialogData_SetDefaultMinMargins 2379
+#define wxPageSetupDialogData_SetMarginTopLeft 2380
+#define wxPageSetupDialogData_SetMarginBottomRight 2381
+#define wxPageSetupDialogData_SetMinMarginTopLeft 2382
+#define wxPageSetupDialogData_SetMinMarginBottomRight 2383
+#define wxPageSetupDialogData_SetPaperId 2384
+#define wxPageSetupDialogData_SetPaperSize_1_1 2385
+#define wxPageSetupDialogData_SetPaperSize_1_0 2386
+#define wxPageSetupDialogData_SetPrintData 2387
+#define wxPrintDialog_new_2_0 2388
+#define wxPrintDialog_new_2_1 2389
+#define wxPrintDialog_destruct 2390
+#define wxPrintDialog_GetPrintDialogData 2391
+#define wxPrintDialog_GetPrintDC 2392
+#define wxPrintDialogData_new_0 2393
+#define wxPrintDialogData_new_1_1 2394
+#define wxPrintDialogData_new_1_0 2395
+#define wxPrintDialogData_destruct 2396
+#define wxPrintDialogData_EnableHelp 2397
+#define wxPrintDialogData_EnablePageNumbers 2398
+#define wxPrintDialogData_EnablePrintToFile 2399
+#define wxPrintDialogData_EnableSelection 2400
+#define wxPrintDialogData_GetAllPages 2401
+#define wxPrintDialogData_GetCollate 2402
+#define wxPrintDialogData_GetFromPage 2403
+#define wxPrintDialogData_GetMaxPage 2404
+#define wxPrintDialogData_GetMinPage 2405
+#define wxPrintDialogData_GetNoCopies 2406
+#define wxPrintDialogData_GetPrintData 2407
+#define wxPrintDialogData_GetPrintToFile 2408
+#define wxPrintDialogData_GetSelection 2409
+#define wxPrintDialogData_GetToPage 2410
+#define wxPrintDialogData_IsOk 2411
+#define wxPrintDialogData_SetCollate 2412
+#define wxPrintDialogData_SetFromPage 2413
+#define wxPrintDialogData_SetMaxPage 2414
+#define wxPrintDialogData_SetMinPage 2415
+#define wxPrintDialogData_SetNoCopies 2416
+#define wxPrintDialogData_SetPrintData 2417
+#define wxPrintDialogData_SetPrintToFile 2418
+#define wxPrintDialogData_SetSelection 2419
+#define wxPrintDialogData_SetToPage 2420
+#define wxPrintData_new_0 2421
+#define wxPrintData_new_1 2422
+#define wxPrintData_destruct 2423
+#define wxPrintData_GetCollate 2424
+#define wxPrintData_GetBin 2425
+#define wxPrintData_GetColour 2426
+#define wxPrintData_GetDuplex 2427
+#define wxPrintData_GetNoCopies 2428
+#define wxPrintData_GetOrientation 2429
+#define wxPrintData_GetPaperId 2430
+#define wxPrintData_GetPrinterName 2431
+#define wxPrintData_GetQuality 2432
+#define wxPrintData_IsOk 2433
+#define wxPrintData_SetBin 2434
+#define wxPrintData_SetCollate 2435
+#define wxPrintData_SetColour 2436
+#define wxPrintData_SetDuplex 2437
+#define wxPrintData_SetNoCopies 2438
+#define wxPrintData_SetOrientation 2439
+#define wxPrintData_SetPaperId 2440
+#define wxPrintData_SetPrinterName 2441
+#define wxPrintData_SetQuality 2442
+#define wxPrintPreview_new_2 2445
+#define wxPrintPreview_new_3 2446
+#define wxPrintPreview_destruct 2448
+#define wxPrintPreview_GetCanvas 2449
+#define wxPrintPreview_GetCurrentPage 2450
+#define wxPrintPreview_GetFrame 2451
+#define wxPrintPreview_GetMaxPage 2452
+#define wxPrintPreview_GetMinPage 2453
+#define wxPrintPreview_GetPrintout 2454
+#define wxPrintPreview_GetPrintoutForPrinting 2455
+#define wxPrintPreview_IsOk 2456
+#define wxPrintPreview_PaintPage 2457
+#define wxPrintPreview_Print 2458
+#define wxPrintPreview_RenderPage 2459
+#define wxPrintPreview_SetCanvas 2460
+#define wxPrintPreview_SetCurrentPage 2461
+#define wxPrintPreview_SetFrame 2462
+#define wxPrintPreview_SetPrintout 2463
+#define wxPrintPreview_SetZoom 2464
+#define wxPreviewFrame_new 2465
+#define wxPreviewFrame_destruct 2466
+#define wxPreviewFrame_CreateControlBar 2467
+#define wxPreviewFrame_CreateCanvas 2468
+#define wxPreviewFrame_Initialize 2469
+#define wxPreviewFrame_OnCloseWindow 2470
+#define wxPreviewControlBar_new 2471
+#define wxPreviewControlBar_destruct 2472
+#define wxPreviewControlBar_CreateButtons 2473
+#define wxPreviewControlBar_GetPrintPreview 2474
+#define wxPreviewControlBar_GetZoomControl 2475
+#define wxPreviewControlBar_SetZoomControl 2476
+#define wxPrinter_new 2478
+#define wxPrinter_CreateAbortWindow 2479
+#define wxPrinter_GetAbort 2480
+#define wxPrinter_GetLastError 2481
+#define wxPrinter_GetPrintDialogData 2482
+#define wxPrinter_Print 2483
+#define wxPrinter_PrintDialog 2484
+#define wxPrinter_ReportError 2485
+#define wxPrinter_Setup 2486
+#define wxPrinter_destroy 2487
+#define wxXmlResource_new_1 2488
+#define wxXmlResource_new_2 2489
+#define wxXmlResource_destruct 2490
+#define wxXmlResource_AttachUnknownControl 2491
+#define wxXmlResource_ClearHandlers 2492
+#define wxXmlResource_CompareVersion 2493
+#define wxXmlResource_Get 2494
+#define wxXmlResource_GetFlags 2495
+#define wxXmlResource_GetVersion 2496
+#define wxXmlResource_GetXRCID 2497
+#define wxXmlResource_InitAllHandlers 2498
+#define wxXmlResource_Load 2499
+#define wxXmlResource_LoadBitmap 2500
+#define wxXmlResource_LoadDialog_2 2501
+#define wxXmlResource_LoadDialog_3 2502
+#define wxXmlResource_LoadFrame_2 2503
+#define wxXmlResource_LoadFrame_3 2504
+#define wxXmlResource_LoadIcon 2505
+#define wxXmlResource_LoadMenu 2506
+#define wxXmlResource_LoadMenuBar_2 2507
+#define wxXmlResource_LoadMenuBar_1 2508
+#define wxXmlResource_LoadPanel_2 2509
+#define wxXmlResource_LoadPanel_3 2510
+#define wxXmlResource_LoadToolBar 2511
+#define wxXmlResource_Set 2512
+#define wxXmlResource_SetFlags 2513
+#define wxXmlResource_Unload 2514
+#define wxXmlResource_xrcctrl 2515
+#define wxHtmlEasyPrinting_new 2516
+#define wxHtmlEasyPrinting_destruct 2517
+#define wxHtmlEasyPrinting_GetPrintData 2518
+#define wxHtmlEasyPrinting_GetPageSetupData 2519
+#define wxHtmlEasyPrinting_PreviewFile 2520
+#define wxHtmlEasyPrinting_PreviewText 2521
+#define wxHtmlEasyPrinting_PrintFile 2522
+#define wxHtmlEasyPrinting_PrintText 2523
+#define wxHtmlEasyPrinting_PageSetup 2524
+#define wxHtmlEasyPrinting_SetFonts 2525
+#define wxHtmlEasyPrinting_SetHeader 2526
+#define wxHtmlEasyPrinting_SetFooter 2527
+#define wxGLCanvas_new_2 2529
+#define wxGLCanvas_new_3_1 2530
+#define wxGLCanvas_new_3_0 2531
+#define wxGLCanvas_GetContext 2532
+#define wxGLCanvas_SetCurrent 2534
+#define wxGLCanvas_SwapBuffers 2535
+#define wxGLCanvas_destroy 2536
+#define wxAuiManager_new 2537
+#define wxAuiManager_destruct 2538
+#define wxAuiManager_AddPane_2_1 2539
+#define wxAuiManager_AddPane_3 2540
+#define wxAuiManager_AddPane_2_0 2541
+#define wxAuiManager_DetachPane 2542
+#define wxAuiManager_GetAllPanes 2543
+#define wxAuiManager_GetArtProvider 2544
+#define wxAuiManager_GetDockSizeConstraint 2545
+#define wxAuiManager_GetFlags 2546
+#define wxAuiManager_GetManagedWindow 2547
+#define wxAuiManager_GetManager 2548
+#define wxAuiManager_GetPane_1_1 2549
+#define wxAuiManager_GetPane_1_0 2550
+#define wxAuiManager_HideHint 2551
+#define wxAuiManager_InsertPane 2552
+#define wxAuiManager_LoadPaneInfo 2553
+#define wxAuiManager_LoadPerspective 2554
+#define wxAuiManager_SavePaneInfo 2555
+#define wxAuiManager_SavePerspective 2556
+#define wxAuiManager_SetArtProvider 2557
+#define wxAuiManager_SetDockSizeConstraint 2558
+#define wxAuiManager_SetFlags 2559
+#define wxAuiManager_SetManagedWindow 2560
+#define wxAuiManager_ShowHint 2561
+#define wxAuiManager_UnInit 2562
+#define wxAuiManager_Update 2563
+#define wxAuiPaneInfo_new_0 2564
+#define wxAuiPaneInfo_new_1 2565
+#define wxAuiPaneInfo_destruct 2566
+#define wxAuiPaneInfo_BestSize_1 2567
+#define wxAuiPaneInfo_BestSize_2 2568
+#define wxAuiPaneInfo_Bottom 2569
+#define wxAuiPaneInfo_BottomDockable 2570
+#define wxAuiPaneInfo_Caption 2571
+#define wxAuiPaneInfo_CaptionVisible 2572
+#define wxAuiPaneInfo_Centre 2573
+#define wxAuiPaneInfo_CentrePane 2574
+#define wxAuiPaneInfo_CloseButton 2575
+#define wxAuiPaneInfo_DefaultPane 2576
+#define wxAuiPaneInfo_DestroyOnClose 2577
+#define wxAuiPaneInfo_Direction 2578
+#define wxAuiPaneInfo_Dock 2579
+#define wxAuiPaneInfo_Dockable 2580
+#define wxAuiPaneInfo_Fixed 2581
+#define wxAuiPaneInfo_Float 2582
+#define wxAuiPaneInfo_Floatable 2583
+#define wxAuiPaneInfo_FloatingPosition_1 2584
+#define wxAuiPaneInfo_FloatingPosition_2 2585
+#define wxAuiPaneInfo_FloatingSize_1 2586
+#define wxAuiPaneInfo_FloatingSize_2 2587
+#define wxAuiPaneInfo_Gripper 2588
+#define wxAuiPaneInfo_GripperTop 2589
+#define wxAuiPaneInfo_HasBorder 2590
+#define wxAuiPaneInfo_HasCaption 2591
+#define wxAuiPaneInfo_HasCloseButton 2592
+#define wxAuiPaneInfo_HasFlag 2593
+#define wxAuiPaneInfo_HasGripper 2594
+#define wxAuiPaneInfo_HasGripperTop 2595
+#define wxAuiPaneInfo_HasMaximizeButton 2596
+#define wxAuiPaneInfo_HasMinimizeButton 2597
+#define wxAuiPaneInfo_HasPinButton 2598
+#define wxAuiPaneInfo_Hide 2599
+#define wxAuiPaneInfo_IsBottomDockable 2600
+#define wxAuiPaneInfo_IsDocked 2601
+#define wxAuiPaneInfo_IsFixed 2602
+#define wxAuiPaneInfo_IsFloatable 2603
+#define wxAuiPaneInfo_IsFloating 2604
+#define wxAuiPaneInfo_IsLeftDockable 2605
+#define wxAuiPaneInfo_IsMovable 2606
+#define wxAuiPaneInfo_IsOk 2607
+#define wxAuiPaneInfo_IsResizable 2608
+#define wxAuiPaneInfo_IsRightDockable 2609
+#define wxAuiPaneInfo_IsShown 2610
+#define wxAuiPaneInfo_IsToolbar 2611
+#define wxAuiPaneInfo_IsTopDockable 2612
+#define wxAuiPaneInfo_Layer 2613
+#define wxAuiPaneInfo_Left 2614
+#define wxAuiPaneInfo_LeftDockable 2615
+#define wxAuiPaneInfo_MaxSize_1 2616
+#define wxAuiPaneInfo_MaxSize_2 2617
+#define wxAuiPaneInfo_MaximizeButton 2618
+#define wxAuiPaneInfo_MinSize_1 2619
+#define wxAuiPaneInfo_MinSize_2 2620
+#define wxAuiPaneInfo_MinimizeButton 2621
+#define wxAuiPaneInfo_Movable 2622
+#define wxAuiPaneInfo_Name 2623
+#define wxAuiPaneInfo_PaneBorder 2624
+#define wxAuiPaneInfo_PinButton 2625
+#define wxAuiPaneInfo_Position 2626
+#define wxAuiPaneInfo_Resizable 2627
+#define wxAuiPaneInfo_Right 2628
+#define wxAuiPaneInfo_RightDockable 2629
+#define wxAuiPaneInfo_Row 2630
+#define wxAuiPaneInfo_SafeSet 2631
+#define wxAuiPaneInfo_SetFlag 2632
+#define wxAuiPaneInfo_Show 2633
+#define wxAuiPaneInfo_ToolbarPane 2634
+#define wxAuiPaneInfo_Top 2635
+#define wxAuiPaneInfo_TopDockable 2636
+#define wxAuiPaneInfo_Window 2637
+#define wxAuiNotebook_new_0 2638
+#define wxAuiNotebook_new_2 2639
+#define wxAuiNotebook_AddPage 2640
+#define wxAuiNotebook_Create 2641
+#define wxAuiNotebook_DeletePage 2642
+#define wxAuiNotebook_GetArtProvider 2643
+#define wxAuiNotebook_GetPage 2644
+#define wxAuiNotebook_GetPageBitmap 2645
+#define wxAuiNotebook_GetPageCount 2646
+#define wxAuiNotebook_GetPageIndex 2647
+#define wxAuiNotebook_GetPageText 2648
+#define wxAuiNotebook_GetSelection 2649
+#define wxAuiNotebook_InsertPage 2650
+#define wxAuiNotebook_RemovePage 2651
+#define wxAuiNotebook_SetArtProvider 2652
+#define wxAuiNotebook_SetFont 2653
+#define wxAuiNotebook_SetPageBitmap 2654
+#define wxAuiNotebook_SetPageText 2655
+#define wxAuiNotebook_SetSelection 2656
+#define wxAuiNotebook_SetTabCtrlHeight 2657
+#define wxAuiNotebook_SetUniformBitmapSize 2658
+#define wxAuiNotebook_destroy 2659
+#define wxMDIParentFrame_new_0 2660
+#define wxMDIParentFrame_new_4 2661
+#define wxMDIParentFrame_destruct 2662
+#define wxMDIParentFrame_ActivateNext 2663
+#define wxMDIParentFrame_ActivatePrevious 2664
+#define wxMDIParentFrame_ArrangeIcons 2665
+#define wxMDIParentFrame_Cascade 2666
+#define wxMDIParentFrame_Create 2667
+#define wxMDIParentFrame_GetActiveChild 2668
+#define wxMDIParentFrame_GetClientWindow 2669
+#define wxMDIParentFrame_Tile 2670
+#define wxMDIChildFrame_new_0 2671
+#define wxMDIChildFrame_new_4 2672
+#define wxMDIChildFrame_destruct 2673
+#define wxMDIChildFrame_Activate 2674
+#define wxMDIChildFrame_Create 2675
+#define wxMDIChildFrame_Maximize 2676
+#define wxMDIChildFrame_Restore 2677
+#define wxMDIClientWindow_new_0 2678
+#define wxMDIClientWindow_new_2 2679
+#define wxMDIClientWindow_destruct 2680
+#define wxMDIClientWindow_CreateClient 2681
+#define wxLayoutAlgorithm_new 2682
+#define wxLayoutAlgorithm_LayoutFrame 2683
+#define wxLayoutAlgorithm_LayoutMDIFrame 2684
+#define wxLayoutAlgorithm_LayoutWindow 2685
+#define wxLayoutAlgorithm_destroy 2686
+#define wxEvent_GetId 2687
+#define wxEvent_GetSkipped 2688
+#define wxEvent_GetTimestamp 2689
+#define wxEvent_IsCommandEvent 2690
+#define wxEvent_ResumePropagation 2691
+#define wxEvent_ShouldPropagate 2692
+#define wxEvent_Skip 2693
+#define wxEvent_StopPropagation 2694
+#define wxCommandEvent_getClientData 2695
+#define wxCommandEvent_GetExtraLong 2696
+#define wxCommandEvent_GetInt 2697
+#define wxCommandEvent_GetSelection 2698
+#define wxCommandEvent_GetString 2699
+#define wxCommandEvent_IsChecked 2700
+#define wxCommandEvent_IsSelection 2701
+#define wxCommandEvent_SetInt 2702
+#define wxCommandEvent_SetString 2703
+#define wxScrollEvent_GetOrientation 2704
+#define wxScrollEvent_GetPosition 2705
+#define wxScrollWinEvent_GetOrientation 2706
+#define wxScrollWinEvent_GetPosition 2707
+#define wxMouseEvent_AltDown 2708
+#define wxMouseEvent_Button 2709
+#define wxMouseEvent_ButtonDClick 2710
+#define wxMouseEvent_ButtonDown 2711
+#define wxMouseEvent_ButtonUp 2712
+#define wxMouseEvent_CmdDown 2713
+#define wxMouseEvent_ControlDown 2714
+#define wxMouseEvent_Dragging 2715
+#define wxMouseEvent_Entering 2716
+#define wxMouseEvent_GetButton 2717
+#define wxMouseEvent_GetPosition 2720
+#define wxMouseEvent_GetLogicalPosition 2721
+#define wxMouseEvent_GetLinesPerAction 2722
+#define wxMouseEvent_GetWheelRotation 2723
+#define wxMouseEvent_GetWheelDelta 2724
+#define wxMouseEvent_GetX 2725
+#define wxMouseEvent_GetY 2726
+#define wxMouseEvent_IsButton 2727
+#define wxMouseEvent_IsPageScroll 2728
+#define wxMouseEvent_Leaving 2729
+#define wxMouseEvent_LeftDClick 2730
+#define wxMouseEvent_LeftDown 2731
+#define wxMouseEvent_LeftIsDown 2732
+#define wxMouseEvent_LeftUp 2733
+#define wxMouseEvent_MetaDown 2734
+#define wxMouseEvent_MiddleDClick 2735
+#define wxMouseEvent_MiddleDown 2736
+#define wxMouseEvent_MiddleIsDown 2737
+#define wxMouseEvent_MiddleUp 2738
+#define wxMouseEvent_Moving 2739
+#define wxMouseEvent_RightDClick 2740
+#define wxMouseEvent_RightDown 2741
+#define wxMouseEvent_RightIsDown 2742
+#define wxMouseEvent_RightUp 2743
+#define wxMouseEvent_ShiftDown 2744
+#define wxSetCursorEvent_GetCursor 2745
+#define wxSetCursorEvent_GetX 2746
+#define wxSetCursorEvent_GetY 2747
+#define wxSetCursorEvent_HasCursor 2748
+#define wxSetCursorEvent_SetCursor 2749
+#define wxKeyEvent_AltDown 2750
+#define wxKeyEvent_CmdDown 2751
+#define wxKeyEvent_ControlDown 2752
+#define wxKeyEvent_GetKeyCode 2753
+#define wxKeyEvent_GetModifiers 2754
+#define wxKeyEvent_GetPosition 2757
+#define wxKeyEvent_GetRawKeyCode 2758
+#define wxKeyEvent_GetRawKeyFlags 2759
+#define wxKeyEvent_GetUnicodeKey 2760
+#define wxKeyEvent_GetX 2761
+#define wxKeyEvent_GetY 2762
+#define wxKeyEvent_HasModifiers 2763
+#define wxKeyEvent_MetaDown 2764
+#define wxKeyEvent_ShiftDown 2765
+#define wxSizeEvent_GetSize 2766
+#define wxMoveEvent_GetPosition 2767
+#define wxEraseEvent_GetDC 2768
+#define wxFocusEvent_GetWindow 2769
+#define wxChildFocusEvent_GetWindow 2770
+#define wxMenuEvent_GetMenu 2771
+#define wxMenuEvent_GetMenuId 2772
+#define wxMenuEvent_IsPopup 2773
+#define wxCloseEvent_CanVeto 2774
+#define wxCloseEvent_GetLoggingOff 2775
+#define wxCloseEvent_SetCanVeto 2776
+#define wxCloseEvent_SetLoggingOff 2777
+#define wxCloseEvent_Veto 2778
+#define wxShowEvent_SetShow 2779
+#define wxShowEvent_GetShow 2780
+#define wxIconizeEvent_Iconized 2781
+#define wxJoystickEvent_ButtonDown 2782
+#define wxJoystickEvent_ButtonIsDown 2783
+#define wxJoystickEvent_ButtonUp 2784
+#define wxJoystickEvent_GetButtonChange 2785
+#define wxJoystickEvent_GetButtonState 2786
+#define wxJoystickEvent_GetJoystick 2787
+#define wxJoystickEvent_GetPosition 2788
+#define wxJoystickEvent_GetZPosition 2789
+#define wxJoystickEvent_IsButton 2790
+#define wxJoystickEvent_IsMove 2791
+#define wxJoystickEvent_IsZMove 2792
+#define wxUpdateUIEvent_CanUpdate 2793
+#define wxUpdateUIEvent_Check 2794
+#define wxUpdateUIEvent_Enable 2795
+#define wxUpdateUIEvent_Show 2796
+#define wxUpdateUIEvent_GetChecked 2797
+#define wxUpdateUIEvent_GetEnabled 2798
+#define wxUpdateUIEvent_GetShown 2799
+#define wxUpdateUIEvent_GetSetChecked 2800
+#define wxUpdateUIEvent_GetSetEnabled 2801
+#define wxUpdateUIEvent_GetSetShown 2802
+#define wxUpdateUIEvent_GetSetText 2803
+#define wxUpdateUIEvent_GetText 2804
+#define wxUpdateUIEvent_GetMode 2805
+#define wxUpdateUIEvent_GetUpdateInterval 2806
+#define wxUpdateUIEvent_ResetUpdateTime 2807
+#define wxUpdateUIEvent_SetMode 2808
+#define wxUpdateUIEvent_SetText 2809
+#define wxUpdateUIEvent_SetUpdateInterval 2810
+#define wxMouseCaptureChangedEvent_GetCapturedWindow 2811
+#define wxPaletteChangedEvent_SetChangedWindow 2812
+#define wxPaletteChangedEvent_GetChangedWindow 2813
+#define wxQueryNewPaletteEvent_SetPaletteRealized 2814
+#define wxQueryNewPaletteEvent_GetPaletteRealized 2815
+#define wxNavigationKeyEvent_GetDirection 2816
+#define wxNavigationKeyEvent_SetDirection 2817
+#define wxNavigationKeyEvent_IsWindowChange 2818
+#define wxNavigationKeyEvent_SetWindowChange 2819
+#define wxNavigationKeyEvent_IsFromTab 2820
+#define wxNavigationKeyEvent_SetFromTab 2821
+#define wxNavigationKeyEvent_GetCurrentFocus 2822
+#define wxNavigationKeyEvent_SetCurrentFocus 2823
+#define wxHelpEvent_GetOrigin 2824
+#define wxHelpEvent_GetPosition 2825
+#define wxHelpEvent_SetOrigin 2826
+#define wxHelpEvent_SetPosition 2827
+#define wxContextMenuEvent_GetPosition 2828
+#define wxContextMenuEvent_SetPosition 2829
+#define wxIdleEvent_CanSend 2830
+#define wxIdleEvent_GetMode 2831
+#define wxIdleEvent_RequestMore 2832
+#define wxIdleEvent_MoreRequested 2833
+#define wxIdleEvent_SetMode 2834
+#define wxGridEvent_AltDown 2835
+#define wxGridEvent_ControlDown 2836
+#define wxGridEvent_GetCol 2837
+#define wxGridEvent_GetPosition 2838
+#define wxGridEvent_GetRow 2839
+#define wxGridEvent_MetaDown 2840
+#define wxGridEvent_Selecting 2841
+#define wxGridEvent_ShiftDown 2842
+#define wxNotifyEvent_Allow 2843
+#define wxNotifyEvent_IsAllowed 2844
+#define wxNotifyEvent_Veto 2845
+#define wxSashEvent_GetEdge 2846
+#define wxSashEvent_GetDragRect 2847
+#define wxSashEvent_GetDragStatus 2848
+#define wxListEvent_GetCacheFrom 2849
+#define wxListEvent_GetCacheTo 2850
+#define wxListEvent_GetKeyCode 2851
+#define wxListEvent_GetIndex 2852
+#define wxListEvent_GetColumn 2853
+#define wxListEvent_GetPoint 2854
+#define wxListEvent_GetLabel 2855
+#define wxListEvent_GetText 2856
+#define wxListEvent_GetImage 2857
+#define wxListEvent_GetData 2858
+#define wxListEvent_GetMask 2859
+#define wxListEvent_GetItem 2860
+#define wxListEvent_IsEditCancelled 2861
+#define wxDateEvent_GetDate 2862
+#define wxCalendarEvent_GetWeekDay 2863
+#define wxFileDirPickerEvent_GetPath 2864
+#define wxColourPickerEvent_GetColour 2865
+#define wxFontPickerEvent_GetFont 2866
+#define wxStyledTextEvent_GetPosition 2867
+#define wxStyledTextEvent_GetKey 2868
+#define wxStyledTextEvent_GetModifiers 2869
+#define wxStyledTextEvent_GetModificationType 2870
+#define wxStyledTextEvent_GetText 2871
+#define wxStyledTextEvent_GetLength 2872
+#define wxStyledTextEvent_GetLinesAdded 2873
+#define wxStyledTextEvent_GetLine 2874
+#define wxStyledTextEvent_GetFoldLevelNow 2875
+#define wxStyledTextEvent_GetFoldLevelPrev 2876
+#define wxStyledTextEvent_GetMargin 2877
+#define wxStyledTextEvent_GetMessage 2878
+#define wxStyledTextEvent_GetWParam 2879
+#define wxStyledTextEvent_GetLParam 2880
+#define wxStyledTextEvent_GetListType 2881
+#define wxStyledTextEvent_GetX 2882
+#define wxStyledTextEvent_GetY 2883
+#define wxStyledTextEvent_GetDragText 2884
+#define wxStyledTextEvent_GetDragAllowMove 2885
+#define wxStyledTextEvent_GetDragResult 2886
+#define wxStyledTextEvent_GetShift 2887
+#define wxStyledTextEvent_GetControl 2888
+#define wxStyledTextEvent_GetAlt 2889
+#define utils_wxGetKeyState 2890
+#define utils_wxGetMousePosition 2891
+#define utils_wxGetMouseState 2892
+#define utils_wxSetDetectableAutoRepeat 2893
+#define utils_wxBell 2894
+#define utils_wxFindMenuItemId 2895
+#define utils_wxGenericFindWindowAtPoint 2896
+#define utils_wxFindWindowAtPoint 2897
+#define utils_wxBeginBusyCursor 2898
+#define utils_wxEndBusyCursor 2899
+#define utils_wxIsBusy 2900
+#define utils_wxShutdown 2901
+#define utils_wxShell 2902
+#define utils_wxLaunchDefaultBrowser 2903
+#define utils_wxGetEmailAddress 2904
+#define utils_wxGetUserId 2905
+#define utils_wxGetHomeDir 2906
+#define utils_wxNewId 2907
+#define utils_wxRegisterId 2908
+#define utils_wxGetCurrentId 2909
+#define utils_wxGetOsDescription 2910
+#define utils_wxIsPlatformLittleEndian 2911
+#define utils_wxIsPlatform64Bit 2912
+#define wxPrintout_new 2913
+#define wxPrintout_destruct 2914
+#define wxPrintout_GetDC 2915
+#define wxPrintout_GetPageSizeMM 2916
+#define wxPrintout_GetPageSizePixels 2917
+#define wxPrintout_GetPaperRectPixels 2918
+#define wxPrintout_GetPPIPrinter 2919
+#define wxPrintout_GetPPIScreen 2920
+#define wxPrintout_GetTitle 2921
+#define wxPrintout_IsPreview 2922
+#define wxPrintout_FitThisSizeToPaper 2923
+#define wxPrintout_FitThisSizeToPage 2924
+#define wxPrintout_FitThisSizeToPageMargins 2925
+#define wxPrintout_MapScreenSizeToPaper 2926
+#define wxPrintout_MapScreenSizeToPage 2927
+#define wxPrintout_MapScreenSizeToPageMargins 2928
+#define wxPrintout_MapScreenSizeToDevice 2929
+#define wxPrintout_GetLogicalPaperRect 2930
+#define wxPrintout_GetLogicalPageRect 2931
+#define wxPrintout_GetLogicalPageMarginsRect 2932
+#define wxPrintout_SetLogicalOrigin 2933
+#define wxPrintout_OffsetLogicalOrigin 2934
+#define wxStyledTextCtrl_new_2 2935
+#define wxStyledTextCtrl_new_0 2936
+#define wxStyledTextCtrl_destruct 2937
+#define wxStyledTextCtrl_Create 2938
+#define wxStyledTextCtrl_AddText 2939
+#define wxStyledTextCtrl_AddStyledText 2940
+#define wxStyledTextCtrl_InsertText 2941
+#define wxStyledTextCtrl_ClearAll 2942
+#define wxStyledTextCtrl_ClearDocumentStyle 2943
+#define wxStyledTextCtrl_GetLength 2944
+#define wxStyledTextCtrl_GetCharAt 2945
+#define wxStyledTextCtrl_GetCurrentPos 2946
+#define wxStyledTextCtrl_GetAnchor 2947
+#define wxStyledTextCtrl_GetStyleAt 2948
+#define wxStyledTextCtrl_Redo 2949
+#define wxStyledTextCtrl_SetUndoCollection 2950
+#define wxStyledTextCtrl_SelectAll 2951
+#define wxStyledTextCtrl_SetSavePoint 2952
+#define wxStyledTextCtrl_GetStyledText 2953
+#define wxStyledTextCtrl_CanRedo 2954
+#define wxStyledTextCtrl_MarkerLineFromHandle 2955
+#define wxStyledTextCtrl_MarkerDeleteHandle 2956
+#define wxStyledTextCtrl_GetUndoCollection 2957
+#define wxStyledTextCtrl_GetViewWhiteSpace 2958
+#define wxStyledTextCtrl_SetViewWhiteSpace 2959
+#define wxStyledTextCtrl_PositionFromPoint 2960
+#define wxStyledTextCtrl_PositionFromPointClose 2961
+#define wxStyledTextCtrl_GotoLine 2962
+#define wxStyledTextCtrl_GotoPos 2963
+#define wxStyledTextCtrl_SetAnchor 2964
+#define wxStyledTextCtrl_GetCurLine 2965
+#define wxStyledTextCtrl_GetEndStyled 2966
+#define wxStyledTextCtrl_ConvertEOLs 2967
+#define wxStyledTextCtrl_GetEOLMode 2968
+#define wxStyledTextCtrl_SetEOLMode 2969
+#define wxStyledTextCtrl_StartStyling 2970
+#define wxStyledTextCtrl_SetStyling 2971
+#define wxStyledTextCtrl_GetBufferedDraw 2972
+#define wxStyledTextCtrl_SetBufferedDraw 2973
+#define wxStyledTextCtrl_SetTabWidth 2974
+#define wxStyledTextCtrl_GetTabWidth 2975
+#define wxStyledTextCtrl_SetCodePage 2976
+#define wxStyledTextCtrl_MarkerDefine 2977
+#define wxStyledTextCtrl_MarkerSetForeground 2978
+#define wxStyledTextCtrl_MarkerSetBackground 2979
+#define wxStyledTextCtrl_MarkerAdd 2980
+#define wxStyledTextCtrl_MarkerDelete 2981
+#define wxStyledTextCtrl_MarkerDeleteAll 2982
+#define wxStyledTextCtrl_MarkerGet 2983
+#define wxStyledTextCtrl_MarkerNext 2984
+#define wxStyledTextCtrl_MarkerPrevious 2985
+#define wxStyledTextCtrl_MarkerDefineBitmap 2986
+#define wxStyledTextCtrl_MarkerAddSet 2987
+#define wxStyledTextCtrl_MarkerSetAlpha 2988
+#define wxStyledTextCtrl_SetMarginType 2989
+#define wxStyledTextCtrl_GetMarginType 2990
+#define wxStyledTextCtrl_SetMarginWidth 2991
+#define wxStyledTextCtrl_GetMarginWidth 2992
+#define wxStyledTextCtrl_SetMarginMask 2993
+#define wxStyledTextCtrl_GetMarginMask 2994
+#define wxStyledTextCtrl_SetMarginSensitive 2995
+#define wxStyledTextCtrl_GetMarginSensitive 2996
+#define wxStyledTextCtrl_StyleClearAll 2997
+#define wxStyledTextCtrl_StyleSetForeground 2998
+#define wxStyledTextCtrl_StyleSetBackground 2999
+#define wxStyledTextCtrl_StyleSetBold 3000
+#define wxStyledTextCtrl_StyleSetItalic 3001
+#define wxStyledTextCtrl_StyleSetSize 3002
+#define wxStyledTextCtrl_StyleSetFaceName 3003
+#define wxStyledTextCtrl_StyleSetEOLFilled 3004
+#define wxStyledTextCtrl_StyleResetDefault 3005
+#define wxStyledTextCtrl_StyleSetUnderline 3006
+#define wxStyledTextCtrl_StyleSetCase 3007
+#define wxStyledTextCtrl_StyleSetHotSpot 3008
+#define wxStyledTextCtrl_SetSelForeground 3009
+#define wxStyledTextCtrl_SetSelBackground 3010
+#define wxStyledTextCtrl_GetSelAlpha 3011
+#define wxStyledTextCtrl_SetSelAlpha 3012
+#define wxStyledTextCtrl_SetCaretForeground 3013
+#define wxStyledTextCtrl_CmdKeyAssign 3014
+#define wxStyledTextCtrl_CmdKeyClear 3015
+#define wxStyledTextCtrl_CmdKeyClearAll 3016
+#define wxStyledTextCtrl_SetStyleBytes 3017
+#define wxStyledTextCtrl_StyleSetVisible 3018
+#define wxStyledTextCtrl_GetCaretPeriod 3019
+#define wxStyledTextCtrl_SetCaretPeriod 3020
+#define wxStyledTextCtrl_SetWordChars 3021
+#define wxStyledTextCtrl_BeginUndoAction 3022
+#define wxStyledTextCtrl_EndUndoAction 3023
+#define wxStyledTextCtrl_IndicatorSetStyle 3024
+#define wxStyledTextCtrl_IndicatorGetStyle 3025
+#define wxStyledTextCtrl_IndicatorSetForeground 3026
+#define wxStyledTextCtrl_IndicatorGetForeground 3027
+#define wxStyledTextCtrl_SetWhitespaceForeground 3028
+#define wxStyledTextCtrl_SetWhitespaceBackground 3029
+#define wxStyledTextCtrl_GetStyleBits 3030
+#define wxStyledTextCtrl_SetLineState 3031
+#define wxStyledTextCtrl_GetLineState 3032
+#define wxStyledTextCtrl_GetMaxLineState 3033
+#define wxStyledTextCtrl_GetCaretLineVisible 3034
+#define wxStyledTextCtrl_SetCaretLineVisible 3035
+#define wxStyledTextCtrl_GetCaretLineBackground 3036
+#define wxStyledTextCtrl_SetCaretLineBackground 3037
+#define wxStyledTextCtrl_AutoCompShow 3038
+#define wxStyledTextCtrl_AutoCompCancel 3039
+#define wxStyledTextCtrl_AutoCompActive 3040
+#define wxStyledTextCtrl_AutoCompPosStart 3041
+#define wxStyledTextCtrl_AutoCompComplete 3042
+#define wxStyledTextCtrl_AutoCompStops 3043
+#define wxStyledTextCtrl_AutoCompSetSeparator 3044
+#define wxStyledTextCtrl_AutoCompGetSeparator 3045
+#define wxStyledTextCtrl_AutoCompSelect 3046
+#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3047
+#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3048
+#define wxStyledTextCtrl_AutoCompSetFillUps 3049
+#define wxStyledTextCtrl_AutoCompSetChooseSingle 3050
+#define wxStyledTextCtrl_AutoCompGetChooseSingle 3051
+#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3052
+#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3053
+#define wxStyledTextCtrl_UserListShow 3054
+#define wxStyledTextCtrl_AutoCompSetAutoHide 3055
+#define wxStyledTextCtrl_AutoCompGetAutoHide 3056
+#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3057
+#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3058
+#define wxStyledTextCtrl_RegisterImage 3059
+#define wxStyledTextCtrl_ClearRegisteredImages 3060
+#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3061
+#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3062
+#define wxStyledTextCtrl_AutoCompSetMaxWidth 3063
+#define wxStyledTextCtrl_AutoCompGetMaxWidth 3064
+#define wxStyledTextCtrl_AutoCompSetMaxHeight 3065
+#define wxStyledTextCtrl_AutoCompGetMaxHeight 3066
+#define wxStyledTextCtrl_SetIndent 3067
+#define wxStyledTextCtrl_GetIndent 3068
+#define wxStyledTextCtrl_SetUseTabs 3069
+#define wxStyledTextCtrl_GetUseTabs 3070
+#define wxStyledTextCtrl_SetLineIndentation 3071
+#define wxStyledTextCtrl_GetLineIndentation 3072
+#define wxStyledTextCtrl_GetLineIndentPosition 3073
+#define wxStyledTextCtrl_GetColumn 3074
+#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3075
+#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3076
+#define wxStyledTextCtrl_SetIndentationGuides 3077
+#define wxStyledTextCtrl_GetIndentationGuides 3078
+#define wxStyledTextCtrl_SetHighlightGuide 3079
+#define wxStyledTextCtrl_GetHighlightGuide 3080
+#define wxStyledTextCtrl_GetLineEndPosition 3081
+#define wxStyledTextCtrl_GetCodePage 3082
+#define wxStyledTextCtrl_GetCaretForeground 3083
+#define wxStyledTextCtrl_GetReadOnly 3084
+#define wxStyledTextCtrl_SetCurrentPos 3085
+#define wxStyledTextCtrl_SetSelectionStart 3086
+#define wxStyledTextCtrl_GetSelectionStart 3087
+#define wxStyledTextCtrl_SetSelectionEnd 3088
+#define wxStyledTextCtrl_GetSelectionEnd 3089
+#define wxStyledTextCtrl_SetPrintMagnification 3090
+#define wxStyledTextCtrl_GetPrintMagnification 3091
+#define wxStyledTextCtrl_SetPrintColourMode 3092
+#define wxStyledTextCtrl_GetPrintColourMode 3093
+#define wxStyledTextCtrl_FindText 3094
+#define wxStyledTextCtrl_FormatRange 3095
+#define wxStyledTextCtrl_GetFirstVisibleLine 3096
+#define wxStyledTextCtrl_GetLine 3097
+#define wxStyledTextCtrl_GetLineCount 3098
+#define wxStyledTextCtrl_SetMarginLeft 3099
+#define wxStyledTextCtrl_GetMarginLeft 3100
+#define wxStyledTextCtrl_SetMarginRight 3101
+#define wxStyledTextCtrl_GetMarginRight 3102
+#define wxStyledTextCtrl_GetModify 3103
+#define wxStyledTextCtrl_SetSelection 3104
+#define wxStyledTextCtrl_GetSelectedText 3105
+#define wxStyledTextCtrl_GetTextRange 3106
+#define wxStyledTextCtrl_HideSelection 3107
+#define wxStyledTextCtrl_LineFromPosition 3108
+#define wxStyledTextCtrl_PositionFromLine 3109
+#define wxStyledTextCtrl_LineScroll 3110
+#define wxStyledTextCtrl_EnsureCaretVisible 3111
+#define wxStyledTextCtrl_ReplaceSelection 3112
+#define wxStyledTextCtrl_SetReadOnly 3113
+#define wxStyledTextCtrl_CanPaste 3114
+#define wxStyledTextCtrl_CanUndo 3115
+#define wxStyledTextCtrl_EmptyUndoBuffer 3116
+#define wxStyledTextCtrl_Undo 3117
+#define wxStyledTextCtrl_Cut 3118
+#define wxStyledTextCtrl_Copy 3119
+#define wxStyledTextCtrl_Paste 3120
+#define wxStyledTextCtrl_Clear 3121
+#define wxStyledTextCtrl_SetText 3122
+#define wxStyledTextCtrl_GetText 3123
+#define wxStyledTextCtrl_GetTextLength 3124
+#define wxStyledTextCtrl_GetOvertype 3125
+#define wxStyledTextCtrl_SetCaretWidth 3126
+#define wxStyledTextCtrl_GetCaretWidth 3127
+#define wxStyledTextCtrl_SetTargetStart 3128
+#define wxStyledTextCtrl_GetTargetStart 3129
+#define wxStyledTextCtrl_SetTargetEnd 3130
+#define wxStyledTextCtrl_GetTargetEnd 3131
+#define wxStyledTextCtrl_ReplaceTarget 3132
+#define wxStyledTextCtrl_SearchInTarget 3133
+#define wxStyledTextCtrl_SetSearchFlags 3134
+#define wxStyledTextCtrl_GetSearchFlags 3135
+#define wxStyledTextCtrl_CallTipShow 3136
+#define wxStyledTextCtrl_CallTipCancel 3137
+#define wxStyledTextCtrl_CallTipActive 3138
+#define wxStyledTextCtrl_CallTipPosAtStart 3139
+#define wxStyledTextCtrl_CallTipSetHighlight 3140
+#define wxStyledTextCtrl_CallTipSetBackground 3141
+#define wxStyledTextCtrl_CallTipSetForeground 3142
+#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3143
+#define wxStyledTextCtrl_CallTipUseStyle 3144
+#define wxStyledTextCtrl_VisibleFromDocLine 3145
+#define wxStyledTextCtrl_DocLineFromVisible 3146
+#define wxStyledTextCtrl_WrapCount 3147
+#define wxStyledTextCtrl_SetFoldLevel 3148
+#define wxStyledTextCtrl_GetFoldLevel 3149
+#define wxStyledTextCtrl_GetLastChild 3150
+#define wxStyledTextCtrl_GetFoldParent 3151
+#define wxStyledTextCtrl_ShowLines 3152
+#define wxStyledTextCtrl_HideLines 3153
+#define wxStyledTextCtrl_GetLineVisible 3154
+#define wxStyledTextCtrl_SetFoldExpanded 3155
+#define wxStyledTextCtrl_GetFoldExpanded 3156
+#define wxStyledTextCtrl_ToggleFold 3157
+#define wxStyledTextCtrl_EnsureVisible 3158
+#define wxStyledTextCtrl_SetFoldFlags 3159
+#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3160
+#define wxStyledTextCtrl_SetTabIndents 3161
+#define wxStyledTextCtrl_GetTabIndents 3162
+#define wxStyledTextCtrl_SetBackSpaceUnIndents 3163
+#define wxStyledTextCtrl_GetBackSpaceUnIndents 3164
+#define wxStyledTextCtrl_SetMouseDwellTime 3165
+#define wxStyledTextCtrl_GetMouseDwellTime 3166
+#define wxStyledTextCtrl_WordStartPosition 3167
+#define wxStyledTextCtrl_WordEndPosition 3168
+#define wxStyledTextCtrl_SetWrapMode 3169
+#define wxStyledTextCtrl_GetWrapMode 3170
+#define wxStyledTextCtrl_SetWrapVisualFlags 3171
+#define wxStyledTextCtrl_GetWrapVisualFlags 3172
+#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3173
+#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3174
+#define wxStyledTextCtrl_SetWrapStartIndent 3175
+#define wxStyledTextCtrl_GetWrapStartIndent 3176
+#define wxStyledTextCtrl_SetLayoutCache 3177
+#define wxStyledTextCtrl_GetLayoutCache 3178
+#define wxStyledTextCtrl_SetScrollWidth 3179
+#define wxStyledTextCtrl_GetScrollWidth 3180
+#define wxStyledTextCtrl_TextWidth 3181
+#define wxStyledTextCtrl_GetEndAtLastLine 3182
+#define wxStyledTextCtrl_TextHeight 3183
+#define wxStyledTextCtrl_SetUseVerticalScrollBar 3184
+#define wxStyledTextCtrl_GetUseVerticalScrollBar 3185
+#define wxStyledTextCtrl_AppendText 3186
+#define wxStyledTextCtrl_GetTwoPhaseDraw 3187
+#define wxStyledTextCtrl_SetTwoPhaseDraw 3188
+#define wxStyledTextCtrl_TargetFromSelection 3189
+#define wxStyledTextCtrl_LinesJoin 3190
+#define wxStyledTextCtrl_LinesSplit 3191
+#define wxStyledTextCtrl_SetFoldMarginColour 3192
+#define wxStyledTextCtrl_SetFoldMarginHiColour 3193
+#define wxStyledTextCtrl_LineDown 3194
+#define wxStyledTextCtrl_LineDownExtend 3195
+#define wxStyledTextCtrl_LineUp 3196
+#define wxStyledTextCtrl_LineUpExtend 3197
+#define wxStyledTextCtrl_CharLeft 3198
+#define wxStyledTextCtrl_CharLeftExtend 3199
+#define wxStyledTextCtrl_CharRight 3200
+#define wxStyledTextCtrl_CharRightExtend 3201
+#define wxStyledTextCtrl_WordLeft 3202
+#define wxStyledTextCtrl_WordLeftExtend 3203
+#define wxStyledTextCtrl_WordRight 3204
+#define wxStyledTextCtrl_WordRightExtend 3205
+#define wxStyledTextCtrl_Home 3206
+#define wxStyledTextCtrl_HomeExtend 3207
+#define wxStyledTextCtrl_LineEnd 3208
+#define wxStyledTextCtrl_LineEndExtend 3209
+#define wxStyledTextCtrl_DocumentStart 3210
+#define wxStyledTextCtrl_DocumentStartExtend 3211
+#define wxStyledTextCtrl_DocumentEnd 3212
+#define wxStyledTextCtrl_DocumentEndExtend 3213
+#define wxStyledTextCtrl_PageUp 3214
+#define wxStyledTextCtrl_PageUpExtend 3215
+#define wxStyledTextCtrl_PageDown 3216
+#define wxStyledTextCtrl_PageDownExtend 3217
+#define wxStyledTextCtrl_EditToggleOvertype 3218
+#define wxStyledTextCtrl_Cancel 3219
+#define wxStyledTextCtrl_DeleteBack 3220
+#define wxStyledTextCtrl_Tab 3221
+#define wxStyledTextCtrl_BackTab 3222
+#define wxStyledTextCtrl_NewLine 3223
+#define wxStyledTextCtrl_FormFeed 3224
+#define wxStyledTextCtrl_VCHome 3225
+#define wxStyledTextCtrl_VCHomeExtend 3226
+#define wxStyledTextCtrl_ZoomIn 3227
+#define wxStyledTextCtrl_ZoomOut 3228
+#define wxStyledTextCtrl_DelWordLeft 3229
+#define wxStyledTextCtrl_DelWordRight 3230
+#define wxStyledTextCtrl_LineCut 3231
+#define wxStyledTextCtrl_LineDelete 3232
+#define wxStyledTextCtrl_LineTranspose 3233
+#define wxStyledTextCtrl_LineDuplicate 3234
+#define wxStyledTextCtrl_LowerCase 3235
+#define wxStyledTextCtrl_UpperCase 3236
+#define wxStyledTextCtrl_LineScrollDown 3237
+#define wxStyledTextCtrl_LineScrollUp 3238
+#define wxStyledTextCtrl_DeleteBackNotLine 3239
+#define wxStyledTextCtrl_HomeDisplay 3240
+#define wxStyledTextCtrl_HomeDisplayExtend 3241
+#define wxStyledTextCtrl_LineEndDisplay 3242
+#define wxStyledTextCtrl_LineEndDisplayExtend 3243
+#define wxStyledTextCtrl_HomeWrapExtend 3244
+#define wxStyledTextCtrl_LineEndWrap 3245
+#define wxStyledTextCtrl_LineEndWrapExtend 3246
+#define wxStyledTextCtrl_VCHomeWrap 3247
+#define wxStyledTextCtrl_VCHomeWrapExtend 3248
+#define wxStyledTextCtrl_LineCopy 3249
+#define wxStyledTextCtrl_MoveCaretInsideView 3250
+#define wxStyledTextCtrl_LineLength 3251
+#define wxStyledTextCtrl_BraceHighlight 3252
+#define wxStyledTextCtrl_BraceBadLight 3253
+#define wxStyledTextCtrl_BraceMatch 3254
+#define wxStyledTextCtrl_GetViewEOL 3255
+#define wxStyledTextCtrl_SetViewEOL 3256
+#define wxStyledTextCtrl_SetModEventMask 3257
+#define wxStyledTextCtrl_GetEdgeColumn 3258
+#define wxStyledTextCtrl_SetEdgeColumn 3259
+#define wxStyledTextCtrl_GetEdgeMode 3260
+#define wxStyledTextCtrl_GetEdgeColour 3261
+#define wxStyledTextCtrl_SetEdgeColour 3262
+#define wxStyledTextCtrl_SearchAnchor 3263
+#define wxStyledTextCtrl_SearchNext 3264
+#define wxStyledTextCtrl_SearchPrev 3265
+#define wxStyledTextCtrl_LinesOnScreen 3266
+#define wxStyledTextCtrl_UsePopUp 3267
+#define wxStyledTextCtrl_SelectionIsRectangle 3268
+#define wxStyledTextCtrl_SetZoom 3269
+#define wxStyledTextCtrl_GetZoom 3270
+#define wxStyledTextCtrl_GetModEventMask 3271
+#define wxStyledTextCtrl_SetSTCFocus 3272
+#define wxStyledTextCtrl_GetSTCFocus 3273
+#define wxStyledTextCtrl_SetStatus 3274
+#define wxStyledTextCtrl_GetStatus 3275
+#define wxStyledTextCtrl_SetMouseDownCaptures 3276
+#define wxStyledTextCtrl_GetMouseDownCaptures 3277
+#define wxStyledTextCtrl_SetSTCCursor 3278
+#define wxStyledTextCtrl_GetSTCCursor 3279
+#define wxStyledTextCtrl_SetControlCharSymbol 3280
+#define wxStyledTextCtrl_GetControlCharSymbol 3281
+#define wxStyledTextCtrl_WordPartLeft 3282
+#define wxStyledTextCtrl_WordPartLeftExtend 3283
+#define wxStyledTextCtrl_WordPartRight 3284
+#define wxStyledTextCtrl_WordPartRightExtend 3285
+#define wxStyledTextCtrl_SetVisiblePolicy 3286
+#define wxStyledTextCtrl_DelLineLeft 3287
+#define wxStyledTextCtrl_DelLineRight 3288
+#define wxStyledTextCtrl_GetXOffset 3289
+#define wxStyledTextCtrl_ChooseCaretX 3290
+#define wxStyledTextCtrl_SetXCaretPolicy 3291
+#define wxStyledTextCtrl_SetYCaretPolicy 3292
+#define wxStyledTextCtrl_GetPrintWrapMode 3293
+#define wxStyledTextCtrl_SetHotspotActiveForeground 3294
+#define wxStyledTextCtrl_SetHotspotActiveBackground 3295
+#define wxStyledTextCtrl_SetHotspotActiveUnderline 3296
+#define wxStyledTextCtrl_SetHotspotSingleLine 3297
+#define wxStyledTextCtrl_ParaDownExtend 3298
+#define wxStyledTextCtrl_ParaUp 3299
+#define wxStyledTextCtrl_ParaUpExtend 3300
+#define wxStyledTextCtrl_PositionBefore 3301
+#define wxStyledTextCtrl_PositionAfter 3302
+#define wxStyledTextCtrl_CopyRange 3303
+#define wxStyledTextCtrl_CopyText 3304
+#define wxStyledTextCtrl_SetSelectionMode 3305
+#define wxStyledTextCtrl_GetSelectionMode 3306
+#define wxStyledTextCtrl_LineDownRectExtend 3307
+#define wxStyledTextCtrl_LineUpRectExtend 3308
+#define wxStyledTextCtrl_CharLeftRectExtend 3309
+#define wxStyledTextCtrl_CharRightRectExtend 3310
+#define wxStyledTextCtrl_HomeRectExtend 3311
+#define wxStyledTextCtrl_VCHomeRectExtend 3312
+#define wxStyledTextCtrl_LineEndRectExtend 3313
+#define wxStyledTextCtrl_PageUpRectExtend 3314
+#define wxStyledTextCtrl_PageDownRectExtend 3315
+#define wxStyledTextCtrl_StutteredPageUp 3316
+#define wxStyledTextCtrl_StutteredPageUpExtend 3317
+#define wxStyledTextCtrl_StutteredPageDown 3318
+#define wxStyledTextCtrl_StutteredPageDownExtend 3319
+#define wxStyledTextCtrl_WordLeftEnd 3320
+#define wxStyledTextCtrl_WordLeftEndExtend 3321
+#define wxStyledTextCtrl_WordRightEnd 3322
+#define wxStyledTextCtrl_WordRightEndExtend 3323
+#define wxStyledTextCtrl_SetWhitespaceChars 3324
+#define wxStyledTextCtrl_SetCharsDefault 3325
+#define wxStyledTextCtrl_AutoCompGetCurrent 3326
+#define wxStyledTextCtrl_Allocate 3327
+#define wxStyledTextCtrl_FindColumn 3328
+#define wxStyledTextCtrl_GetCaretSticky 3329
+#define wxStyledTextCtrl_SetCaretSticky 3330
+#define wxStyledTextCtrl_ToggleCaretSticky 3331
+#define wxStyledTextCtrl_SetPasteConvertEndings 3332
+#define wxStyledTextCtrl_GetPasteConvertEndings 3333
+#define wxStyledTextCtrl_SelectionDuplicate 3334
+#define wxStyledTextCtrl_SetCaretLineBackAlpha 3335
+#define wxStyledTextCtrl_GetCaretLineBackAlpha 3336
+#define wxStyledTextCtrl_StartRecord 3337
+#define wxStyledTextCtrl_StopRecord 3338
+#define wxStyledTextCtrl_SetLexer 3339
+#define wxStyledTextCtrl_GetLexer 3340
+#define wxStyledTextCtrl_Colourise 3341
+#define wxStyledTextCtrl_SetProperty 3342
+#define wxStyledTextCtrl_SetKeyWords 3343
+#define wxStyledTextCtrl_SetLexerLanguage 3344
+#define wxStyledTextCtrl_GetProperty 3345
+#define wxStyledTextCtrl_GetStyleBitsNeeded 3346
+#define wxStyledTextCtrl_GetCurrentLine 3347
+#define wxStyledTextCtrl_StyleSetSpec 3348
+#define wxStyledTextCtrl_StyleSetFont 3349
+#define wxStyledTextCtrl_StyleSetFontAttr 3350
+#define wxStyledTextCtrl_StyleSetCharacterSet 3351
+#define wxStyledTextCtrl_StyleSetFontEncoding 3352
+#define wxStyledTextCtrl_CmdKeyExecute 3353
+#define wxStyledTextCtrl_SetMargins 3354
+#define wxStyledTextCtrl_GetSelection 3355
+#define wxStyledTextCtrl_PointFromPosition 3356
+#define wxStyledTextCtrl_ScrollToLine 3357
+#define wxStyledTextCtrl_ScrollToColumn 3358
+#define wxStyledTextCtrl_SendMsg 3359
+#define wxStyledTextCtrl_SetVScrollBar 3360
+#define wxStyledTextCtrl_SetHScrollBar 3361
+#define wxStyledTextCtrl_GetLastKeydownProcessed 3362
+#define wxStyledTextCtrl_SetLastKeydownProcessed 3363
+#define wxStyledTextCtrl_SaveFile 3364
+#define wxStyledTextCtrl_LoadFile 3365
+#define wxStyledTextCtrl_DoDragOver 3366
+#define wxStyledTextCtrl_DoDropText 3367
+#define wxStyledTextCtrl_GetUseAntiAliasing 3368
+#define wxStyledTextCtrl_AddTextRaw 3369
+#define wxStyledTextCtrl_InsertTextRaw 3370
+#define wxStyledTextCtrl_GetCurLineRaw 3371
+#define wxStyledTextCtrl_GetLineRaw 3372
+#define wxStyledTextCtrl_GetSelectedTextRaw 3373
+#define wxStyledTextCtrl_GetTextRangeRaw 3374
+#define wxStyledTextCtrl_SetTextRaw 3375
+#define wxStyledTextCtrl_GetTextRaw 3376
+#define wxStyledTextCtrl_AppendTextRaw 3377
+#define wxArtProvider_GetBitmap 3378
+#define wxArtProvider_GetIcon 3379
+#define wxTreeEvent_GetKeyCode 3380
+#define wxTreeEvent_GetItem 3381
+#define wxTreeEvent_GetKeyEvent 3382
+#define wxTreeEvent_GetLabel 3383
+#define wxTreeEvent_GetOldItem 3384
+#define wxTreeEvent_GetPoint 3385
+#define wxTreeEvent_IsEditCancelled 3386
+#define wxTreeEvent_SetToolTip 3387
+#define wxNotebookEvent_GetOldSelection 3388
+#define wxNotebookEvent_GetSelection 3389
+#define wxNotebookEvent_SetOldSelection 3390
+#define wxNotebookEvent_SetSelection 3391
+#define wxFileDataObject_new 3392
+#define wxFileDataObject_AddFile 3393
+#define wxFileDataObject_GetFilenames 3394
+#define wxFileDataObject_destroy 3395
+#define wxTextDataObject_new 3396
+#define wxTextDataObject_GetTextLength 3397
+#define wxTextDataObject_GetText 3398
+#define wxTextDataObject_SetText 3399
+#define wxTextDataObject_destroy 3400
+#define wxBitmapDataObject_new_1_1 3401
+#define wxBitmapDataObject_new_1_0 3402
+#define wxBitmapDataObject_GetBitmap 3403
+#define wxBitmapDataObject_SetBitmap 3404
+#define wxBitmapDataObject_destroy 3405
+#define wxClipboard_new 3407
+#define wxClipboard_destruct 3408
+#define wxClipboard_AddData 3409
+#define wxClipboard_Clear 3410
+#define wxClipboard_Close 3411
+#define wxClipboard_Flush 3412
+#define wxClipboard_GetData 3413
+#define wxClipboard_IsOpened 3414
+#define wxClipboard_Open 3415
+#define wxClipboard_SetData 3416
+#define wxClipboard_UsePrimarySelection 3418
+#define wxClipboard_IsSupported 3419
+#define wxClipboard_Get 3420
+#define wxSpinEvent_GetPosition 3421
+#define wxSpinEvent_SetPosition 3422
+#define wxSplitterWindow_new_0 3423
+#define wxSplitterWindow_new_2 3424
+#define wxSplitterWindow_destruct 3425
+#define wxSplitterWindow_Create 3426
+#define wxSplitterWindow_GetMinimumPaneSize 3427
+#define wxSplitterWindow_GetSashGravity 3428
+#define wxSplitterWindow_GetSashPosition 3429
+#define wxSplitterWindow_GetSplitMode 3430
+#define wxSplitterWindow_GetWindow1 3431
+#define wxSplitterWindow_GetWindow2 3432
+#define wxSplitterWindow_Initialize 3433
+#define wxSplitterWindow_IsSplit 3434
+#define wxSplitterWindow_ReplaceWindow 3435
+#define wxSplitterWindow_SetSashGravity 3436
+#define wxSplitterWindow_SetSashPosition 3437
+#define wxSplitterWindow_SetSashSize 3438
+#define wxSplitterWindow_SetMinimumPaneSize 3439
+#define wxSplitterWindow_SetSplitMode 3440
+#define wxSplitterWindow_SplitHorizontally 3441
+#define wxSplitterWindow_SplitVertically 3442
+#define wxSplitterWindow_Unsplit 3443
+#define wxSplitterWindow_UpdateSize 3444
+#define wxSplitterEvent_GetSashPosition 3445
+#define wxSplitterEvent_GetX 3446
+#define wxSplitterEvent_GetY 3447
+#define wxSplitterEvent_GetWindowBeingRemoved 3448
+#define wxSplitterEvent_SetSashPosition 3449
+#define wxHtmlWindow_new_0 3450
+#define wxHtmlWindow_new_2 3451
+#define wxHtmlWindow_AppendToPage 3452
+#define wxHtmlWindow_GetOpenedAnchor 3453
+#define wxHtmlWindow_GetOpenedPage 3454
+#define wxHtmlWindow_GetOpenedPageTitle 3455
+#define wxHtmlWindow_GetRelatedFrame 3456
+#define wxHtmlWindow_HistoryBack 3457
+#define wxHtmlWindow_HistoryCanBack 3458
+#define wxHtmlWindow_HistoryCanForward 3459
+#define wxHtmlWindow_HistoryClear 3460
+#define wxHtmlWindow_HistoryForward 3461
+#define wxHtmlWindow_LoadFile 3462
+#define wxHtmlWindow_LoadPage 3463
+#define wxHtmlWindow_SelectAll 3464
+#define wxHtmlWindow_SelectionToText 3465
+#define wxHtmlWindow_SelectLine 3466
+#define wxHtmlWindow_SelectWord 3467
+#define wxHtmlWindow_SetBorders 3468
+#define wxHtmlWindow_SetFonts 3469
+#define wxHtmlWindow_SetPage 3470
+#define wxHtmlWindow_SetRelatedFrame 3471
+#define wxHtmlWindow_SetRelatedStatusBar 3472
+#define wxHtmlWindow_ToText 3473
+#define wxHtmlWindow_destroy 3474
+#define wxHtmlLinkEvent_GetLinkInfo 3475
+#define wxAuiNotebookEvent_SetSelection 3476
+#define wxAuiNotebookEvent_GetSelection 3477
+#define wxAuiNotebookEvent_SetOldSelection 3478
+#define wxAuiNotebookEvent_GetOldSelection 3479
+#define wxAuiNotebookEvent_SetDragSource 3480
+#define wxAuiNotebookEvent_GetDragSource 3481
+#define wxAuiManagerEvent_SetManager 3482
+#define wxAuiManagerEvent_GetManager 3483
+#define wxAuiManagerEvent_SetPane 3484
+#define wxAuiManagerEvent_GetPane 3485
+#define wxAuiManagerEvent_SetButton 3486
+#define wxAuiManagerEvent_GetButton 3487
+#define wxAuiManagerEvent_SetDC 3488
+#define wxAuiManagerEvent_GetDC 3489
+#define wxAuiManagerEvent_Veto 3490
+#define wxAuiManagerEvent_GetVeto 3491
+#define wxAuiManagerEvent_SetCanVeto 3492
+#define wxAuiManagerEvent_CanVeto 3493
+#define wxLogNull_new 3494
+#define wxLogNull_destroy 3495
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
index d115bb2243..4486dff63b 100644
--- a/lib/wx/c_src/wxe_impl.cpp
+++ b/lib/wx/c_src/wxe_impl.cpp
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -615,28 +615,33 @@ int WxeApp::getRef(void * ptr, wxeMemEnv *memenv) {
ptrMap::iterator it = ptr2ref.find(ptr);
if(it != ptr2ref.end()) {
wxeRefData *refd = it->second;
- return refd->ref;
- } else { // New Ptr
- int ref;
- intList free = memenv->free;
-
- if(free.IsEmpty()) {
- ref = memenv->next++;
- } else {
- ref = free.Pop();
- };
- if(ref >= memenv->max) {
- memenv->max *= 2;
- memenv->ref2ptr =
- (void **) driver_realloc(memenv->ref2ptr,memenv->max * sizeof(void*));
- }
+ if(refd->memenv == memenv) {
+ // Found it return
+ return refd->ref;
+ } // else
+ // Old reference to deleted object, release old and recreate in current memenv.
+ clearPtr(ptr);
+ }
+ int ref;
+ intList free = memenv->free;
- memenv->ref2ptr[ref] = ptr;
- ptr2ref[ptr] = new wxeRefData(ref, 0, false, memenv);
- return ref;
+ if(free.IsEmpty()) {
+ ref = memenv->next++;
+ } else {
+ ref = free.Pop();
+ };
+ if(ref >= memenv->max) {
+ memenv->max *= 2;
+ memenv->ref2ptr =
+ (void **) driver_realloc(memenv->ref2ptr,memenv->max * sizeof(void*));
}
+
+ memenv->ref2ptr[ref] = ptr;
+ ptr2ref[ptr] = new wxeRefData(ref, 0, false, memenv);
+ return ref;
}
+
void WxeApp::clearPtr(void * ptr) {
ptrMap::iterator it;
it = ptr2ref.find(ptr);
@@ -697,13 +702,15 @@ void WxeApp::clearPtr(void * ptr) {
void * WxeApp::getPtr(char * bp, wxeMemEnv *memenv) {
int index = *(int *) bp;
- if(!memenv)
+ if(!memenv) {
throw wxe_badarg(index);
+ }
void * temp = memenv->ref2ptr[index];
if((index < memenv->next) && ((index == 0) || (temp > NULL)))
return temp;
- else
+ else {
throw wxe_badarg(index);
+ }
}
void WxeApp::registerPid(char * bp, ErlDrvTermData pid, wxeMemEnv * memenv) {
diff --git a/lib/wx/c_src/wxe_return.cpp b/lib/wx/c_src/wxe_return.cpp
index 8a00d6f4c6..2c4f7541e7 100644
--- a/lib/wx/c_src/wxe_return.cpp
+++ b/lib/wx/c_src/wxe_return.cpp
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -219,7 +219,7 @@ void wxeReturn::add(wxArrayInt val) {
INLINE
void wxeReturn::add(wxUIntPtr *val) {
- addInt((ErlDrvTermData)val); // TODO is this right?
+ add(ERL_DRV_UINT, (ErlDrvTermData) val);
}
INLINE
diff --git a/lib/wx/doc/src/Makefile b/lib/wx/doc/src/Makefile
index fd9f7441a3..c8eb6174c4 100644
--- a/lib/wx/doc/src/Makefile
+++ b/lib/wx/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2008-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2008-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -82,7 +82,6 @@ XML_FILES = \
$(XML_PART_FILES) $(XML_REF3_FILES) \
$(XML_NOTES_FILES) $(XML_APPLICATION_FILES)
-
# ----------------------------------------------------
INFO_FILE = ../../info
@@ -130,12 +129,13 @@ ref_man.xml: ref_man.xml.src
@echo
$(ErlMods:%.erl=%.xml):
- docb_gen -def vsn $(VSN) -sort_functions false ../../src/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -sort_functions false ../../src/$(@:%.xml=%.erl)
+
$(GenMods:%.erl=%.xml):
- docb_gen -def vsn $(VSN) -sort_functions false ../../src/gen/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -sort_functions false ../../src/gen/$(@:%.xml=%.erl)
$(XML_CHAPTER_FILES):
- docb_gen -chapter -def vsn $(VSN) ../overview.edoc
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -chapter ../overview.edoc
debug opt:
diff --git a/lib/wx/include/gl.hrl b/lib/wx/include/gl.hrl
index 7891ebf568..2fa0d72a59 100644
--- a/lib/wx/include/gl.hrl
+++ b/lib/wx/include/gl.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% OPENGL DEFINITIONS
diff --git a/lib/wx/include/glu.hrl b/lib/wx/include/glu.hrl
index 27985aa8f7..a2ab55d054 100644
--- a/lib/wx/include/glu.hrl
+++ b/lib/wx/include/glu.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% GLU DEFINITIONS
diff --git a/lib/wx/include/wx.hrl b/lib/wx/include/wx.hrl
index b22f7e34b8..f5824196b0 100644
--- a/lib/wx/include/wx.hrl
+++ b/lib/wx/include/wx.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
@@ -261,7 +261,7 @@
%% Callback event: {@link wxColourPickerEvent}
-record(wxColourPicker,{type, colour}).
-%% @type wxTree() = #wxTree{type=wxEventType(),item=wxTreeItemId(),itemOld=wxTreeItemId(),pointDrag={X::integer(),Y::integer()}}.
+%% @type wxTree() = #wxTree{type=wxEventType(),item=integer(),itemOld=integer(),pointDrag={X::integer(),Y::integer()}}.
%% <dl><dt>EventType:</dt> <dd><em>command_tree_begin_drag</em>, <em>command_tree_begin_rdrag</em>, <em>command_tree_begin_label_edit</em>, <em>command_tree_end_label_edit</em>, <em>command_tree_delete_item</em>, <em>command_tree_get_info</em>, <em>command_tree_set_info</em>, <em>command_tree_item_expanded</em>, <em>command_tree_item_expanding</em>, <em>command_tree_item_collapsed</em>, <em>command_tree_item_collapsing</em>, <em>command_tree_sel_changed</em>, <em>command_tree_sel_changing</em>, <em>command_tree_key_down</em>, <em>command_tree_item_activated</em>, <em>command_tree_item_right_click</em>, <em>command_tree_item_middle_click</em>, <em>command_tree_end_drag</em>, <em>command_tree_state_image_click</em>, <em>command_tree_item_gettooltip</em>, <em>command_tree_item_menu</em></dd></dl>
%% Callback event: {@link wxTreeEvent}
-record(wxTree,{type, item,itemOld,pointDrag}).
diff --git a/lib/wx/src/gen/gl.erl b/lib/wx/src/gen/gl.erl
index 8220acad98..d789f1b72f 100644
--- a/lib/wx/src/gen/gl.erl
+++ b/lib/wx/src/gen/gl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% OPENGL API
diff --git a/lib/wx/src/gen/gl_debug.hrl b/lib/wx/src/gen/gl_debug.hrl
index 8c25d94590..68225197cf 100644
--- a/lib/wx/src/gen/gl_debug.hrl
+++ b/lib/wx/src/gen/gl_debug.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/glu.erl b/lib/wx/src/gen/glu.erl
index 9a06be4077..ae4bac4e06 100644
--- a/lib/wx/src/gen/glu.erl
+++ b/lib/wx/src/gen/glu.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% OPENGL UTILITY API
diff --git a/lib/wx/src/gen/wxAcceleratorEntry.erl b/lib/wx/src/gen/wxAcceleratorEntry.erl
index 4c6d35829c..c7256a80db 100644
--- a/lib/wx/src/gen/wxAcceleratorEntry.erl
+++ b/lib/wx/src/gen/wxAcceleratorEntry.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAcceleratorTable.erl b/lib/wx/src/gen/wxAcceleratorTable.erl
index f4f7f55f70..9fe5e4ee51 100644
--- a/lib/wx/src/gen/wxAcceleratorTable.erl
+++ b/lib/wx/src/gen/wxAcceleratorTable.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxArtProvider.erl b/lib/wx/src/gen/wxArtProvider.erl
index 4708f0844b..7a45b0d79d 100644
--- a/lib/wx/src/gen/wxArtProvider.erl
+++ b/lib/wx/src/gen/wxArtProvider.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiDockArt.erl b/lib/wx/src/gen/wxAuiDockArt.erl
index 9997e69dfd..f2be643dd9 100644
--- a/lib/wx/src/gen/wxAuiDockArt.erl
+++ b/lib/wx/src/gen/wxAuiDockArt.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiManager.erl b/lib/wx/src/gen/wxAuiManager.erl
index 7f46a36991..5d19ca5f58 100644
--- a/lib/wx/src/gen/wxAuiManager.erl
+++ b/lib/wx/src/gen/wxAuiManager.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiManagerEvent.erl b/lib/wx/src/gen/wxAuiManagerEvent.erl
index c15eeb4ad6..c348f2abdb 100644
--- a/lib/wx/src/gen/wxAuiManagerEvent.erl
+++ b/lib/wx/src/gen/wxAuiManagerEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiNotebook.erl b/lib/wx/src/gen/wxAuiNotebook.erl
index abd2cf618b..67596ed082 100644
--- a/lib/wx/src/gen/wxAuiNotebook.erl
+++ b/lib/wx/src/gen/wxAuiNotebook.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiNotebookEvent.erl b/lib/wx/src/gen/wxAuiNotebookEvent.erl
index 763d7092f2..6257ff3602 100644
--- a/lib/wx/src/gen/wxAuiNotebookEvent.erl
+++ b/lib/wx/src/gen/wxAuiNotebookEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiPaneInfo.erl b/lib/wx/src/gen/wxAuiPaneInfo.erl
index 1683045a90..8f699452cf 100644
--- a/lib/wx/src/gen/wxAuiPaneInfo.erl
+++ b/lib/wx/src/gen/wxAuiPaneInfo.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiTabArt.erl b/lib/wx/src/gen/wxAuiTabArt.erl
index 354ab611d0..725bac9664 100644
--- a/lib/wx/src/gen/wxAuiTabArt.erl
+++ b/lib/wx/src/gen/wxAuiTabArt.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBitmap.erl b/lib/wx/src/gen/wxBitmap.erl
index 930d87198c..0b5a216a35 100644
--- a/lib/wx/src/gen/wxBitmap.erl
+++ b/lib/wx/src/gen/wxBitmap.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBitmapButton.erl b/lib/wx/src/gen/wxBitmapButton.erl
index 78d43d4918..a06b77e47b 100644
--- a/lib/wx/src/gen/wxBitmapButton.erl
+++ b/lib/wx/src/gen/wxBitmapButton.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBitmapDataObject.erl b/lib/wx/src/gen/wxBitmapDataObject.erl
index 7c7f6a20b0..31a896bf82 100644
--- a/lib/wx/src/gen/wxBitmapDataObject.erl
+++ b/lib/wx/src/gen/wxBitmapDataObject.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBoxSizer.erl b/lib/wx/src/gen/wxBoxSizer.erl
index 3599cd11b6..30f56b37c1 100644
--- a/lib/wx/src/gen/wxBoxSizer.erl
+++ b/lib/wx/src/gen/wxBoxSizer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBrush.erl b/lib/wx/src/gen/wxBrush.erl
index 2a5f184ce6..0d8a99fa3e 100644
--- a/lib/wx/src/gen/wxBrush.erl
+++ b/lib/wx/src/gen/wxBrush.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBufferedDC.erl b/lib/wx/src/gen/wxBufferedDC.erl
index b99822040d..25d3fb41dc 100644
--- a/lib/wx/src/gen/wxBufferedDC.erl
+++ b/lib/wx/src/gen/wxBufferedDC.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBufferedPaintDC.erl b/lib/wx/src/gen/wxBufferedPaintDC.erl
index 5674712055..805d69ce2c 100644
--- a/lib/wx/src/gen/wxBufferedPaintDC.erl
+++ b/lib/wx/src/gen/wxBufferedPaintDC.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxButton.erl b/lib/wx/src/gen/wxButton.erl
index 261a961063..9fee37139a 100644
--- a/lib/wx/src/gen/wxButton.erl
+++ b/lib/wx/src/gen/wxButton.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCalendarCtrl.erl b/lib/wx/src/gen/wxCalendarCtrl.erl
index 5b87ac54e4..bea52dd332 100644
--- a/lib/wx/src/gen/wxCalendarCtrl.erl
+++ b/lib/wx/src/gen/wxCalendarCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCalendarDateAttr.erl b/lib/wx/src/gen/wxCalendarDateAttr.erl
index 197e0eb996..e0f6cd5f73 100644
--- a/lib/wx/src/gen/wxCalendarDateAttr.erl
+++ b/lib/wx/src/gen/wxCalendarDateAttr.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCalendarEvent.erl b/lib/wx/src/gen/wxCalendarEvent.erl
index de51d20cae..4fa2628fa0 100644
--- a/lib/wx/src/gen/wxCalendarEvent.erl
+++ b/lib/wx/src/gen/wxCalendarEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCaret.erl b/lib/wx/src/gen/wxCaret.erl
index 50844d36ff..168865e5b4 100644
--- a/lib/wx/src/gen/wxCaret.erl
+++ b/lib/wx/src/gen/wxCaret.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCheckBox.erl b/lib/wx/src/gen/wxCheckBox.erl
index bf368dc965..583ac25e87 100644
--- a/lib/wx/src/gen/wxCheckBox.erl
+++ b/lib/wx/src/gen/wxCheckBox.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCheckListBox.erl b/lib/wx/src/gen/wxCheckListBox.erl
index 7cbf9d18df..4c84bc4f93 100644
--- a/lib/wx/src/gen/wxCheckListBox.erl
+++ b/lib/wx/src/gen/wxCheckListBox.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxChildFocusEvent.erl b/lib/wx/src/gen/wxChildFocusEvent.erl
index ea04e6863b..4abdb492e8 100644
--- a/lib/wx/src/gen/wxChildFocusEvent.erl
+++ b/lib/wx/src/gen/wxChildFocusEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxChoice.erl b/lib/wx/src/gen/wxChoice.erl
index 3e20d5f933..1626736b07 100644
--- a/lib/wx/src/gen/wxChoice.erl
+++ b/lib/wx/src/gen/wxChoice.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxChoicebook.erl b/lib/wx/src/gen/wxChoicebook.erl
index faf7c402b7..b11a100bc7 100644
--- a/lib/wx/src/gen/wxChoicebook.erl
+++ b/lib/wx/src/gen/wxChoicebook.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxClientDC.erl b/lib/wx/src/gen/wxClientDC.erl
index 86418cc922..08ec69954c 100644
--- a/lib/wx/src/gen/wxClientDC.erl
+++ b/lib/wx/src/gen/wxClientDC.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxClipboard.erl b/lib/wx/src/gen/wxClipboard.erl
index c92f7b9af4..1c9f1f8b40 100644
--- a/lib/wx/src/gen/wxClipboard.erl
+++ b/lib/wx/src/gen/wxClipboard.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCloseEvent.erl b/lib/wx/src/gen/wxCloseEvent.erl
index e8e25a448c..6e3ac5fa70 100644
--- a/lib/wx/src/gen/wxCloseEvent.erl
+++ b/lib/wx/src/gen/wxCloseEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxColourData.erl b/lib/wx/src/gen/wxColourData.erl
index 973086c295..2b9ec830cb 100644
--- a/lib/wx/src/gen/wxColourData.erl
+++ b/lib/wx/src/gen/wxColourData.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxColourDialog.erl b/lib/wx/src/gen/wxColourDialog.erl
index 08a6b73775..89ee8ecb27 100644
--- a/lib/wx/src/gen/wxColourDialog.erl
+++ b/lib/wx/src/gen/wxColourDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxColourPickerCtrl.erl b/lib/wx/src/gen/wxColourPickerCtrl.erl
index 1f345b4294..2bec462324 100644
--- a/lib/wx/src/gen/wxColourPickerCtrl.erl
+++ b/lib/wx/src/gen/wxColourPickerCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxColourPickerEvent.erl b/lib/wx/src/gen/wxColourPickerEvent.erl
index 0ed131fc30..f35d2727a5 100644
--- a/lib/wx/src/gen/wxColourPickerEvent.erl
+++ b/lib/wx/src/gen/wxColourPickerEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxComboBox.erl b/lib/wx/src/gen/wxComboBox.erl
index 6a40aacd50..55983a4108 100644
--- a/lib/wx/src/gen/wxComboBox.erl
+++ b/lib/wx/src/gen/wxComboBox.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCommandEvent.erl b/lib/wx/src/gen/wxCommandEvent.erl
index f1df933d78..925a26f2c9 100644
--- a/lib/wx/src/gen/wxCommandEvent.erl
+++ b/lib/wx/src/gen/wxCommandEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxContextMenuEvent.erl b/lib/wx/src/gen/wxContextMenuEvent.erl
index 15167b0996..ea3e4ff0d5 100644
--- a/lib/wx/src/gen/wxContextMenuEvent.erl
+++ b/lib/wx/src/gen/wxContextMenuEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxControl.erl b/lib/wx/src/gen/wxControl.erl
index 1088afcc43..c612b2514a 100644
--- a/lib/wx/src/gen/wxControl.erl
+++ b/lib/wx/src/gen/wxControl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxControlWithItems.erl b/lib/wx/src/gen/wxControlWithItems.erl
index ff5e3aaedf..cb98949f7e 100644
--- a/lib/wx/src/gen/wxControlWithItems.erl
+++ b/lib/wx/src/gen/wxControlWithItems.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxCursor.erl b/lib/wx/src/gen/wxCursor.erl
index 4c2a46cc84..283fb0c80c 100644
--- a/lib/wx/src/gen/wxCursor.erl
+++ b/lib/wx/src/gen/wxCursor.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDC.erl b/lib/wx/src/gen/wxDC.erl
index 17bf77c331..b87cbb1c5c 100644
--- a/lib/wx/src/gen/wxDC.erl
+++ b/lib/wx/src/gen/wxDC.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDataObject.erl b/lib/wx/src/gen/wxDataObject.erl
index 801bd3dfba..bad6d96fb5 100644
--- a/lib/wx/src/gen/wxDataObject.erl
+++ b/lib/wx/src/gen/wxDataObject.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDateEvent.erl b/lib/wx/src/gen/wxDateEvent.erl
index 9885d6729a..ca500982e9 100644
--- a/lib/wx/src/gen/wxDateEvent.erl
+++ b/lib/wx/src/gen/wxDateEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDatePickerCtrl.erl b/lib/wx/src/gen/wxDatePickerCtrl.erl
index b9ac9cdbad..92d58213f8 100644
--- a/lib/wx/src/gen/wxDatePickerCtrl.erl
+++ b/lib/wx/src/gen/wxDatePickerCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDialog.erl b/lib/wx/src/gen/wxDialog.erl
index 75b8064bf7..d88af2acd1 100644
--- a/lib/wx/src/gen/wxDialog.erl
+++ b/lib/wx/src/gen/wxDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDirDialog.erl b/lib/wx/src/gen/wxDirDialog.erl
index 4329be13bd..01d71049b5 100644
--- a/lib/wx/src/gen/wxDirDialog.erl
+++ b/lib/wx/src/gen/wxDirDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDirPickerCtrl.erl b/lib/wx/src/gen/wxDirPickerCtrl.erl
index 787d3606f5..5f131b51a7 100644
--- a/lib/wx/src/gen/wxDirPickerCtrl.erl
+++ b/lib/wx/src/gen/wxDirPickerCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDisplayChangedEvent.erl b/lib/wx/src/gen/wxDisplayChangedEvent.erl
index 280a51ffc2..29b5fb67d6 100644
--- a/lib/wx/src/gen/wxDisplayChangedEvent.erl
+++ b/lib/wx/src/gen/wxDisplayChangedEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxEraseEvent.erl b/lib/wx/src/gen/wxEraseEvent.erl
index 66fc161aba..7d1d52dfb1 100644
--- a/lib/wx/src/gen/wxEraseEvent.erl
+++ b/lib/wx/src/gen/wxEraseEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxEvent.erl b/lib/wx/src/gen/wxEvent.erl
index dda4c0189d..403fd89f1f 100644
--- a/lib/wx/src/gen/wxEvent.erl
+++ b/lib/wx/src/gen/wxEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxEvtHandler.erl b/lib/wx/src/gen/wxEvtHandler.erl
index 0d4e224fc5..f155351b66 100644
--- a/lib/wx/src/gen/wxEvtHandler.erl
+++ b/lib/wx/src/gen/wxEvtHandler.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFileDataObject.erl b/lib/wx/src/gen/wxFileDataObject.erl
index 513f15eb00..09fd5ea832 100644
--- a/lib/wx/src/gen/wxFileDataObject.erl
+++ b/lib/wx/src/gen/wxFileDataObject.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFileDialog.erl b/lib/wx/src/gen/wxFileDialog.erl
index efe1ff57f3..7bffdee19e 100644
--- a/lib/wx/src/gen/wxFileDialog.erl
+++ b/lib/wx/src/gen/wxFileDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFileDirPickerEvent.erl b/lib/wx/src/gen/wxFileDirPickerEvent.erl
index 0f9166e542..dfa2592d9e 100644
--- a/lib/wx/src/gen/wxFileDirPickerEvent.erl
+++ b/lib/wx/src/gen/wxFileDirPickerEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFilePickerCtrl.erl b/lib/wx/src/gen/wxFilePickerCtrl.erl
index c182d20f36..a8dc861efb 100644
--- a/lib/wx/src/gen/wxFilePickerCtrl.erl
+++ b/lib/wx/src/gen/wxFilePickerCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFindReplaceData.erl b/lib/wx/src/gen/wxFindReplaceData.erl
index ac09a23e89..cf7551cab5 100644
--- a/lib/wx/src/gen/wxFindReplaceData.erl
+++ b/lib/wx/src/gen/wxFindReplaceData.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFindReplaceDialog.erl b/lib/wx/src/gen/wxFindReplaceDialog.erl
index 82da24abf5..091babcc31 100644
--- a/lib/wx/src/gen/wxFindReplaceDialog.erl
+++ b/lib/wx/src/gen/wxFindReplaceDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFlexGridSizer.erl b/lib/wx/src/gen/wxFlexGridSizer.erl
index 5387d04043..a862cdd788 100644
--- a/lib/wx/src/gen/wxFlexGridSizer.erl
+++ b/lib/wx/src/gen/wxFlexGridSizer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFocusEvent.erl b/lib/wx/src/gen/wxFocusEvent.erl
index 48a0f65e4f..4fb0432927 100644
--- a/lib/wx/src/gen/wxFocusEvent.erl
+++ b/lib/wx/src/gen/wxFocusEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFont.erl b/lib/wx/src/gen/wxFont.erl
index 4ee829d83d..3158429763 100644
--- a/lib/wx/src/gen/wxFont.erl
+++ b/lib/wx/src/gen/wxFont.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFontData.erl b/lib/wx/src/gen/wxFontData.erl
index 9b8de9212f..5fc27c14d6 100644
--- a/lib/wx/src/gen/wxFontData.erl
+++ b/lib/wx/src/gen/wxFontData.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFontDialog.erl b/lib/wx/src/gen/wxFontDialog.erl
index 009e320117..b04fef436b 100644
--- a/lib/wx/src/gen/wxFontDialog.erl
+++ b/lib/wx/src/gen/wxFontDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFontPickerCtrl.erl b/lib/wx/src/gen/wxFontPickerCtrl.erl
index fca934df49..83e25f9789 100644
--- a/lib/wx/src/gen/wxFontPickerCtrl.erl
+++ b/lib/wx/src/gen/wxFontPickerCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFontPickerEvent.erl b/lib/wx/src/gen/wxFontPickerEvent.erl
index 28c1e0fc98..28dc4308bd 100644
--- a/lib/wx/src/gen/wxFontPickerEvent.erl
+++ b/lib/wx/src/gen/wxFontPickerEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFrame.erl b/lib/wx/src/gen/wxFrame.erl
index 136651c001..934e562ee7 100644
--- a/lib/wx/src/gen/wxFrame.erl
+++ b/lib/wx/src/gen/wxFrame.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGBSizerItem.erl b/lib/wx/src/gen/wxGBSizerItem.erl
index 4d79e5c3db..43909138b8 100644
--- a/lib/wx/src/gen/wxGBSizerItem.erl
+++ b/lib/wx/src/gen/wxGBSizerItem.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGLCanvas.erl b/lib/wx/src/gen/wxGLCanvas.erl
index 25d4ddc9f2..927b7eeb05 100644
--- a/lib/wx/src/gen/wxGLCanvas.erl
+++ b/lib/wx/src/gen/wxGLCanvas.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGauge.erl b/lib/wx/src/gen/wxGauge.erl
index 3a5e117e19..559daea3d4 100644
--- a/lib/wx/src/gen/wxGauge.erl
+++ b/lib/wx/src/gen/wxGauge.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGenericDirCtrl.erl b/lib/wx/src/gen/wxGenericDirCtrl.erl
index 4146a3bacc..bd97e14816 100644
--- a/lib/wx/src/gen/wxGenericDirCtrl.erl
+++ b/lib/wx/src/gen/wxGenericDirCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
@@ -191,7 +191,7 @@ getFilterIndex(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxGenericDirCtrl_GetFilterIndex,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxGenericDirCtrl()) -> wxTreeItemId()
+%% @spec (This::wxGenericDirCtrl()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgenericdirctrl.html#wxgenericdirctrlgetrootid">external documentation</a>.
getRootId(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxGenericDirCtrl),
diff --git a/lib/wx/src/gen/wxGraphicsBrush.erl b/lib/wx/src/gen/wxGraphicsBrush.erl
index c1db82dcb3..99fd7f1ac8 100644
--- a/lib/wx/src/gen/wxGraphicsBrush.erl
+++ b/lib/wx/src/gen/wxGraphicsBrush.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsContext.erl b/lib/wx/src/gen/wxGraphicsContext.erl
index 885578657d..4ca9ad25c4 100644
--- a/lib/wx/src/gen/wxGraphicsContext.erl
+++ b/lib/wx/src/gen/wxGraphicsContext.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsFont.erl b/lib/wx/src/gen/wxGraphicsFont.erl
index 07c964d9b9..423bc15f8b 100644
--- a/lib/wx/src/gen/wxGraphicsFont.erl
+++ b/lib/wx/src/gen/wxGraphicsFont.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsMatrix.erl b/lib/wx/src/gen/wxGraphicsMatrix.erl
index b8c7b3eefb..ed6de90267 100644
--- a/lib/wx/src/gen/wxGraphicsMatrix.erl
+++ b/lib/wx/src/gen/wxGraphicsMatrix.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsObject.erl b/lib/wx/src/gen/wxGraphicsObject.erl
index 5b8b44ceca..7e63285b7a 100644
--- a/lib/wx/src/gen/wxGraphicsObject.erl
+++ b/lib/wx/src/gen/wxGraphicsObject.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsPath.erl b/lib/wx/src/gen/wxGraphicsPath.erl
index 7b27545d5f..c3adc3581d 100644
--- a/lib/wx/src/gen/wxGraphicsPath.erl
+++ b/lib/wx/src/gen/wxGraphicsPath.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsPen.erl b/lib/wx/src/gen/wxGraphicsPen.erl
index 6abf52f025..ee15519d6d 100644
--- a/lib/wx/src/gen/wxGraphicsPen.erl
+++ b/lib/wx/src/gen/wxGraphicsPen.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsRenderer.erl b/lib/wx/src/gen/wxGraphicsRenderer.erl
index 457ffe2b6e..ed53ebf468 100644
--- a/lib/wx/src/gen/wxGraphicsRenderer.erl
+++ b/lib/wx/src/gen/wxGraphicsRenderer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGrid.erl b/lib/wx/src/gen/wxGrid.erl
index 2a45bc3d6b..84ca181ce1 100644
--- a/lib/wx/src/gen/wxGrid.erl
+++ b/lib/wx/src/gen/wxGrid.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridBagSizer.erl b/lib/wx/src/gen/wxGridBagSizer.erl
index 56dc6092ad..716024bcbc 100644
--- a/lib/wx/src/gen/wxGridBagSizer.erl
+++ b/lib/wx/src/gen/wxGridBagSizer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellAttr.erl b/lib/wx/src/gen/wxGridCellAttr.erl
index b9fd65304c..3d23c2acfc 100644
--- a/lib/wx/src/gen/wxGridCellAttr.erl
+++ b/lib/wx/src/gen/wxGridCellAttr.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellBoolEditor.erl b/lib/wx/src/gen/wxGridCellBoolEditor.erl
index b5afaba68f..13084b3590 100644
--- a/lib/wx/src/gen/wxGridCellBoolEditor.erl
+++ b/lib/wx/src/gen/wxGridCellBoolEditor.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellBoolRenderer.erl b/lib/wx/src/gen/wxGridCellBoolRenderer.erl
index 442c00df1c..8cfdd9d02e 100644
--- a/lib/wx/src/gen/wxGridCellBoolRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellBoolRenderer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellChoiceEditor.erl b/lib/wx/src/gen/wxGridCellChoiceEditor.erl
index d62933fd07..ebadc1888b 100644
--- a/lib/wx/src/gen/wxGridCellChoiceEditor.erl
+++ b/lib/wx/src/gen/wxGridCellChoiceEditor.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellEditor.erl b/lib/wx/src/gen/wxGridCellEditor.erl
index c08027e040..a27ba7bd0f 100644
--- a/lib/wx/src/gen/wxGridCellEditor.erl
+++ b/lib/wx/src/gen/wxGridCellEditor.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellFloatEditor.erl b/lib/wx/src/gen/wxGridCellFloatEditor.erl
index e924c8f9a5..104602b137 100644
--- a/lib/wx/src/gen/wxGridCellFloatEditor.erl
+++ b/lib/wx/src/gen/wxGridCellFloatEditor.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellFloatRenderer.erl b/lib/wx/src/gen/wxGridCellFloatRenderer.erl
index 1d207ae4e0..000cbcf4a7 100644
--- a/lib/wx/src/gen/wxGridCellFloatRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellFloatRenderer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellNumberEditor.erl b/lib/wx/src/gen/wxGridCellNumberEditor.erl
index 347c03c377..4a5dd9d58b 100644
--- a/lib/wx/src/gen/wxGridCellNumberEditor.erl
+++ b/lib/wx/src/gen/wxGridCellNumberEditor.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellNumberRenderer.erl b/lib/wx/src/gen/wxGridCellNumberRenderer.erl
index cf90987dc9..2ace853675 100644
--- a/lib/wx/src/gen/wxGridCellNumberRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellNumberRenderer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellRenderer.erl b/lib/wx/src/gen/wxGridCellRenderer.erl
index c7040049a4..d9520c478f 100644
--- a/lib/wx/src/gen/wxGridCellRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellRenderer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellStringRenderer.erl b/lib/wx/src/gen/wxGridCellStringRenderer.erl
index 1c37cf4d6c..bc0e6b229d 100644
--- a/lib/wx/src/gen/wxGridCellStringRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellStringRenderer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellTextEditor.erl b/lib/wx/src/gen/wxGridCellTextEditor.erl
index f785d736f0..305940fddc 100644
--- a/lib/wx/src/gen/wxGridCellTextEditor.erl
+++ b/lib/wx/src/gen/wxGridCellTextEditor.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridEvent.erl b/lib/wx/src/gen/wxGridEvent.erl
index 4d89408c98..bf7dd15a70 100644
--- a/lib/wx/src/gen/wxGridEvent.erl
+++ b/lib/wx/src/gen/wxGridEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridSizer.erl b/lib/wx/src/gen/wxGridSizer.erl
index bcc62be429..cf0d3bb8b7 100644
--- a/lib/wx/src/gen/wxGridSizer.erl
+++ b/lib/wx/src/gen/wxGridSizer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxHelpEvent.erl b/lib/wx/src/gen/wxHelpEvent.erl
index 4785ff10de..d21b55d171 100644
--- a/lib/wx/src/gen/wxHelpEvent.erl
+++ b/lib/wx/src/gen/wxHelpEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxHtmlEasyPrinting.erl b/lib/wx/src/gen/wxHtmlEasyPrinting.erl
index a782bd71c3..adb56273c8 100644
--- a/lib/wx/src/gen/wxHtmlEasyPrinting.erl
+++ b/lib/wx/src/gen/wxHtmlEasyPrinting.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxHtmlLinkEvent.erl b/lib/wx/src/gen/wxHtmlLinkEvent.erl
index 04eccad939..aba2cb4ab7 100644
--- a/lib/wx/src/gen/wxHtmlLinkEvent.erl
+++ b/lib/wx/src/gen/wxHtmlLinkEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxHtmlWindow.erl b/lib/wx/src/gen/wxHtmlWindow.erl
index 6f43c17890..745f52e0ea 100644
--- a/lib/wx/src/gen/wxHtmlWindow.erl
+++ b/lib/wx/src/gen/wxHtmlWindow.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxIcon.erl b/lib/wx/src/gen/wxIcon.erl
index d95fad1458..4f605a8f04 100644
--- a/lib/wx/src/gen/wxIcon.erl
+++ b/lib/wx/src/gen/wxIcon.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxIconBundle.erl b/lib/wx/src/gen/wxIconBundle.erl
index be600c69da..3350838203 100644
--- a/lib/wx/src/gen/wxIconBundle.erl
+++ b/lib/wx/src/gen/wxIconBundle.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxIconizeEvent.erl b/lib/wx/src/gen/wxIconizeEvent.erl
index 09f8843b74..43d805faa4 100644
--- a/lib/wx/src/gen/wxIconizeEvent.erl
+++ b/lib/wx/src/gen/wxIconizeEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxIdleEvent.erl b/lib/wx/src/gen/wxIdleEvent.erl
index e205eff522..d7f1e117d7 100644
--- a/lib/wx/src/gen/wxIdleEvent.erl
+++ b/lib/wx/src/gen/wxIdleEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxImage.erl b/lib/wx/src/gen/wxImage.erl
index f90ae09707..d35a56bdc6 100644
--- a/lib/wx/src/gen/wxImage.erl
+++ b/lib/wx/src/gen/wxImage.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxImageList.erl b/lib/wx/src/gen/wxImageList.erl
index b20dfda315..ecc11f100e 100644
--- a/lib/wx/src/gen/wxImageList.erl
+++ b/lib/wx/src/gen/wxImageList.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxJoystickEvent.erl b/lib/wx/src/gen/wxJoystickEvent.erl
index b07cbd6d9a..cf4cd0fcaf 100644
--- a/lib/wx/src/gen/wxJoystickEvent.erl
+++ b/lib/wx/src/gen/wxJoystickEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxKeyEvent.erl b/lib/wx/src/gen/wxKeyEvent.erl
index 0e92402435..0dea0fec7c 100644
--- a/lib/wx/src/gen/wxKeyEvent.erl
+++ b/lib/wx/src/gen/wxKeyEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxLayoutAlgorithm.erl b/lib/wx/src/gen/wxLayoutAlgorithm.erl
index 8ea920d80b..d61142c9e0 100644
--- a/lib/wx/src/gen/wxLayoutAlgorithm.erl
+++ b/lib/wx/src/gen/wxLayoutAlgorithm.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxListBox.erl b/lib/wx/src/gen/wxListBox.erl
index 5fd9f329d0..5c4d67cf2a 100644
--- a/lib/wx/src/gen/wxListBox.erl
+++ b/lib/wx/src/gen/wxListBox.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxListCtrl.erl b/lib/wx/src/gen/wxListCtrl.erl
index 980415f577..a847f4059e 100644
--- a/lib/wx/src/gen/wxListCtrl.erl
+++ b/lib/wx/src/gen/wxListCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxListEvent.erl b/lib/wx/src/gen/wxListEvent.erl
index fd1cc381ed..2d80e86abc 100644
--- a/lib/wx/src/gen/wxListEvent.erl
+++ b/lib/wx/src/gen/wxListEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxListItem.erl b/lib/wx/src/gen/wxListItem.erl
index 31d44b9601..9891adb897 100644
--- a/lib/wx/src/gen/wxListItem.erl
+++ b/lib/wx/src/gen/wxListItem.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxListView.erl b/lib/wx/src/gen/wxListView.erl
index a39a594a6a..7c938a21ca 100644
--- a/lib/wx/src/gen/wxListView.erl
+++ b/lib/wx/src/gen/wxListView.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxListbook.erl b/lib/wx/src/gen/wxListbook.erl
index 385c50c316..7cdc861c26 100644
--- a/lib/wx/src/gen/wxListbook.erl
+++ b/lib/wx/src/gen/wxListbook.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxLogNull.erl b/lib/wx/src/gen/wxLogNull.erl
index f33070b197..3ec2c6384d 100644
--- a/lib/wx/src/gen/wxLogNull.erl
+++ b/lib/wx/src/gen/wxLogNull.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMDIChildFrame.erl b/lib/wx/src/gen/wxMDIChildFrame.erl
index 3403ab6c9c..42e1af8d98 100644
--- a/lib/wx/src/gen/wxMDIChildFrame.erl
+++ b/lib/wx/src/gen/wxMDIChildFrame.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMDIClientWindow.erl b/lib/wx/src/gen/wxMDIClientWindow.erl
index 6a6fbab4a7..a1bcaf0dee 100644
--- a/lib/wx/src/gen/wxMDIClientWindow.erl
+++ b/lib/wx/src/gen/wxMDIClientWindow.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMDIParentFrame.erl b/lib/wx/src/gen/wxMDIParentFrame.erl
index 2638309ce7..1519ec985c 100644
--- a/lib/wx/src/gen/wxMDIParentFrame.erl
+++ b/lib/wx/src/gen/wxMDIParentFrame.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMask.erl b/lib/wx/src/gen/wxMask.erl
index 881f8ba183..0686165254 100644
--- a/lib/wx/src/gen/wxMask.erl
+++ b/lib/wx/src/gen/wxMask.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMaximizeEvent.erl b/lib/wx/src/gen/wxMaximizeEvent.erl
index 4ad1be3de0..0d775bf201 100644
--- a/lib/wx/src/gen/wxMaximizeEvent.erl
+++ b/lib/wx/src/gen/wxMaximizeEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMemoryDC.erl b/lib/wx/src/gen/wxMemoryDC.erl
index 28471cc8d3..97b74a4d9f 100644
--- a/lib/wx/src/gen/wxMemoryDC.erl
+++ b/lib/wx/src/gen/wxMemoryDC.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMenu.erl b/lib/wx/src/gen/wxMenu.erl
index bc4fef6f18..02a8c5e76e 100644
--- a/lib/wx/src/gen/wxMenu.erl
+++ b/lib/wx/src/gen/wxMenu.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMenuBar.erl b/lib/wx/src/gen/wxMenuBar.erl
index 28dab451b8..84017d1526 100644
--- a/lib/wx/src/gen/wxMenuBar.erl
+++ b/lib/wx/src/gen/wxMenuBar.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMenuEvent.erl b/lib/wx/src/gen/wxMenuEvent.erl
index 77ce7c04b7..47e696d0ba 100644
--- a/lib/wx/src/gen/wxMenuEvent.erl
+++ b/lib/wx/src/gen/wxMenuEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMenuItem.erl b/lib/wx/src/gen/wxMenuItem.erl
index 2d9fd15d86..74f314f468 100644
--- a/lib/wx/src/gen/wxMenuItem.erl
+++ b/lib/wx/src/gen/wxMenuItem.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMessageDialog.erl b/lib/wx/src/gen/wxMessageDialog.erl
index eab41919ba..83e6dcee7f 100644
--- a/lib/wx/src/gen/wxMessageDialog.erl
+++ b/lib/wx/src/gen/wxMessageDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMiniFrame.erl b/lib/wx/src/gen/wxMiniFrame.erl
index 3e7799a66f..f99b74da1f 100644
--- a/lib/wx/src/gen/wxMiniFrame.erl
+++ b/lib/wx/src/gen/wxMiniFrame.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMirrorDC.erl b/lib/wx/src/gen/wxMirrorDC.erl
index 9300f7a31e..20cc2b2f28 100644
--- a/lib/wx/src/gen/wxMirrorDC.erl
+++ b/lib/wx/src/gen/wxMirrorDC.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl b/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl
index 629dcde795..c156f0e87e 100644
--- a/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl
+++ b/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMouseEvent.erl b/lib/wx/src/gen/wxMouseEvent.erl
index 0772e99b0d..69a9efc75d 100644
--- a/lib/wx/src/gen/wxMouseEvent.erl
+++ b/lib/wx/src/gen/wxMouseEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMoveEvent.erl b/lib/wx/src/gen/wxMoveEvent.erl
index 17a33ff3ed..4d88658262 100644
--- a/lib/wx/src/gen/wxMoveEvent.erl
+++ b/lib/wx/src/gen/wxMoveEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxMultiChoiceDialog.erl b/lib/wx/src/gen/wxMultiChoiceDialog.erl
index 98690654e6..6784dfeb48 100644
--- a/lib/wx/src/gen/wxMultiChoiceDialog.erl
+++ b/lib/wx/src/gen/wxMultiChoiceDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxNavigationKeyEvent.erl b/lib/wx/src/gen/wxNavigationKeyEvent.erl
index 9a74a75c51..ed54eca139 100644
--- a/lib/wx/src/gen/wxNavigationKeyEvent.erl
+++ b/lib/wx/src/gen/wxNavigationKeyEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxNcPaintEvent.erl b/lib/wx/src/gen/wxNcPaintEvent.erl
index 22e00d337d..015b7d41b0 100644
--- a/lib/wx/src/gen/wxNcPaintEvent.erl
+++ b/lib/wx/src/gen/wxNcPaintEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxNotebook.erl b/lib/wx/src/gen/wxNotebook.erl
index 93cc741036..2f00e79607 100644
--- a/lib/wx/src/gen/wxNotebook.erl
+++ b/lib/wx/src/gen/wxNotebook.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxNotebookEvent.erl b/lib/wx/src/gen/wxNotebookEvent.erl
index 4664f85527..58c3c0ccc0 100644
--- a/lib/wx/src/gen/wxNotebookEvent.erl
+++ b/lib/wx/src/gen/wxNotebookEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxNotifyEvent.erl b/lib/wx/src/gen/wxNotifyEvent.erl
index 4e463aa7e0..195e0db0cf 100644
--- a/lib/wx/src/gen/wxNotifyEvent.erl
+++ b/lib/wx/src/gen/wxNotifyEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPageSetupDialog.erl b/lib/wx/src/gen/wxPageSetupDialog.erl
index 73eac44ab5..6802f3b26f 100644
--- a/lib/wx/src/gen/wxPageSetupDialog.erl
+++ b/lib/wx/src/gen/wxPageSetupDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPageSetupDialogData.erl b/lib/wx/src/gen/wxPageSetupDialogData.erl
index 576be819a2..479c5be963 100644
--- a/lib/wx/src/gen/wxPageSetupDialogData.erl
+++ b/lib/wx/src/gen/wxPageSetupDialogData.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPaintDC.erl b/lib/wx/src/gen/wxPaintDC.erl
index ea4e847f69..a84bca2342 100644
--- a/lib/wx/src/gen/wxPaintDC.erl
+++ b/lib/wx/src/gen/wxPaintDC.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPaintEvent.erl b/lib/wx/src/gen/wxPaintEvent.erl
index 9f6b84890b..859e00e8dd 100644
--- a/lib/wx/src/gen/wxPaintEvent.erl
+++ b/lib/wx/src/gen/wxPaintEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPalette.erl b/lib/wx/src/gen/wxPalette.erl
index 499e6f47ce..38b9be3906 100644
--- a/lib/wx/src/gen/wxPalette.erl
+++ b/lib/wx/src/gen/wxPalette.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPaletteChangedEvent.erl b/lib/wx/src/gen/wxPaletteChangedEvent.erl
index 147389709c..1cde5997a3 100644
--- a/lib/wx/src/gen/wxPaletteChangedEvent.erl
+++ b/lib/wx/src/gen/wxPaletteChangedEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPanel.erl b/lib/wx/src/gen/wxPanel.erl
index ca18caf4da..8afbe6df99 100644
--- a/lib/wx/src/gen/wxPanel.erl
+++ b/lib/wx/src/gen/wxPanel.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPasswordEntryDialog.erl b/lib/wx/src/gen/wxPasswordEntryDialog.erl
index 70728355e9..125a9915c5 100644
--- a/lib/wx/src/gen/wxPasswordEntryDialog.erl
+++ b/lib/wx/src/gen/wxPasswordEntryDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPen.erl b/lib/wx/src/gen/wxPen.erl
index cf159f559e..ffd2c42140 100644
--- a/lib/wx/src/gen/wxPen.erl
+++ b/lib/wx/src/gen/wxPen.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPickerBase.erl b/lib/wx/src/gen/wxPickerBase.erl
index 173f31faf0..90c8fa7642 100644
--- a/lib/wx/src/gen/wxPickerBase.erl
+++ b/lib/wx/src/gen/wxPickerBase.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPostScriptDC.erl b/lib/wx/src/gen/wxPostScriptDC.erl
index 6e67abdd08..d142f33bc5 100644
--- a/lib/wx/src/gen/wxPostScriptDC.erl
+++ b/lib/wx/src/gen/wxPostScriptDC.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPreviewCanvas.erl b/lib/wx/src/gen/wxPreviewCanvas.erl
index 4f52e2015f..d483d78f39 100644
--- a/lib/wx/src/gen/wxPreviewCanvas.erl
+++ b/lib/wx/src/gen/wxPreviewCanvas.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPreviewControlBar.erl b/lib/wx/src/gen/wxPreviewControlBar.erl
index 0118977e9a..db1eee9582 100644
--- a/lib/wx/src/gen/wxPreviewControlBar.erl
+++ b/lib/wx/src/gen/wxPreviewControlBar.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPreviewFrame.erl b/lib/wx/src/gen/wxPreviewFrame.erl
index 93dac8dbd9..c324680e87 100644
--- a/lib/wx/src/gen/wxPreviewFrame.erl
+++ b/lib/wx/src/gen/wxPreviewFrame.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPrintData.erl b/lib/wx/src/gen/wxPrintData.erl
index 49fad6b093..3e4fac5912 100644
--- a/lib/wx/src/gen/wxPrintData.erl
+++ b/lib/wx/src/gen/wxPrintData.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPrintDialog.erl b/lib/wx/src/gen/wxPrintDialog.erl
index 5100e7dcd4..f167059990 100644
--- a/lib/wx/src/gen/wxPrintDialog.erl
+++ b/lib/wx/src/gen/wxPrintDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPrintDialogData.erl b/lib/wx/src/gen/wxPrintDialogData.erl
index b4ad5a4a82..3bbac3b4fc 100644
--- a/lib/wx/src/gen/wxPrintDialogData.erl
+++ b/lib/wx/src/gen/wxPrintDialogData.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPrintPreview.erl b/lib/wx/src/gen/wxPrintPreview.erl
index 8a616c64fb..cab174e3ee 100644
--- a/lib/wx/src/gen/wxPrintPreview.erl
+++ b/lib/wx/src/gen/wxPrintPreview.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPrinter.erl b/lib/wx/src/gen/wxPrinter.erl
index d12a1f5909..cc32badeb3 100644
--- a/lib/wx/src/gen/wxPrinter.erl
+++ b/lib/wx/src/gen/wxPrinter.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxPrintout.erl b/lib/wx/src/gen/wxPrintout.erl
index 30811d32a0..67a7cb5c82 100644
--- a/lib/wx/src/gen/wxPrintout.erl
+++ b/lib/wx/src/gen/wxPrintout.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxProgressDialog.erl b/lib/wx/src/gen/wxProgressDialog.erl
index 6d7d2d9743..78b3b1d3a0 100644
--- a/lib/wx/src/gen/wxProgressDialog.erl
+++ b/lib/wx/src/gen/wxProgressDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxQueryNewPaletteEvent.erl b/lib/wx/src/gen/wxQueryNewPaletteEvent.erl
index 140d58c42c..a5322f0d64 100644
--- a/lib/wx/src/gen/wxQueryNewPaletteEvent.erl
+++ b/lib/wx/src/gen/wxQueryNewPaletteEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxRadioBox.erl b/lib/wx/src/gen/wxRadioBox.erl
index ab76354da2..0481b03cd2 100644
--- a/lib/wx/src/gen/wxRadioBox.erl
+++ b/lib/wx/src/gen/wxRadioBox.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxRadioButton.erl b/lib/wx/src/gen/wxRadioButton.erl
index 066023d121..7d2c41ec10 100644
--- a/lib/wx/src/gen/wxRadioButton.erl
+++ b/lib/wx/src/gen/wxRadioButton.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxRegion.erl b/lib/wx/src/gen/wxRegion.erl
index a2d2c7d830..6a929480b1 100644
--- a/lib/wx/src/gen/wxRegion.erl
+++ b/lib/wx/src/gen/wxRegion.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSashEvent.erl b/lib/wx/src/gen/wxSashEvent.erl
index 56453fbe2f..3df2543378 100644
--- a/lib/wx/src/gen/wxSashEvent.erl
+++ b/lib/wx/src/gen/wxSashEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSashLayoutWindow.erl b/lib/wx/src/gen/wxSashLayoutWindow.erl
index 9b3c372369..9d40021b3f 100644
--- a/lib/wx/src/gen/wxSashLayoutWindow.erl
+++ b/lib/wx/src/gen/wxSashLayoutWindow.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSashWindow.erl b/lib/wx/src/gen/wxSashWindow.erl
index d836d84ed3..c665dd4c9a 100644
--- a/lib/wx/src/gen/wxSashWindow.erl
+++ b/lib/wx/src/gen/wxSashWindow.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxScreenDC.erl b/lib/wx/src/gen/wxScreenDC.erl
index 35dcb23179..86b62a48c7 100644
--- a/lib/wx/src/gen/wxScreenDC.erl
+++ b/lib/wx/src/gen/wxScreenDC.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxScrollBar.erl b/lib/wx/src/gen/wxScrollBar.erl
index f77b4dde21..9ca197af8d 100644
--- a/lib/wx/src/gen/wxScrollBar.erl
+++ b/lib/wx/src/gen/wxScrollBar.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxScrollEvent.erl b/lib/wx/src/gen/wxScrollEvent.erl
index 52bb5b8347..19e21e6b03 100644
--- a/lib/wx/src/gen/wxScrollEvent.erl
+++ b/lib/wx/src/gen/wxScrollEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxScrollWinEvent.erl b/lib/wx/src/gen/wxScrollWinEvent.erl
index d87be2c792..9b7fcca3da 100644
--- a/lib/wx/src/gen/wxScrollWinEvent.erl
+++ b/lib/wx/src/gen/wxScrollWinEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxScrolledWindow.erl b/lib/wx/src/gen/wxScrolledWindow.erl
index d3e250fbe1..9673d09fe8 100644
--- a/lib/wx/src/gen/wxScrolledWindow.erl
+++ b/lib/wx/src/gen/wxScrolledWindow.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSetCursorEvent.erl b/lib/wx/src/gen/wxSetCursorEvent.erl
index 74cc1c1a5a..75cf542ba1 100644
--- a/lib/wx/src/gen/wxSetCursorEvent.erl
+++ b/lib/wx/src/gen/wxSetCursorEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxShowEvent.erl b/lib/wx/src/gen/wxShowEvent.erl
index 173cd4269a..c00b1acbee 100644
--- a/lib/wx/src/gen/wxShowEvent.erl
+++ b/lib/wx/src/gen/wxShowEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSingleChoiceDialog.erl b/lib/wx/src/gen/wxSingleChoiceDialog.erl
index 485e7f8be9..9424a536cd 100644
--- a/lib/wx/src/gen/wxSingleChoiceDialog.erl
+++ b/lib/wx/src/gen/wxSingleChoiceDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSizeEvent.erl b/lib/wx/src/gen/wxSizeEvent.erl
index e9e337df33..115f6d3f6c 100644
--- a/lib/wx/src/gen/wxSizeEvent.erl
+++ b/lib/wx/src/gen/wxSizeEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSizer.erl b/lib/wx/src/gen/wxSizer.erl
index 4086d34b19..7cc31b1b6e 100644
--- a/lib/wx/src/gen/wxSizer.erl
+++ b/lib/wx/src/gen/wxSizer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSizerFlags.erl b/lib/wx/src/gen/wxSizerFlags.erl
index 898b2d42ed..8dfaa2ca4b 100644
--- a/lib/wx/src/gen/wxSizerFlags.erl
+++ b/lib/wx/src/gen/wxSizerFlags.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSizerItem.erl b/lib/wx/src/gen/wxSizerItem.erl
index e8391d859a..e69b269b21 100644
--- a/lib/wx/src/gen/wxSizerItem.erl
+++ b/lib/wx/src/gen/wxSizerItem.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSlider.erl b/lib/wx/src/gen/wxSlider.erl
index 694630859b..55418ece91 100644
--- a/lib/wx/src/gen/wxSlider.erl
+++ b/lib/wx/src/gen/wxSlider.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSpinButton.erl b/lib/wx/src/gen/wxSpinButton.erl
index 1cc59ec6aa..5c0c3637a1 100644
--- a/lib/wx/src/gen/wxSpinButton.erl
+++ b/lib/wx/src/gen/wxSpinButton.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSpinCtrl.erl b/lib/wx/src/gen/wxSpinCtrl.erl
index bed2d733a3..ae137195c9 100644
--- a/lib/wx/src/gen/wxSpinCtrl.erl
+++ b/lib/wx/src/gen/wxSpinCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSpinEvent.erl b/lib/wx/src/gen/wxSpinEvent.erl
index 2c44b3c2a3..37fc6e6457 100644
--- a/lib/wx/src/gen/wxSpinEvent.erl
+++ b/lib/wx/src/gen/wxSpinEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSplashScreen.erl b/lib/wx/src/gen/wxSplashScreen.erl
index 8fe543c4e8..c7c5d5cf90 100644
--- a/lib/wx/src/gen/wxSplashScreen.erl
+++ b/lib/wx/src/gen/wxSplashScreen.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSplitterEvent.erl b/lib/wx/src/gen/wxSplitterEvent.erl
index a3a8171742..0f40455998 100644
--- a/lib/wx/src/gen/wxSplitterEvent.erl
+++ b/lib/wx/src/gen/wxSplitterEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSplitterWindow.erl b/lib/wx/src/gen/wxSplitterWindow.erl
index 6522858266..689ddd03b2 100644
--- a/lib/wx/src/gen/wxSplitterWindow.erl
+++ b/lib/wx/src/gen/wxSplitterWindow.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStaticBitmap.erl b/lib/wx/src/gen/wxStaticBitmap.erl
index 5f22b5780e..8c6adc16aa 100644
--- a/lib/wx/src/gen/wxStaticBitmap.erl
+++ b/lib/wx/src/gen/wxStaticBitmap.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStaticBox.erl b/lib/wx/src/gen/wxStaticBox.erl
index 08e8fd8c0c..da53a5c2fe 100644
--- a/lib/wx/src/gen/wxStaticBox.erl
+++ b/lib/wx/src/gen/wxStaticBox.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStaticBoxSizer.erl b/lib/wx/src/gen/wxStaticBoxSizer.erl
index d097bc95e3..efe1918b21 100644
--- a/lib/wx/src/gen/wxStaticBoxSizer.erl
+++ b/lib/wx/src/gen/wxStaticBoxSizer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStaticLine.erl b/lib/wx/src/gen/wxStaticLine.erl
index c4b660b317..b879e53ab0 100644
--- a/lib/wx/src/gen/wxStaticLine.erl
+++ b/lib/wx/src/gen/wxStaticLine.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStaticText.erl b/lib/wx/src/gen/wxStaticText.erl
index 0e4aec3365..baac7b1877 100644
--- a/lib/wx/src/gen/wxStaticText.erl
+++ b/lib/wx/src/gen/wxStaticText.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStatusBar.erl b/lib/wx/src/gen/wxStatusBar.erl
index c77c3c447d..c7e605c65b 100644
--- a/lib/wx/src/gen/wxStatusBar.erl
+++ b/lib/wx/src/gen/wxStatusBar.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStdDialogButtonSizer.erl b/lib/wx/src/gen/wxStdDialogButtonSizer.erl
index 3ee3ef4a36..4826fae0a7 100644
--- a/lib/wx/src/gen/wxStdDialogButtonSizer.erl
+++ b/lib/wx/src/gen/wxStdDialogButtonSizer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStyledTextCtrl.erl b/lib/wx/src/gen/wxStyledTextCtrl.erl
index 21964403f9..edf6d9cfed 100644
--- a/lib/wx/src/gen/wxStyledTextCtrl.erl
+++ b/lib/wx/src/gen/wxStyledTextCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxStyledTextEvent.erl b/lib/wx/src/gen/wxStyledTextEvent.erl
index ed5788b6fd..753431e47e 100644
--- a/lib/wx/src/gen/wxStyledTextEvent.erl
+++ b/lib/wx/src/gen/wxStyledTextEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxSysColourChangedEvent.erl b/lib/wx/src/gen/wxSysColourChangedEvent.erl
index a90c7320d9..2b0d12d78a 100644
--- a/lib/wx/src/gen/wxSysColourChangedEvent.erl
+++ b/lib/wx/src/gen/wxSysColourChangedEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTextAttr.erl b/lib/wx/src/gen/wxTextAttr.erl
index dea39c19d0..d504588e28 100644
--- a/lib/wx/src/gen/wxTextAttr.erl
+++ b/lib/wx/src/gen/wxTextAttr.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTextCtrl.erl b/lib/wx/src/gen/wxTextCtrl.erl
index 1df8accdaa..43ce66d744 100644
--- a/lib/wx/src/gen/wxTextCtrl.erl
+++ b/lib/wx/src/gen/wxTextCtrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTextDataObject.erl b/lib/wx/src/gen/wxTextDataObject.erl
index 1e4cee70aa..5905977270 100644
--- a/lib/wx/src/gen/wxTextDataObject.erl
+++ b/lib/wx/src/gen/wxTextDataObject.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTextEntryDialog.erl b/lib/wx/src/gen/wxTextEntryDialog.erl
index 42e7f41513..5957a8aa54 100644
--- a/lib/wx/src/gen/wxTextEntryDialog.erl
+++ b/lib/wx/src/gen/wxTextEntryDialog.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxToggleButton.erl b/lib/wx/src/gen/wxToggleButton.erl
index 0a8f4f1127..dccf2e6e7d 100644
--- a/lib/wx/src/gen/wxToggleButton.erl
+++ b/lib/wx/src/gen/wxToggleButton.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxToolBar.erl b/lib/wx/src/gen/wxToolBar.erl
index c8392a10ca..0af762e0bd 100644
--- a/lib/wx/src/gen/wxToolBar.erl
+++ b/lib/wx/src/gen/wxToolBar.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxToolTip.erl b/lib/wx/src/gen/wxToolTip.erl
index 3a57ece765..b56e632cab 100644
--- a/lib/wx/src/gen/wxToolTip.erl
+++ b/lib/wx/src/gen/wxToolTip.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxToolbook.erl b/lib/wx/src/gen/wxToolbook.erl
index 44d3ea945d..31f4830700 100644
--- a/lib/wx/src/gen/wxToolbook.erl
+++ b/lib/wx/src/gen/wxToolbook.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTopLevelWindow.erl b/lib/wx/src/gen/wxTopLevelWindow.erl
index 3bb63886d9..75eeaca2bb 100644
--- a/lib/wx/src/gen/wxTopLevelWindow.erl
+++ b/lib/wx/src/gen/wxTopLevelWindow.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxTreeCtrl.erl b/lib/wx/src/gen/wxTreeCtrl.erl
index cc08c14754..a5f0bdc750 100644
--- a/lib/wx/src/gen/wxTreeCtrl.erl
+++ b/lib/wx/src/gen/wxTreeCtrl.erl
@@ -1,23 +1,27 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html">wxTreeCtrl</a>.
+%%
+%% Note: The representation of treeItemId() have changed from the original class implementation to be an semi-opaque type,Equality between TreeItemId's can be tested and zero means that the TreeItem is invalid.
+
+%%
%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
@@ -33,10 +37,10 @@
collapse/2,collapseAndReset/2,create/2,create/3,delete/2,deleteAllItems/1,
deleteChildren/2,destroy/1,ensureVisible/2,expand/2,getBoundingRect/3,
getBoundingRect/4,getChildrenCount/2,getChildrenCount/3,getCount/1,
- getEditControl/1,getFirstVisibleItem/1,getImageList/1,getIndent/1,
- getItemBackgroundColour/2,getItemData/2,getItemFont/2,getItemImage/2,
- getItemImage/3,getItemParent/2,getItemText/2,getItemTextColour/2,
- getLastChild/2,getNextSibling/2,getNextVisible/2,getPrevSibling/2,
+ getEditControl/1,getFirstChild/2,getFirstVisibleItem/1,getImageList/1,
+ getIndent/1,getItemBackgroundColour/2,getItemData/2,getItemFont/2,
+ getItemImage/2,getItemImage/3,getItemParent/2,getItemText/2,getItemTextColour/2,
+ getLastChild/2,getNextChild/3,getNextSibling/2,getNextVisible/2,getPrevSibling/2,
getPrevVisible/2,getRootItem/1,getSelection/1,getSelections/1,getStateImageList/1,
hitTest/2,insertItem/4,insertItem/5,isBold/2,isExpanded/2,isSelected/2,
isVisible/2,itemHasChildren/2,new/0,new/1,new/2,prependItem/3,prependItem/4,
@@ -119,13 +123,13 @@ new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
wxe_util:construct(?wxTreeCtrl_new_2,
<<ParentRef:32/?UI, 0:32,BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Text::string()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Text::string()) -> integer()
%% @equiv addRoot(This,Text, [])
addRoot(This,Text)
when is_record(This, wx_ref),is_list(Text) ->
addRoot(This,Text, []).
-%% @spec (This::wxTreeCtrl(), Text::string(), [Option]) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Text::string(), [Option]) -> integer()
%% Option = {image, integer()} | {selectedImage, integer()} | {data, term()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrladdroot">external documentation</a>.
addRoot(#wx_ref{type=ThisT,ref=ThisRef},Text, Options)
@@ -140,17 +144,17 @@ addRoot(#wx_ref{type=ThisT,ref=ThisRef},Text, Options)
wxe_util:call(?wxTreeCtrl_AddRoot,
<<ThisRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Parent::wxTreeItemId(), Text::string()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Text::string()) -> integer()
%% @equiv appendItem(This,Parent,Text, [])
appendItem(This,Parent,Text)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Parent),is_list(Text) ->
appendItem(This,Parent,Text, []).
-%% @spec (This::wxTreeCtrl(), Parent::wxTreeItemId(), Text::string(), [Option]) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Text::string(), [Option]) -> integer()
%% Option = {image, integer()} | {selectedImage, integer()} | {data, term()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlappenditem">external documentation</a>.
-appendItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+appendItem(#wx_ref{type=ThisT,ref=ThisRef},Parent,Text, Options)
+ when is_integer(Parent),is_list(Text),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({image, Image}, Acc) -> [<<1:32/?UI,Image:32/?UI>>|Acc];
@@ -159,7 +163,7 @@ appendItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentR
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_AppendItem,
- <<ThisRef:32/?UI,ParentRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Parent:64/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
%% @spec (This::wxTreeCtrl(), ImageList::wxImageList:wxImageList()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlassignimagelist">external documentation</a>.
@@ -177,19 +181,21 @@ assignStateImageList(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ImageListT,ref
wxe_util:cast(?wxTreeCtrl_AssignStateImageList,
<<ThisRef:32/?UI,ImageListRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlcollapse">external documentation</a>.
-collapse(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+collapse(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_Collapse,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlcollapseandreset">external documentation</a>.
-collapseAndReset(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+collapseAndReset(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_CollapseAndReset,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
%% @spec (This::wxTreeCtrl(), Parent::wxWindow:wxWindow()) -> bool()
%% @equiv create(This,Parent, [])
@@ -214,12 +220,13 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Opti
wxe_util:call(?wxTreeCtrl_Create,
<<ThisRef:32/?UI,ParentRef:32/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrldelete">external documentation</a>.
-delete(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+delete(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_Delete,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
%% @spec (This::wxTreeCtrl()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrldeleteallitems">external documentation</a>.
@@ -228,62 +235,65 @@ deleteAllItems(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:cast(?wxTreeCtrl_DeleteAllItems,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrldeletechildren">external documentation</a>.
-deleteChildren(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+deleteChildren(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_DeleteChildren,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlensurevisible">external documentation</a>.
-ensureVisible(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+ensureVisible(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_EnsureVisible,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlexpand">external documentation</a>.
-expand(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+expand(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_Expand,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool()
%% @equiv getBoundingRect(This,Item,Rect, [])
getBoundingRect(This,Item,Rect={RectX,RectY,RectW,RectH})
- when is_record(This, wx_ref),is_record(Item, wx_ref),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) ->
+ when is_record(This, wx_ref),is_integer(Item),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) ->
getBoundingRect(This,Item,Rect, []).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, [Option]) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, [Option]) -> bool()
%% Option = {textOnly, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetboundingrect">external documentation</a>.
-getBoundingRect(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},{RectX,RectY,RectW,RectH}, Options)
- when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),is_list(Options) ->
+getBoundingRect(#wx_ref{type=ThisT,ref=ThisRef},Item,{RectX,RectY,RectW,RectH}, Options)
+ when is_integer(Item),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({textOnly, TextOnly}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(TextOnly)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_GetBoundingRect,
- <<ThisRef:32/?UI,ItemRef:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> integer()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @equiv getChildrenCount(This,Item, [])
getChildrenCount(This,Item)
- when is_record(This, wx_ref),is_record(Item, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Item) ->
getChildrenCount(This,Item, []).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> integer()
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> integer()
%% Option = {recursively, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetchildrencount">external documentation</a>.
-getChildrenCount(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+getChildrenCount(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({recursively, Recursively}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Recursively)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_GetChildrenCount,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
%% @spec (This::wxTreeCtrl()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetcount">external documentation</a>.
@@ -299,7 +309,23 @@ getEditControl(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxTreeCtrl_GetEditControl,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> {integer(),Cookie::integer()}
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetfirstchild">external documentation</a>.
+getFirstChild(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
+ ?CLASS(ThisT,wxTreeCtrl),
+ wxe_util:call(?wxTreeCtrl_GetFirstChild,
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
+
+%% @spec (This::wxTreeCtrl(), Item::integer(), Cookie::integer()) -> {integer(),Cookie::integer()}
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetnextchild">external documentation</a>.
+getNextChild(#wx_ref{type=ThisT,ref=ThisRef},Item,Cookie)
+ when is_integer(Item),is_integer(Cookie) ->
+ ?CLASS(ThisT,wxTreeCtrl),
+ wxe_util:call(?wxTreeCtrl_GetNextChild,
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,Cookie:64/?UI>>).
+
+%% @spec (This::wxTreeCtrl()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetfirstvisibleitem">external documentation</a>.
getFirstVisibleItem(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeCtrl),
@@ -320,119 +346,131 @@ getIndent(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxTreeCtrl_GetIndent,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wx:colour()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> wx:colour()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitembackgroundcolour">external documentation</a>.
-getItemBackgroundColour(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemBackgroundColour(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemBackgroundColour,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> term()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> term()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemdata">external documentation</a>.
-getItemData(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemData(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemData,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxFont:wxFont()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> wxFont:wxFont()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemfont">external documentation</a>.
-getItemFont(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemFont(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemFont,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> integer()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemimage">external documentation</a>.
-getItemImage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemImage(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemImage_1,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> integer()
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> integer()
%% Option = {which, WxTreeItemIcon}
%% WxTreeItemIcon = integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemimage">external documentation</a>.
%%<br /> WxTreeItemIcon is one of ?wxTreeItemIcon_Normal | ?wxTreeItemIcon_Selected | ?wxTreeItemIcon_Expanded | ?wxTreeItemIcon_SelectedExpanded | ?wxTreeItemIcon_Max
-getItemImage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+getItemImage(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({which, Which}, Acc) -> [<<1:32/?UI,Which:32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_GetItemImage_2,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> string()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> string()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemtext">external documentation</a>.
-getItemText(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemText(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemText,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wx:colour()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> wx:colour()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemtextcolour">external documentation</a>.
-getItemTextColour(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemTextColour(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemTextColour,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetlastchild">external documentation</a>.
-getLastChild(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getLastChild(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetLastChild,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetnextsibling">external documentation</a>.
-getNextSibling(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getNextSibling(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetNextSibling,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetnextvisible">external documentation</a>.
-getNextVisible(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getNextVisible(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetNextVisible,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemparent">external documentation</a>.
-getItemParent(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemParent(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemParent,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetprevsibling">external documentation</a>.
-getPrevSibling(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getPrevSibling(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetPrevSibling,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetprevvisible">external documentation</a>.
-getPrevVisible(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getPrevVisible(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetPrevVisible,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetrootitem">external documentation</a>.
getRootItem(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetRootItem,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetselection">external documentation</a>.
getSelection(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetSelection,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl()) -> {integer(),Val::[wxTreeItemId()]}
+%% @spec (This::wxTreeCtrl()) -> {integer(),Val::[integer()]}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetselections">external documentation</a>.
getSelections(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeCtrl),
@@ -446,7 +484,7 @@ getStateImageList(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxTreeCtrl_GetStateImageList,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Point::{X::integer(),Y::integer()}) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Point::{X::integer(),Y::integer()}) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlhittest">external documentation</a>.
hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY})
when is_integer(PointX),is_integer(PointY) ->
@@ -454,35 +492,17 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY})
wxe_util:call(?wxTreeCtrl_HitTest,
<<ThisRef:32/?UI,PointX:32/?UI,PointY:32/?UI>>).
-%% @spec (This::wxTreeCtrl(),Parent::wxTreeItemId(),X::integer()|wxTreeItemId(),Text::string()) -> wxTreeItemId()
-%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlinsertitem">external documentation</a>.
-%% <br /> Alternatives:
-%% <p><c>
-%% insertItem(This::wxTreeCtrl(), Parent::wxTreeItemId(), Pos::integer(), Text::string()) -> insertItem(This,Parent,Pos,Text, []) </c></p>
-%% <p><c>
-%% insertItem(This::wxTreeCtrl(), Parent::wxTreeItemId(), IdPrevious::wxTreeItemId(), Text::string()) -> insertItem(This,Parent,IdPrevious,Text, []) </c></p>
-
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Pos::integer(), Text::string()) -> integer()
+%% @equiv insertItem(This,Parent,Pos,Text, [])
insertItem(This,Parent,Pos,Text)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Pos),is_list(Text) ->
- insertItem(This,Parent,Pos,Text, []);
-
-insertItem(This,Parent,IdPrevious,Text)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_record(IdPrevious, wx_ref),is_list(Text) ->
- insertItem(This,Parent,IdPrevious,Text, []).
+ when is_record(This, wx_ref),is_integer(Parent),is_integer(Pos),is_list(Text) ->
+ insertItem(This,Parent,Pos,Text, []).
-%% @spec (This::wxTreeCtrl(),Parent::wxTreeItemId(),X::integer()|wxTreeItemId(),Text::string(),[Option]) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Pos::integer(), Text::string(), [Option]) -> integer()
+%% Option = {image, integer()} | {selImage, integer()} | {data, term()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlinsertitem">external documentation</a>.
-%% <br /> Alternatives:
-%% <p><c>
-%% insertItem(This::wxTreeCtrl(), Parent::wxTreeItemId(), Pos::integer(), Text::string(), [Option]) -> wxTreeItemId() </c>
-%%<br /> Option = {image, integer()} | {selImage, integer()} | {data, term()}
-%% </p>
-%% <p><c>
-%% insertItem(This::wxTreeCtrl(), Parent::wxTreeItemId(), IdPrevious::wxTreeItemId(), Text::string(), [Option]) -> wxTreeItemId() </c>
-%%<br /> Option = {image, integer()} | {selectedImage, integer()} | {data, term()}
-%% </p>
-insertItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentRef},Pos,Text, Options)
- when is_integer(Pos),is_list(Text),is_list(Options) ->
+insertItem(#wx_ref{type=ThisT,ref=ThisRef},Parent,Pos,Text, Options)
+ when is_integer(Parent),is_integer(Pos),is_list(Text),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({image, Image}, Acc) -> [<<1:32/?UI,Image:32/?UI>>|Acc];
@@ -490,66 +510,60 @@ insertItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentR
({data, Data}, Acc) -> wxe_util:send_bin(term_to_binary(Data)),[<<3:32/?UI,0:32>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
- wxe_util:call(?wxTreeCtrl_InsertItem_4_0,
- <<ThisRef:32/?UI,ParentRef:32/?UI,Pos:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>);
-insertItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentRef},#wx_ref{type=wxTreeItemId,ref=IdPreviousRef},Text, Options)
- when is_list(Text),is_list(Options) ->
- ?CLASS(ThisT,wxTreeCtrl),
- Text_UC = unicode:characters_to_binary([Text,0]),
- MOpts = fun({image, Image}, Acc) -> [<<1:32/?UI,Image:32/?UI>>|Acc];
- ({selectedImage, SelectedImage}, Acc) -> [<<2:32/?UI,SelectedImage:32/?UI>>|Acc];
- ({data, Data}, Acc) -> wxe_util:send_bin(term_to_binary(Data)),[<<3:32/?UI,0:32>>|Acc];
- (BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
- BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
- wxe_util:call(?wxTreeCtrl_InsertItem_4_1,
- <<ThisRef:32/?UI,ParentRef:32/?UI,IdPreviousRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
+ wxe_util:call(?wxTreeCtrl_InsertItem,
+ <<ThisRef:32/?UI,0:32,Parent:64/?UI,Pos:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlisbold">external documentation</a>.
-isBold(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+isBold(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_IsBold,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlisexpanded">external documentation</a>.
-isExpanded(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+isExpanded(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_IsExpanded,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlisselected">external documentation</a>.
-isSelected(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+isSelected(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_IsSelected,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlisvisible">external documentation</a>.
-isVisible(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+isVisible(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_IsVisible,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlitemhaschildren">external documentation</a>.
-itemHasChildren(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+itemHasChildren(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_ItemHasChildren,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Parent::wxTreeItemId(), Text::string()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Text::string()) -> integer()
%% @equiv prependItem(This,Parent,Text, [])
prependItem(This,Parent,Text)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Parent),is_list(Text) ->
prependItem(This,Parent,Text, []).
-%% @spec (This::wxTreeCtrl(), Parent::wxTreeItemId(), Text::string(), [Option]) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Text::string(), [Option]) -> integer()
%% Option = {image, integer()} | {selectedImage, integer()} | {data, term()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlprependitem">external documentation</a>.
-prependItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+prependItem(#wx_ref{type=ThisT,ref=ThisRef},Parent,Text, Options)
+ when is_integer(Parent),is_list(Text),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({image, Image}, Acc) -> [<<1:32/?UI,Image:32/?UI>>|Acc];
@@ -558,33 +572,35 @@ prependItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=Parent
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_PrependItem,
- <<ThisRef:32/?UI,ParentRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Parent:64/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlscrollto">external documentation</a>.
-scrollTo(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+scrollTo(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_ScrollTo,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlselectitem">external documentation</a>.
-selectItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+selectItem(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_SelectItem_1,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> ok
%% Option = {select, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlselectitem">external documentation</a>.
-selectItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+selectItem(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({select, Select}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Select)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:cast(?wxTreeCtrl_SelectItem_2,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
%% @spec (This::wxTreeCtrl(), Indent::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetindent">external documentation</a>.
@@ -602,122 +618,124 @@ setImageList(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ImageListT,ref=ImageLi
wxe_util:cast(?wxTreeCtrl_SetImageList,
<<ThisRef:32/?UI,ImageListRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Col::wx:colour()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Col::wx:colour()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitembackgroundcolour">external documentation</a>.
-setItemBackgroundColour(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Col)
- when tuple_size(Col) =:= 3; tuple_size(Col) =:= 4 ->
+setItemBackgroundColour(#wx_ref{type=ThisT,ref=ThisRef},Item,Col)
+ when is_integer(Item),tuple_size(Col) =:= 3; tuple_size(Col) =:= 4 ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_SetItemBackgroundColour,
- <<ThisRef:32/?UI,ItemRef:32/?UI,(wxe_util:colour_bin(Col)):16/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,(wxe_util:colour_bin(Col)):16/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @equiv setItemBold(This,Item, [])
setItemBold(This,Item)
- when is_record(This, wx_ref),is_record(Item, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Item) ->
setItemBold(This,Item, []).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> ok
%% Option = {bold, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitembold">external documentation</a>.
-setItemBold(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+setItemBold(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({bold, Bold}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Bold)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:cast(?wxTreeCtrl_SetItemBold,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Data::term()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Data::term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemdata">external documentation</a>.
-setItemData(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Data) ->
+setItemData(#wx_ref{type=ThisT,ref=ThisRef},Item,Data)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:send_bin(term_to_binary(Data)),
wxe_util:cast(?wxTreeCtrl_SetItemData,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @equiv setItemDropHighlight(This,Item, [])
setItemDropHighlight(This,Item)
- when is_record(This, wx_ref),is_record(Item, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Item) ->
setItemDropHighlight(This,Item, []).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> ok
%% Option = {highlight, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemdrophighlight">external documentation</a>.
-setItemDropHighlight(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+setItemDropHighlight(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({highlight, Highlight}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Highlight)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:cast(?wxTreeCtrl_SetItemDropHighlight,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Font::wxFont:wxFont()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Font::wxFont:wxFont()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemfont">external documentation</a>.
-setItemFont(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},#wx_ref{type=FontT,ref=FontRef}) ->
+setItemFont(#wx_ref{type=ThisT,ref=ThisRef},Item,#wx_ref{type=FontT,ref=FontRef})
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
?CLASS(FontT,wxFont),
wxe_util:cast(?wxTreeCtrl_SetItemFont,
- <<ThisRef:32/?UI,ItemRef:32/?UI,FontRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,FontRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @equiv setItemHasChildren(This,Item, [])
setItemHasChildren(This,Item)
- when is_record(This, wx_ref),is_record(Item, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Item) ->
setItemHasChildren(This,Item, []).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> ok
%% Option = {has, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemhaschildren">external documentation</a>.
-setItemHasChildren(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+setItemHasChildren(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({has, Has}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Has)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:cast(?wxTreeCtrl_SetItemHasChildren,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Image::integer()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Image::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemimage">external documentation</a>.
-setItemImage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Image)
- when is_integer(Image) ->
+setItemImage(#wx_ref{type=ThisT,ref=ThisRef},Item,Image)
+ when is_integer(Item),is_integer(Image) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_SetItemImage_2,
- <<ThisRef:32/?UI,ItemRef:32/?UI,Image:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,Image:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Image::integer(), [Option]) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Image::integer(), [Option]) -> ok
%% Option = {which, WxTreeItemIcon}
%% WxTreeItemIcon = integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemimage">external documentation</a>.
%%<br /> WxTreeItemIcon is one of ?wxTreeItemIcon_Normal | ?wxTreeItemIcon_Selected | ?wxTreeItemIcon_Expanded | ?wxTreeItemIcon_SelectedExpanded | ?wxTreeItemIcon_Max
-setItemImage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Image, Options)
- when is_integer(Image),is_list(Options) ->
+setItemImage(#wx_ref{type=ThisT,ref=ThisRef},Item,Image, Options)
+ when is_integer(Item),is_integer(Image),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({which, Which}, Acc) -> [<<1:32/?UI,Which:32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:cast(?wxTreeCtrl_SetItemImage_3,
- <<ThisRef:32/?UI,ItemRef:32/?UI,Image:32/?UI, 0:32,BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,Image:32/?UI, 0:32,BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Text::string()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Text::string()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemtext">external documentation</a>.
-setItemText(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Text)
- when is_list(Text) ->
+setItemText(#wx_ref{type=ThisT,ref=ThisRef},Item,Text)
+ when is_integer(Item),is_list(Text) ->
?CLASS(ThisT,wxTreeCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxTreeCtrl_SetItemText,
- <<ThisRef:32/?UI,ItemRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Col::wx:colour()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Col::wx:colour()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemtextcolour">external documentation</a>.
-setItemTextColour(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Col)
- when tuple_size(Col) =:= 3; tuple_size(Col) =:= 4 ->
+setItemTextColour(#wx_ref{type=ThisT,ref=ThisRef},Item,Col)
+ when is_integer(Item),tuple_size(Col) =:= 3; tuple_size(Col) =:= 4 ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_SetItemTextColour,
- <<ThisRef:32/?UI,ItemRef:32/?UI,(wxe_util:colour_bin(Col)):16/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,(wxe_util:colour_bin(Col)):16/binary>>).
%% @spec (This::wxTreeCtrl(), ImageList::wxImageList:wxImageList()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetstateimagelist">external documentation</a>.
@@ -735,26 +753,29 @@ setWindowStyle(#wx_ref{type=ThisT,ref=ThisRef},Styles)
wxe_util:cast(?wxTreeCtrl_SetWindowStyle,
<<ThisRef:32/?UI,Styles:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsortchildren">external documentation</a>.
-sortChildren(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+sortChildren(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_SortChildren,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrltoggle">external documentation</a>.
-toggle(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+toggle(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_Toggle,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrltoggleitemselection">external documentation</a>.
-toggleItemSelection(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+toggleItemSelection(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_ToggleItemSelection,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
%% @spec (This::wxTreeCtrl()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlunselect">external documentation</a>.
@@ -770,12 +791,13 @@ unselectAll(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:cast(?wxTreeCtrl_UnselectAll,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlunselectitem">external documentation</a>.
-unselectItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+unselectItem(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_UnselectItem,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
%% @spec (This::wxTreeCtrl()) -> ok
%% @doc Destroys this object, do not use object again
diff --git a/lib/wx/src/gen/wxTreeEvent.erl b/lib/wx/src/gen/wxTreeEvent.erl
index 3f20e79b22..11e442b0f3 100644
--- a/lib/wx/src/gen/wxTreeEvent.erl
+++ b/lib/wx/src/gen/wxTreeEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
@@ -55,7 +55,7 @@ getKeyCode(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxTreeEvent_GetKeyCode,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeEvent()) -> wxTreeItemId()
+%% @spec (This::wxTreeEvent()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreeevent.html#wxtreeeventgetitem">external documentation</a>.
getItem(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeEvent),
@@ -76,7 +76,7 @@ getLabel(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxTreeEvent_GetLabel,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeEvent()) -> wxTreeItemId()
+%% @spec (This::wxTreeEvent()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreeevent.html#wxtreeeventgetolditem">external documentation</a>.
getOldItem(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeEvent),
diff --git a/lib/wx/src/gen/wxTreebook.erl b/lib/wx/src/gen/wxTreebook.erl
index 34b16a1cc6..2117388623 100644
--- a/lib/wx/src/gen/wxTreebook.erl
+++ b/lib/wx/src/gen/wxTreebook.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxUpdateUIEvent.erl b/lib/wx/src/gen/wxUpdateUIEvent.erl
index eddccd3575..9dd4c5caf9 100644
--- a/lib/wx/src/gen/wxUpdateUIEvent.erl
+++ b/lib/wx/src/gen/wxUpdateUIEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxWindow.erl b/lib/wx/src/gen/wxWindow.erl
index d431696660..be9727757c 100644
--- a/lib/wx/src/gen/wxWindow.erl
+++ b/lib/wx/src/gen/wxWindow.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxWindowCreateEvent.erl b/lib/wx/src/gen/wxWindowCreateEvent.erl
index 0503bdfef4..fa58999b92 100644
--- a/lib/wx/src/gen/wxWindowCreateEvent.erl
+++ b/lib/wx/src/gen/wxWindowCreateEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxWindowDC.erl b/lib/wx/src/gen/wxWindowDC.erl
index 63b2249844..a441d178da 100644
--- a/lib/wx/src/gen/wxWindowDC.erl
+++ b/lib/wx/src/gen/wxWindowDC.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxWindowDestroyEvent.erl b/lib/wx/src/gen/wxWindowDestroyEvent.erl
index 8d98b36f68..40ec93af5d 100644
--- a/lib/wx/src/gen/wxWindowDestroyEvent.erl
+++ b/lib/wx/src/gen/wxWindowDestroyEvent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxXmlResource.erl b/lib/wx/src/gen/wxXmlResource.erl
index c9f396e608..3a7070e2c1 100644
--- a/lib/wx/src/gen/wxXmlResource.erl
+++ b/lib/wx/src/gen/wxXmlResource.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wx_misc.erl b/lib/wx/src/gen/wx_misc.erl
index ef50e22e99..cf23d4cf8b 100644
--- a/lib/wx/src/gen/wx_misc.erl
+++ b/lib/wx/src/gen/wx_misc.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxe_debug.hrl b/lib/wx/src/gen/wxe_debug.hrl
index 11f5b9e781..c325170dbb 100644
--- a/lib/wx/src/gen/wxe_debug.hrl
+++ b/lib/wx/src/gen/wxe_debug.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
@@ -1842,1438 +1842,1439 @@ wxdebug_table() ->
{2015, {wxTreeCtrl, getChildrenCount, 2}},
{2016, {wxTreeCtrl, getCount, 0}},
{2017, {wxTreeCtrl, getEditControl, 0}},
- {2018, {wxTreeCtrl, getFirstVisibleItem, 0}},
- {2019, {wxTreeCtrl, getImageList, 0}},
- {2020, {wxTreeCtrl, getIndent, 0}},
- {2021, {wxTreeCtrl, getItemBackgroundColour, 1}},
- {2022, {wxTreeCtrl, getItemData, 1}},
- {2023, {wxTreeCtrl, getItemFont, 1}},
- {2024, {wxTreeCtrl, getItemImage_1, 1}},
- {2025, {wxTreeCtrl, getItemImage_2, 2}},
- {2026, {wxTreeCtrl, getItemText, 1}},
- {2027, {wxTreeCtrl, getItemTextColour, 1}},
- {2028, {wxTreeCtrl, getLastChild, 1}},
- {2029, {wxTreeCtrl, getNextSibling, 1}},
- {2030, {wxTreeCtrl, getNextVisible, 1}},
- {2031, {wxTreeCtrl, getItemParent, 1}},
- {2032, {wxTreeCtrl, getPrevSibling, 1}},
- {2033, {wxTreeCtrl, getPrevVisible, 1}},
- {2034, {wxTreeCtrl, getRootItem, 0}},
- {2035, {wxTreeCtrl, getSelection, 0}},
- {2036, {wxTreeCtrl, getSelections, 1}},
- {2037, {wxTreeCtrl, getStateImageList, 0}},
- {2038, {wxTreeCtrl, hitTest, 1}},
- {2039, {wxTreeCtrl, insertItem_4_1, 4}},
- {2040, {wxTreeCtrl, insertItem_4_0, 4}},
- {2041, {wxTreeCtrl, isBold, 1}},
- {2042, {wxTreeCtrl, isExpanded, 1}},
- {2043, {wxTreeCtrl, isSelected, 1}},
- {2044, {wxTreeCtrl, isVisible, 1}},
- {2045, {wxTreeCtrl, itemHasChildren, 1}},
- {2046, {wxTreeCtrl, prependItem, 3}},
- {2047, {wxTreeCtrl, scrollTo, 1}},
- {2048, {wxTreeCtrl, selectItem_1, 1}},
- {2049, {wxTreeCtrl, selectItem_2, 2}},
- {2050, {wxTreeCtrl, setIndent, 1}},
- {2051, {wxTreeCtrl, setImageList, 1}},
- {2052, {wxTreeCtrl, setItemBackgroundColour, 2}},
- {2053, {wxTreeCtrl, setItemBold, 2}},
- {2054, {wxTreeCtrl, setItemData, 2}},
- {2055, {wxTreeCtrl, setItemDropHighlight, 2}},
- {2056, {wxTreeCtrl, setItemFont, 2}},
- {2057, {wxTreeCtrl, setItemHasChildren, 2}},
- {2058, {wxTreeCtrl, setItemImage_2, 2}},
- {2059, {wxTreeCtrl, setItemImage_3, 3}},
- {2060, {wxTreeCtrl, setItemText, 2}},
- {2061, {wxTreeCtrl, setItemTextColour, 2}},
- {2062, {wxTreeCtrl, setStateImageList, 1}},
- {2063, {wxTreeCtrl, setWindowStyle, 1}},
- {2064, {wxTreeCtrl, sortChildren, 1}},
- {2065, {wxTreeCtrl, toggle, 1}},
- {2066, {wxTreeCtrl, toggleItemSelection, 1}},
- {2067, {wxTreeCtrl, unselect, 0}},
- {2068, {wxTreeCtrl, unselectAll, 0}},
- {2069, {wxTreeCtrl, unselectItem, 1}},
- {2070, {wxScrollBar, new_0, 0}},
- {2071, {wxScrollBar, new_3, 3}},
- {2072, {wxScrollBar, destruct, 0}},
- {2073, {wxScrollBar, create, 3}},
- {2074, {wxScrollBar, getRange, 0}},
- {2075, {wxScrollBar, getPageSize, 0}},
- {2076, {wxScrollBar, getThumbPosition, 0}},
- {2077, {wxScrollBar, getThumbSize, 0}},
- {2078, {wxScrollBar, setThumbPosition, 1}},
- {2079, {wxScrollBar, setScrollbar, 5}},
- {2081, {wxSpinButton, new_2, 2}},
- {2082, {wxSpinButton, new_0, 0}},
- {2083, {wxSpinButton, create, 2}},
- {2084, {wxSpinButton, getMax, 0}},
- {2085, {wxSpinButton, getMin, 0}},
- {2086, {wxSpinButton, getValue, 0}},
- {2087, {wxSpinButton, setRange, 2}},
- {2088, {wxSpinButton, setValue, 1}},
- {2089, {wxSpinButton, 'Destroy', undefined}},
- {2090, {wxSpinCtrl, new_0, 0}},
- {2091, {wxSpinCtrl, new_2, 2}},
- {2093, {wxSpinCtrl, create, 2}},
- {2096, {wxSpinCtrl, setValue_1_1, 1}},
- {2097, {wxSpinCtrl, setValue_1_0, 1}},
- {2099, {wxSpinCtrl, getValue, 0}},
- {2101, {wxSpinCtrl, setRange, 2}},
- {2102, {wxSpinCtrl, setSelection, 2}},
- {2104, {wxSpinCtrl, getMin, 0}},
- {2106, {wxSpinCtrl, getMax, 0}},
- {2107, {wxSpinCtrl, 'Destroy', undefined}},
- {2108, {wxStaticText, new_0, 0}},
- {2109, {wxStaticText, new_4, 4}},
- {2110, {wxStaticText, create, 4}},
- {2111, {wxStaticText, getLabel, 0}},
- {2112, {wxStaticText, setLabel, 1}},
- {2113, {wxStaticText, wrap, 1}},
- {2114, {wxStaticText, 'Destroy', undefined}},
- {2115, {wxStaticBitmap, new_0, 0}},
- {2116, {wxStaticBitmap, new_4, 4}},
- {2117, {wxStaticBitmap, create, 4}},
- {2118, {wxStaticBitmap, getBitmap, 0}},
- {2119, {wxStaticBitmap, setBitmap, 1}},
- {2120, {wxStaticBitmap, 'Destroy', undefined}},
- {2121, {wxRadioBox, new, 7}},
- {2123, {wxRadioBox, destruct, 0}},
- {2124, {wxRadioBox, create, 7}},
- {2125, {wxRadioBox, enable_2, 2}},
- {2126, {wxRadioBox, enable_1, 1}},
- {2127, {wxRadioBox, getSelection, 0}},
- {2128, {wxRadioBox, getString, 1}},
- {2129, {wxRadioBox, setSelection, 1}},
- {2130, {wxRadioBox, show_2, 2}},
- {2131, {wxRadioBox, show_1, 1}},
- {2132, {wxRadioBox, getColumnCount, 0}},
- {2133, {wxRadioBox, getItemHelpText, 1}},
- {2134, {wxRadioBox, getItemToolTip, 1}},
- {2136, {wxRadioBox, getItemFromPoint, 1}},
- {2137, {wxRadioBox, getRowCount, 0}},
- {2138, {wxRadioBox, isItemEnabled, 1}},
- {2139, {wxRadioBox, isItemShown, 1}},
- {2140, {wxRadioBox, setItemHelpText, 2}},
- {2141, {wxRadioBox, setItemToolTip, 2}},
- {2142, {wxRadioButton, new_0, 0}},
- {2143, {wxRadioButton, new_4, 4}},
- {2144, {wxRadioButton, create, 4}},
- {2145, {wxRadioButton, getValue, 0}},
- {2146, {wxRadioButton, setValue, 1}},
- {2147, {wxRadioButton, 'Destroy', undefined}},
- {2149, {wxSlider, new_6, 6}},
- {2150, {wxSlider, new_0, 0}},
- {2151, {wxSlider, create, 6}},
- {2152, {wxSlider, getLineSize, 0}},
- {2153, {wxSlider, getMax, 0}},
- {2154, {wxSlider, getMin, 0}},
- {2155, {wxSlider, getPageSize, 0}},
- {2156, {wxSlider, getThumbLength, 0}},
- {2157, {wxSlider, getValue, 0}},
- {2158, {wxSlider, setLineSize, 1}},
- {2159, {wxSlider, setPageSize, 1}},
- {2160, {wxSlider, setRange, 2}},
- {2161, {wxSlider, setThumbLength, 1}},
- {2162, {wxSlider, setValue, 1}},
- {2163, {wxSlider, 'Destroy', undefined}},
- {2165, {wxDialog, new_4, 4}},
- {2166, {wxDialog, new_0, 0}},
- {2168, {wxDialog, destruct, 0}},
- {2169, {wxDialog, create, 4}},
- {2170, {wxDialog, createButtonSizer, 1}},
- {2171, {wxDialog, createStdDialogButtonSizer, 1}},
- {2172, {wxDialog, endModal, 1}},
- {2173, {wxDialog, getAffirmativeId, 0}},
- {2174, {wxDialog, getReturnCode, 0}},
- {2175, {wxDialog, isModal, 0}},
- {2176, {wxDialog, setAffirmativeId, 1}},
- {2177, {wxDialog, setReturnCode, 1}},
- {2178, {wxDialog, show, 1}},
- {2179, {wxDialog, showModal, 0}},
- {2180, {wxColourDialog, new_0, 0}},
- {2181, {wxColourDialog, new_2, 2}},
- {2182, {wxColourDialog, destruct, 0}},
- {2183, {wxColourDialog, create, 2}},
- {2184, {wxColourDialog, getColourData, 0}},
- {2185, {wxColourData, new_0, 0}},
- {2186, {wxColourData, new_1, 1}},
- {2187, {wxColourData, destruct, 0}},
- {2188, {wxColourData, getChooseFull, 0}},
- {2189, {wxColourData, getColour, 0}},
- {2191, {wxColourData, getCustomColour, 1}},
- {2192, {wxColourData, setChooseFull, 1}},
- {2193, {wxColourData, setColour, 1}},
- {2194, {wxColourData, setCustomColour, 2}},
- {2195, {wxPalette, new_0, 0}},
- {2196, {wxPalette, new_4, 4}},
- {2198, {wxPalette, destruct, 0}},
- {2199, {wxPalette, create, 4}},
- {2200, {wxPalette, getColoursCount, 0}},
- {2201, {wxPalette, getPixel, 3}},
- {2202, {wxPalette, getRGB, 4}},
- {2203, {wxPalette, isOk, 0}},
- {2207, {wxDirDialog, new, 2}},
- {2208, {wxDirDialog, destruct, 0}},
- {2209, {wxDirDialog, getPath, 0}},
- {2210, {wxDirDialog, getMessage, 0}},
- {2211, {wxDirDialog, setMessage, 1}},
- {2212, {wxDirDialog, setPath, 1}},
- {2216, {wxFileDialog, new, 2}},
- {2217, {wxFileDialog, destruct, 0}},
- {2218, {wxFileDialog, getDirectory, 0}},
- {2219, {wxFileDialog, getFilename, 0}},
- {2220, {wxFileDialog, getFilenames, 1}},
- {2221, {wxFileDialog, getFilterIndex, 0}},
- {2222, {wxFileDialog, getMessage, 0}},
- {2223, {wxFileDialog, getPath, 0}},
- {2224, {wxFileDialog, getPaths, 1}},
- {2225, {wxFileDialog, getWildcard, 0}},
- {2226, {wxFileDialog, setDirectory, 1}},
- {2227, {wxFileDialog, setFilename, 1}},
- {2228, {wxFileDialog, setFilterIndex, 1}},
- {2229, {wxFileDialog, setMessage, 1}},
- {2230, {wxFileDialog, setPath, 1}},
- {2231, {wxFileDialog, setWildcard, 1}},
- {2232, {wxPickerBase, setInternalMargin, 1}},
- {2233, {wxPickerBase, getInternalMargin, 0}},
- {2234, {wxPickerBase, setTextCtrlProportion, 1}},
- {2235, {wxPickerBase, setPickerCtrlProportion, 1}},
- {2236, {wxPickerBase, getTextCtrlProportion, 0}},
- {2237, {wxPickerBase, getPickerCtrlProportion, 0}},
- {2238, {wxPickerBase, hasTextCtrl, 0}},
- {2239, {wxPickerBase, getTextCtrl, 0}},
- {2240, {wxPickerBase, isTextCtrlGrowable, 0}},
- {2241, {wxPickerBase, setPickerCtrlGrowable, 1}},
- {2242, {wxPickerBase, setTextCtrlGrowable, 1}},
- {2243, {wxPickerBase, isPickerCtrlGrowable, 0}},
- {2244, {wxFilePickerCtrl, new_0, 0}},
- {2245, {wxFilePickerCtrl, new_3, 3}},
- {2246, {wxFilePickerCtrl, create, 3}},
- {2247, {wxFilePickerCtrl, getPath, 0}},
- {2248, {wxFilePickerCtrl, setPath, 1}},
- {2249, {wxFilePickerCtrl, 'Destroy', undefined}},
- {2250, {wxDirPickerCtrl, new_0, 0}},
- {2251, {wxDirPickerCtrl, new_3, 3}},
- {2252, {wxDirPickerCtrl, create, 3}},
- {2253, {wxDirPickerCtrl, getPath, 0}},
- {2254, {wxDirPickerCtrl, setPath, 1}},
- {2255, {wxDirPickerCtrl, 'Destroy', undefined}},
- {2256, {wxColourPickerCtrl, new_0, 0}},
- {2257, {wxColourPickerCtrl, new_3, 3}},
- {2258, {wxColourPickerCtrl, create, 3}},
- {2259, {wxColourPickerCtrl, getColour, 0}},
- {2260, {wxColourPickerCtrl, setColour_1_1, 1}},
- {2261, {wxColourPickerCtrl, setColour_1_0, 1}},
- {2262, {wxColourPickerCtrl, 'Destroy', undefined}},
- {2263, {wxDatePickerCtrl, new_0, 0}},
- {2264, {wxDatePickerCtrl, new_3, 3}},
- {2265, {wxDatePickerCtrl, getRange, 2}},
- {2266, {wxDatePickerCtrl, getValue, 0}},
- {2267, {wxDatePickerCtrl, setRange, 2}},
- {2268, {wxDatePickerCtrl, setValue, 1}},
- {2269, {wxDatePickerCtrl, 'Destroy', undefined}},
- {2270, {wxFontPickerCtrl, new_0, 0}},
- {2271, {wxFontPickerCtrl, new_3, 3}},
- {2272, {wxFontPickerCtrl, create, 3}},
- {2273, {wxFontPickerCtrl, getSelectedFont, 0}},
- {2274, {wxFontPickerCtrl, setSelectedFont, 1}},
- {2275, {wxFontPickerCtrl, getMaxPointSize, 0}},
- {2276, {wxFontPickerCtrl, setMaxPointSize, 1}},
- {2277, {wxFontPickerCtrl, 'Destroy', undefined}},
- {2280, {wxFindReplaceDialog, new_0, 0}},
- {2281, {wxFindReplaceDialog, new_4, 4}},
- {2282, {wxFindReplaceDialog, destruct, 0}},
- {2283, {wxFindReplaceDialog, create, 4}},
- {2284, {wxFindReplaceDialog, getData, 0}},
- {2285, {wxFindReplaceData, new_0, 0}},
- {2286, {wxFindReplaceData, new_1, 1}},
- {2287, {wxFindReplaceData, getFindString, 0}},
- {2288, {wxFindReplaceData, getReplaceString, 0}},
- {2289, {wxFindReplaceData, getFlags, 0}},
- {2290, {wxFindReplaceData, setFlags, 1}},
- {2291, {wxFindReplaceData, setFindString, 1}},
- {2292, {wxFindReplaceData, setReplaceString, 1}},
- {2293, {wxFindReplaceData, 'Destroy', undefined}},
- {2294, {wxMultiChoiceDialog, new_0, 0}},
- {2296, {wxMultiChoiceDialog, new_5, 5}},
- {2297, {wxMultiChoiceDialog, getSelections, 0}},
- {2298, {wxMultiChoiceDialog, setSelections, 1}},
- {2299, {wxMultiChoiceDialog, 'Destroy', undefined}},
- {2300, {wxSingleChoiceDialog, new_0, 0}},
- {2302, {wxSingleChoiceDialog, new_5, 5}},
- {2303, {wxSingleChoiceDialog, getSelection, 0}},
- {2304, {wxSingleChoiceDialog, getStringSelection, 0}},
- {2305, {wxSingleChoiceDialog, setSelection, 1}},
- {2306, {wxSingleChoiceDialog, 'Destroy', undefined}},
- {2307, {wxTextEntryDialog, new, 3}},
- {2308, {wxTextEntryDialog, getValue, 0}},
- {2309, {wxTextEntryDialog, setValue, 1}},
- {2310, {wxTextEntryDialog, 'Destroy', undefined}},
- {2311, {wxPasswordEntryDialog, new, 3}},
- {2312, {wxPasswordEntryDialog, 'Destroy', undefined}},
- {2313, {wxFontData, new_0, 0}},
- {2314, {wxFontData, new_1, 1}},
- {2315, {wxFontData, destruct, 0}},
- {2316, {wxFontData, enableEffects, 1}},
- {2317, {wxFontData, getAllowSymbols, 0}},
- {2318, {wxFontData, getColour, 0}},
- {2319, {wxFontData, getChosenFont, 0}},
- {2320, {wxFontData, getEnableEffects, 0}},
- {2321, {wxFontData, getInitialFont, 0}},
- {2322, {wxFontData, getShowHelp, 0}},
- {2323, {wxFontData, setAllowSymbols, 1}},
- {2324, {wxFontData, setChosenFont, 1}},
- {2325, {wxFontData, setColour, 1}},
- {2326, {wxFontData, setInitialFont, 1}},
- {2327, {wxFontData, setRange, 2}},
- {2328, {wxFontData, setShowHelp, 1}},
- {2332, {wxFontDialog, new_0, 0}},
- {2334, {wxFontDialog, new_2, 2}},
- {2336, {wxFontDialog, create, 2}},
- {2337, {wxFontDialog, getFontData, 0}},
- {2339, {wxFontDialog, 'Destroy', undefined}},
- {2340, {wxProgressDialog, new, 3}},
- {2341, {wxProgressDialog, destruct, 0}},
- {2342, {wxProgressDialog, resume, 0}},
- {2343, {wxProgressDialog, update_2, 2}},
- {2344, {wxProgressDialog, update_0, 0}},
- {2345, {wxMessageDialog, new, 3}},
- {2346, {wxMessageDialog, destruct, 0}},
- {2347, {wxPageSetupDialog, new, 2}},
- {2348, {wxPageSetupDialog, destruct, 0}},
- {2349, {wxPageSetupDialog, getPageSetupData, 0}},
- {2350, {wxPageSetupDialog, showModal, 0}},
- {2351, {wxPageSetupDialogData, new_0, 0}},
- {2352, {wxPageSetupDialogData, new_1_0, 1}},
- {2353, {wxPageSetupDialogData, new_1_1, 1}},
- {2354, {wxPageSetupDialogData, destruct, 0}},
- {2355, {wxPageSetupDialogData, enableHelp, 1}},
- {2356, {wxPageSetupDialogData, enableMargins, 1}},
- {2357, {wxPageSetupDialogData, enableOrientation, 1}},
- {2358, {wxPageSetupDialogData, enablePaper, 1}},
- {2359, {wxPageSetupDialogData, enablePrinter, 1}},
- {2360, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
- {2361, {wxPageSetupDialogData, getEnableMargins, 0}},
- {2362, {wxPageSetupDialogData, getEnableOrientation, 0}},
- {2363, {wxPageSetupDialogData, getEnablePaper, 0}},
- {2364, {wxPageSetupDialogData, getEnablePrinter, 0}},
- {2365, {wxPageSetupDialogData, getEnableHelp, 0}},
- {2366, {wxPageSetupDialogData, getDefaultInfo, 0}},
- {2367, {wxPageSetupDialogData, getMarginTopLeft, 0}},
- {2368, {wxPageSetupDialogData, getMarginBottomRight, 0}},
- {2369, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
- {2370, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
- {2371, {wxPageSetupDialogData, getPaperId, 0}},
- {2372, {wxPageSetupDialogData, getPaperSize, 0}},
- {2374, {wxPageSetupDialogData, getPrintData, 0}},
- {2375, {wxPageSetupDialogData, isOk, 0}},
- {2376, {wxPageSetupDialogData, setDefaultInfo, 1}},
- {2377, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
- {2378, {wxPageSetupDialogData, setMarginTopLeft, 1}},
- {2379, {wxPageSetupDialogData, setMarginBottomRight, 1}},
- {2380, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
- {2381, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
- {2382, {wxPageSetupDialogData, setPaperId, 1}},
- {2383, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
- {2384, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
- {2385, {wxPageSetupDialogData, setPrintData, 1}},
- {2386, {wxPrintDialog, new_2_0, 2}},
- {2387, {wxPrintDialog, new_2_1, 2}},
- {2388, {wxPrintDialog, destruct, 0}},
- {2389, {wxPrintDialog, getPrintDialogData, 0}},
- {2390, {wxPrintDialog, getPrintDC, 0}},
- {2391, {wxPrintDialogData, new_0, 0}},
- {2392, {wxPrintDialogData, new_1_1, 1}},
- {2393, {wxPrintDialogData, new_1_0, 1}},
- {2394, {wxPrintDialogData, destruct, 0}},
- {2395, {wxPrintDialogData, enableHelp, 1}},
- {2396, {wxPrintDialogData, enablePageNumbers, 1}},
- {2397, {wxPrintDialogData, enablePrintToFile, 1}},
- {2398, {wxPrintDialogData, enableSelection, 1}},
- {2399, {wxPrintDialogData, getAllPages, 0}},
- {2400, {wxPrintDialogData, getCollate, 0}},
- {2401, {wxPrintDialogData, getFromPage, 0}},
- {2402, {wxPrintDialogData, getMaxPage, 0}},
- {2403, {wxPrintDialogData, getMinPage, 0}},
- {2404, {wxPrintDialogData, getNoCopies, 0}},
- {2405, {wxPrintDialogData, getPrintData, 0}},
- {2406, {wxPrintDialogData, getPrintToFile, 0}},
- {2407, {wxPrintDialogData, getSelection, 0}},
- {2408, {wxPrintDialogData, getToPage, 0}},
- {2409, {wxPrintDialogData, isOk, 0}},
- {2410, {wxPrintDialogData, setCollate, 1}},
- {2411, {wxPrintDialogData, setFromPage, 1}},
- {2412, {wxPrintDialogData, setMaxPage, 1}},
- {2413, {wxPrintDialogData, setMinPage, 1}},
- {2414, {wxPrintDialogData, setNoCopies, 1}},
- {2415, {wxPrintDialogData, setPrintData, 1}},
- {2416, {wxPrintDialogData, setPrintToFile, 1}},
- {2417, {wxPrintDialogData, setSelection, 1}},
- {2418, {wxPrintDialogData, setToPage, 1}},
- {2419, {wxPrintData, new_0, 0}},
- {2420, {wxPrintData, new_1, 1}},
- {2421, {wxPrintData, destruct, 0}},
- {2422, {wxPrintData, getCollate, 0}},
- {2423, {wxPrintData, getBin, 0}},
- {2424, {wxPrintData, getColour, 0}},
- {2425, {wxPrintData, getDuplex, 0}},
- {2426, {wxPrintData, getNoCopies, 0}},
- {2427, {wxPrintData, getOrientation, 0}},
- {2428, {wxPrintData, getPaperId, 0}},
- {2429, {wxPrintData, getPrinterName, 0}},
- {2430, {wxPrintData, getQuality, 0}},
- {2431, {wxPrintData, isOk, 0}},
- {2432, {wxPrintData, setBin, 1}},
- {2433, {wxPrintData, setCollate, 1}},
- {2434, {wxPrintData, setColour, 1}},
- {2435, {wxPrintData, setDuplex, 1}},
- {2436, {wxPrintData, setNoCopies, 1}},
- {2437, {wxPrintData, setOrientation, 1}},
- {2438, {wxPrintData, setPaperId, 1}},
- {2439, {wxPrintData, setPrinterName, 1}},
- {2440, {wxPrintData, setQuality, 1}},
- {2443, {wxPrintPreview, new_2, 2}},
- {2444, {wxPrintPreview, new_3, 3}},
- {2446, {wxPrintPreview, destruct, 0}},
- {2447, {wxPrintPreview, getCanvas, 0}},
- {2448, {wxPrintPreview, getCurrentPage, 0}},
- {2449, {wxPrintPreview, getFrame, 0}},
- {2450, {wxPrintPreview, getMaxPage, 0}},
- {2451, {wxPrintPreview, getMinPage, 0}},
- {2452, {wxPrintPreview, getPrintout, 0}},
- {2453, {wxPrintPreview, getPrintoutForPrinting, 0}},
- {2454, {wxPrintPreview, isOk, 0}},
- {2455, {wxPrintPreview, paintPage, 2}},
- {2456, {wxPrintPreview, print, 1}},
- {2457, {wxPrintPreview, renderPage, 1}},
- {2458, {wxPrintPreview, setCanvas, 1}},
- {2459, {wxPrintPreview, setCurrentPage, 1}},
- {2460, {wxPrintPreview, setFrame, 1}},
- {2461, {wxPrintPreview, setPrintout, 1}},
- {2462, {wxPrintPreview, setZoom, 1}},
- {2463, {wxPreviewFrame, new, 3}},
- {2464, {wxPreviewFrame, destruct, 0}},
- {2465, {wxPreviewFrame, createControlBar, 0}},
- {2466, {wxPreviewFrame, createCanvas, 0}},
- {2467, {wxPreviewFrame, initialize, 0}},
- {2468, {wxPreviewFrame, onCloseWindow, 1}},
- {2469, {wxPreviewControlBar, new, 4}},
- {2470, {wxPreviewControlBar, destruct, 0}},
- {2471, {wxPreviewControlBar, createButtons, 0}},
- {2472, {wxPreviewControlBar, getPrintPreview, 0}},
- {2473, {wxPreviewControlBar, getZoomControl, 0}},
- {2474, {wxPreviewControlBar, setZoomControl, 1}},
- {2476, {wxPrinter, new, 1}},
- {2477, {wxPrinter, createAbortWindow, 2}},
- {2478, {wxPrinter, getAbort, 0}},
- {2479, {wxPrinter, getLastError, 0}},
- {2480, {wxPrinter, getPrintDialogData, 0}},
- {2481, {wxPrinter, print, 3}},
- {2482, {wxPrinter, printDialog, 1}},
- {2483, {wxPrinter, reportError, 3}},
- {2484, {wxPrinter, setup, 1}},
- {2485, {wxPrinter, 'Destroy', undefined}},
- {2486, {wxXmlResource, new_1, 1}},
- {2487, {wxXmlResource, new_2, 2}},
- {2488, {wxXmlResource, destruct, 0}},
- {2489, {wxXmlResource, attachUnknownControl, 3}},
- {2490, {wxXmlResource, clearHandlers, 0}},
- {2491, {wxXmlResource, compareVersion, 4}},
- {2492, {wxXmlResource, get, 0}},
- {2493, {wxXmlResource, getFlags, 0}},
- {2494, {wxXmlResource, getVersion, 0}},
- {2495, {wxXmlResource, getXRCID, 2}},
- {2496, {wxXmlResource, initAllHandlers, 0}},
- {2497, {wxXmlResource, load, 1}},
- {2498, {wxXmlResource, loadBitmap, 1}},
- {2499, {wxXmlResource, loadDialog_2, 2}},
- {2500, {wxXmlResource, loadDialog_3, 3}},
- {2501, {wxXmlResource, loadFrame_2, 2}},
- {2502, {wxXmlResource, loadFrame_3, 3}},
- {2503, {wxXmlResource, loadIcon, 1}},
- {2504, {wxXmlResource, loadMenu, 1}},
- {2505, {wxXmlResource, loadMenuBar_2, 2}},
- {2506, {wxXmlResource, loadMenuBar_1, 1}},
- {2507, {wxXmlResource, loadPanel_2, 2}},
- {2508, {wxXmlResource, loadPanel_3, 3}},
- {2509, {wxXmlResource, loadToolBar, 2}},
- {2510, {wxXmlResource, set, 1}},
- {2511, {wxXmlResource, setFlags, 1}},
- {2512, {wxXmlResource, unload, 1}},
- {2513, {wxXmlResource, xrcctrl, 3}},
- {2514, {wxHtmlEasyPrinting, new, 1}},
- {2515, {wxHtmlEasyPrinting, destruct, 0}},
- {2516, {wxHtmlEasyPrinting, getPrintData, 0}},
- {2517, {wxHtmlEasyPrinting, getPageSetupData, 0}},
- {2518, {wxHtmlEasyPrinting, previewFile, 1}},
- {2519, {wxHtmlEasyPrinting, previewText, 2}},
- {2520, {wxHtmlEasyPrinting, printFile, 1}},
- {2521, {wxHtmlEasyPrinting, printText, 2}},
- {2522, {wxHtmlEasyPrinting, pageSetup, 0}},
- {2523, {wxHtmlEasyPrinting, setFonts, 3}},
- {2524, {wxHtmlEasyPrinting, setHeader, 2}},
- {2525, {wxHtmlEasyPrinting, setFooter, 2}},
- {2527, {wxGLCanvas, new_2, 2}},
- {2528, {wxGLCanvas, new_3_1, 3}},
- {2529, {wxGLCanvas, new_3_0, 3}},
- {2530, {wxGLCanvas, getContext, 0}},
- {2532, {wxGLCanvas, setCurrent, 0}},
- {2533, {wxGLCanvas, swapBuffers, 0}},
- {2534, {wxGLCanvas, 'Destroy', undefined}},
- {2535, {wxAuiManager, new, 1}},
- {2536, {wxAuiManager, destruct, 0}},
- {2537, {wxAuiManager, addPane_2_1, 2}},
- {2538, {wxAuiManager, addPane_3, 3}},
- {2539, {wxAuiManager, addPane_2_0, 2}},
- {2540, {wxAuiManager, detachPane, 1}},
- {2541, {wxAuiManager, getAllPanes, 0}},
- {2542, {wxAuiManager, getArtProvider, 0}},
- {2543, {wxAuiManager, getDockSizeConstraint, 2}},
- {2544, {wxAuiManager, getFlags, 0}},
- {2545, {wxAuiManager, getManagedWindow, 0}},
- {2546, {wxAuiManager, getManager, 1}},
- {2547, {wxAuiManager, getPane_1_1, 1}},
- {2548, {wxAuiManager, getPane_1_0, 1}},
- {2549, {wxAuiManager, hideHint, 0}},
- {2550, {wxAuiManager, insertPane, 3}},
- {2551, {wxAuiManager, loadPaneInfo, 2}},
- {2552, {wxAuiManager, loadPerspective, 2}},
- {2553, {wxAuiManager, savePaneInfo, 1}},
- {2554, {wxAuiManager, savePerspective, 0}},
- {2555, {wxAuiManager, setArtProvider, 1}},
- {2556, {wxAuiManager, setDockSizeConstraint, 2}},
- {2557, {wxAuiManager, setFlags, 1}},
- {2558, {wxAuiManager, setManagedWindow, 1}},
- {2559, {wxAuiManager, showHint, 1}},
- {2560, {wxAuiManager, unInit, 0}},
- {2561, {wxAuiManager, update, 0}},
- {2562, {wxAuiPaneInfo, new_0, 0}},
- {2563, {wxAuiPaneInfo, new_1, 1}},
- {2564, {wxAuiPaneInfo, destruct, 0}},
- {2565, {wxAuiPaneInfo, bestSize_1, 1}},
- {2566, {wxAuiPaneInfo, bestSize_2, 2}},
- {2567, {wxAuiPaneInfo, bottom, 0}},
- {2568, {wxAuiPaneInfo, bottomDockable, 1}},
- {2569, {wxAuiPaneInfo, caption, 1}},
- {2570, {wxAuiPaneInfo, captionVisible, 1}},
- {2571, {wxAuiPaneInfo, centre, 0}},
- {2572, {wxAuiPaneInfo, centrePane, 0}},
- {2573, {wxAuiPaneInfo, closeButton, 1}},
- {2574, {wxAuiPaneInfo, defaultPane, 0}},
- {2575, {wxAuiPaneInfo, destroyOnClose, 1}},
- {2576, {wxAuiPaneInfo, direction, 1}},
- {2577, {wxAuiPaneInfo, dock, 0}},
- {2578, {wxAuiPaneInfo, dockable, 1}},
- {2579, {wxAuiPaneInfo, fixed, 0}},
- {2580, {wxAuiPaneInfo, float, 0}},
- {2581, {wxAuiPaneInfo, floatable, 1}},
- {2582, {wxAuiPaneInfo, floatingPosition_1, 1}},
- {2583, {wxAuiPaneInfo, floatingPosition_2, 2}},
- {2584, {wxAuiPaneInfo, floatingSize_1, 1}},
- {2585, {wxAuiPaneInfo, floatingSize_2, 2}},
- {2586, {wxAuiPaneInfo, gripper, 1}},
- {2587, {wxAuiPaneInfo, gripperTop, 1}},
- {2588, {wxAuiPaneInfo, hasBorder, 0}},
- {2589, {wxAuiPaneInfo, hasCaption, 0}},
- {2590, {wxAuiPaneInfo, hasCloseButton, 0}},
- {2591, {wxAuiPaneInfo, hasFlag, 1}},
- {2592, {wxAuiPaneInfo, hasGripper, 0}},
- {2593, {wxAuiPaneInfo, hasGripperTop, 0}},
- {2594, {wxAuiPaneInfo, hasMaximizeButton, 0}},
- {2595, {wxAuiPaneInfo, hasMinimizeButton, 0}},
- {2596, {wxAuiPaneInfo, hasPinButton, 0}},
- {2597, {wxAuiPaneInfo, hide, 0}},
- {2598, {wxAuiPaneInfo, isBottomDockable, 0}},
- {2599, {wxAuiPaneInfo, isDocked, 0}},
- {2600, {wxAuiPaneInfo, isFixed, 0}},
- {2601, {wxAuiPaneInfo, isFloatable, 0}},
- {2602, {wxAuiPaneInfo, isFloating, 0}},
- {2603, {wxAuiPaneInfo, isLeftDockable, 0}},
- {2604, {wxAuiPaneInfo, isMovable, 0}},
- {2605, {wxAuiPaneInfo, isOk, 0}},
- {2606, {wxAuiPaneInfo, isResizable, 0}},
- {2607, {wxAuiPaneInfo, isRightDockable, 0}},
- {2608, {wxAuiPaneInfo, isShown, 0}},
- {2609, {wxAuiPaneInfo, isToolbar, 0}},
- {2610, {wxAuiPaneInfo, isTopDockable, 0}},
- {2611, {wxAuiPaneInfo, layer, 1}},
- {2612, {wxAuiPaneInfo, left, 0}},
- {2613, {wxAuiPaneInfo, leftDockable, 1}},
- {2614, {wxAuiPaneInfo, maxSize_1, 1}},
- {2615, {wxAuiPaneInfo, maxSize_2, 2}},
- {2616, {wxAuiPaneInfo, maximizeButton, 1}},
- {2617, {wxAuiPaneInfo, minSize_1, 1}},
- {2618, {wxAuiPaneInfo, minSize_2, 2}},
- {2619, {wxAuiPaneInfo, minimizeButton, 1}},
- {2620, {wxAuiPaneInfo, movable, 1}},
- {2621, {wxAuiPaneInfo, name, 1}},
- {2622, {wxAuiPaneInfo, paneBorder, 1}},
- {2623, {wxAuiPaneInfo, pinButton, 1}},
- {2624, {wxAuiPaneInfo, position, 1}},
- {2625, {wxAuiPaneInfo, resizable, 1}},
- {2626, {wxAuiPaneInfo, right, 0}},
- {2627, {wxAuiPaneInfo, rightDockable, 1}},
- {2628, {wxAuiPaneInfo, row, 1}},
- {2629, {wxAuiPaneInfo, safeSet, 1}},
- {2630, {wxAuiPaneInfo, setFlag, 2}},
- {2631, {wxAuiPaneInfo, show, 1}},
- {2632, {wxAuiPaneInfo, toolbarPane, 0}},
- {2633, {wxAuiPaneInfo, top, 0}},
- {2634, {wxAuiPaneInfo, topDockable, 1}},
- {2635, {wxAuiPaneInfo, window, 1}},
- {2636, {wxAuiNotebook, new_0, 0}},
- {2637, {wxAuiNotebook, new_2, 2}},
- {2638, {wxAuiNotebook, addPage, 3}},
- {2639, {wxAuiNotebook, create, 2}},
- {2640, {wxAuiNotebook, deletePage, 1}},
- {2641, {wxAuiNotebook, getArtProvider, 0}},
- {2642, {wxAuiNotebook, getPage, 1}},
- {2643, {wxAuiNotebook, getPageBitmap, 1}},
- {2644, {wxAuiNotebook, getPageCount, 0}},
- {2645, {wxAuiNotebook, getPageIndex, 1}},
- {2646, {wxAuiNotebook, getPageText, 1}},
- {2647, {wxAuiNotebook, getSelection, 0}},
- {2648, {wxAuiNotebook, insertPage, 4}},
- {2649, {wxAuiNotebook, removePage, 1}},
- {2650, {wxAuiNotebook, setArtProvider, 1}},
- {2651, {wxAuiNotebook, setFont, 1}},
- {2652, {wxAuiNotebook, setPageBitmap, 2}},
- {2653, {wxAuiNotebook, setPageText, 2}},
- {2654, {wxAuiNotebook, setSelection, 1}},
- {2655, {wxAuiNotebook, setTabCtrlHeight, 1}},
- {2656, {wxAuiNotebook, setUniformBitmapSize, 1}},
- {2657, {wxAuiNotebook, 'Destroy', undefined}},
- {2658, {wxMDIParentFrame, new_0, 0}},
- {2659, {wxMDIParentFrame, new_4, 4}},
- {2660, {wxMDIParentFrame, destruct, 0}},
- {2661, {wxMDIParentFrame, activateNext, 0}},
- {2662, {wxMDIParentFrame, activatePrevious, 0}},
- {2663, {wxMDIParentFrame, arrangeIcons, 0}},
- {2664, {wxMDIParentFrame, cascade, 0}},
- {2665, {wxMDIParentFrame, create, 4}},
- {2666, {wxMDIParentFrame, getActiveChild, 0}},
- {2667, {wxMDIParentFrame, getClientWindow, 0}},
- {2668, {wxMDIParentFrame, tile, 1}},
- {2669, {wxMDIChildFrame, new_0, 0}},
- {2670, {wxMDIChildFrame, new_4, 4}},
- {2671, {wxMDIChildFrame, destruct, 0}},
- {2672, {wxMDIChildFrame, activate, 0}},
- {2673, {wxMDIChildFrame, create, 4}},
- {2674, {wxMDIChildFrame, maximize, 1}},
- {2675, {wxMDIChildFrame, restore, 0}},
- {2676, {wxMDIClientWindow, new_0, 0}},
- {2677, {wxMDIClientWindow, new_2, 2}},
- {2678, {wxMDIClientWindow, destruct, 0}},
- {2679, {wxMDIClientWindow, createClient, 2}},
- {2680, {wxLayoutAlgorithm, new, 0}},
- {2681, {wxLayoutAlgorithm, layoutFrame, 2}},
- {2682, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
- {2683, {wxLayoutAlgorithm, layoutWindow, 2}},
- {2684, {wxLayoutAlgorithm, 'Destroy', undefined}},
- {2685, {wxEvent, getId, 0}},
- {2686, {wxEvent, getSkipped, 0}},
- {2687, {wxEvent, getTimestamp, 0}},
- {2688, {wxEvent, isCommandEvent, 0}},
- {2689, {wxEvent, resumePropagation, 1}},
- {2690, {wxEvent, shouldPropagate, 0}},
- {2691, {wxEvent, skip, 1}},
- {2692, {wxEvent, stopPropagation, 0}},
- {2693, {wxCommandEvent, getClientData, 0}},
- {2694, {wxCommandEvent, getExtraLong, 0}},
- {2695, {wxCommandEvent, getInt, 0}},
- {2696, {wxCommandEvent, getSelection, 0}},
- {2697, {wxCommandEvent, getString, 0}},
- {2698, {wxCommandEvent, isChecked, 0}},
- {2699, {wxCommandEvent, isSelection, 0}},
- {2700, {wxCommandEvent, setInt, 1}},
- {2701, {wxCommandEvent, setString, 1}},
- {2702, {wxScrollEvent, getOrientation, 0}},
- {2703, {wxScrollEvent, getPosition, 0}},
- {2704, {wxScrollWinEvent, getOrientation, 0}},
- {2705, {wxScrollWinEvent, getPosition, 0}},
- {2706, {wxMouseEvent, altDown, 0}},
- {2707, {wxMouseEvent, button, 1}},
- {2708, {wxMouseEvent, buttonDClick, 1}},
- {2709, {wxMouseEvent, buttonDown, 1}},
- {2710, {wxMouseEvent, buttonUp, 1}},
- {2711, {wxMouseEvent, cmdDown, 0}},
- {2712, {wxMouseEvent, controlDown, 0}},
- {2713, {wxMouseEvent, dragging, 0}},
- {2714, {wxMouseEvent, entering, 0}},
- {2715, {wxMouseEvent, getButton, 0}},
- {2718, {wxMouseEvent, getPosition, 0}},
- {2719, {wxMouseEvent, getLogicalPosition, 1}},
- {2720, {wxMouseEvent, getLinesPerAction, 0}},
- {2721, {wxMouseEvent, getWheelRotation, 0}},
- {2722, {wxMouseEvent, getWheelDelta, 0}},
- {2723, {wxMouseEvent, getX, 0}},
- {2724, {wxMouseEvent, getY, 0}},
- {2725, {wxMouseEvent, isButton, 0}},
- {2726, {wxMouseEvent, isPageScroll, 0}},
- {2727, {wxMouseEvent, leaving, 0}},
- {2728, {wxMouseEvent, leftDClick, 0}},
- {2729, {wxMouseEvent, leftDown, 0}},
- {2730, {wxMouseEvent, leftIsDown, 0}},
- {2731, {wxMouseEvent, leftUp, 0}},
- {2732, {wxMouseEvent, metaDown, 0}},
- {2733, {wxMouseEvent, middleDClick, 0}},
- {2734, {wxMouseEvent, middleDown, 0}},
- {2735, {wxMouseEvent, middleIsDown, 0}},
- {2736, {wxMouseEvent, middleUp, 0}},
- {2737, {wxMouseEvent, moving, 0}},
- {2738, {wxMouseEvent, rightDClick, 0}},
- {2739, {wxMouseEvent, rightDown, 0}},
- {2740, {wxMouseEvent, rightIsDown, 0}},
- {2741, {wxMouseEvent, rightUp, 0}},
- {2742, {wxMouseEvent, shiftDown, 0}},
- {2743, {wxSetCursorEvent, getCursor, 0}},
- {2744, {wxSetCursorEvent, getX, 0}},
- {2745, {wxSetCursorEvent, getY, 0}},
- {2746, {wxSetCursorEvent, hasCursor, 0}},
- {2747, {wxSetCursorEvent, setCursor, 1}},
- {2748, {wxKeyEvent, altDown, 0}},
- {2749, {wxKeyEvent, cmdDown, 0}},
- {2750, {wxKeyEvent, controlDown, 0}},
- {2751, {wxKeyEvent, getKeyCode, 0}},
- {2752, {wxKeyEvent, getModifiers, 0}},
- {2755, {wxKeyEvent, getPosition, 0}},
- {2756, {wxKeyEvent, getRawKeyCode, 0}},
- {2757, {wxKeyEvent, getRawKeyFlags, 0}},
- {2758, {wxKeyEvent, getUnicodeKey, 0}},
- {2759, {wxKeyEvent, getX, 0}},
- {2760, {wxKeyEvent, getY, 0}},
- {2761, {wxKeyEvent, hasModifiers, 0}},
- {2762, {wxKeyEvent, metaDown, 0}},
- {2763, {wxKeyEvent, shiftDown, 0}},
- {2764, {wxSizeEvent, getSize, 0}},
- {2765, {wxMoveEvent, getPosition, 0}},
- {2766, {wxEraseEvent, getDC, 0}},
- {2767, {wxFocusEvent, getWindow, 0}},
- {2768, {wxChildFocusEvent, getWindow, 0}},
- {2769, {wxMenuEvent, getMenu, 0}},
- {2770, {wxMenuEvent, getMenuId, 0}},
- {2771, {wxMenuEvent, isPopup, 0}},
- {2772, {wxCloseEvent, canVeto, 0}},
- {2773, {wxCloseEvent, getLoggingOff, 0}},
- {2774, {wxCloseEvent, setCanVeto, 1}},
- {2775, {wxCloseEvent, setLoggingOff, 1}},
- {2776, {wxCloseEvent, veto, 1}},
- {2777, {wxShowEvent, setShow, 1}},
- {2778, {wxShowEvent, getShow, 0}},
- {2779, {wxIconizeEvent, iconized, 0}},
- {2780, {wxJoystickEvent, buttonDown, 1}},
- {2781, {wxJoystickEvent, buttonIsDown, 1}},
- {2782, {wxJoystickEvent, buttonUp, 1}},
- {2783, {wxJoystickEvent, getButtonChange, 0}},
- {2784, {wxJoystickEvent, getButtonState, 0}},
- {2785, {wxJoystickEvent, getJoystick, 0}},
- {2786, {wxJoystickEvent, getPosition, 0}},
- {2787, {wxJoystickEvent, getZPosition, 0}},
- {2788, {wxJoystickEvent, isButton, 0}},
- {2789, {wxJoystickEvent, isMove, 0}},
- {2790, {wxJoystickEvent, isZMove, 0}},
- {2791, {wxUpdateUIEvent, canUpdate, 1}},
- {2792, {wxUpdateUIEvent, check, 1}},
- {2793, {wxUpdateUIEvent, enable, 1}},
- {2794, {wxUpdateUIEvent, show, 1}},
- {2795, {wxUpdateUIEvent, getChecked, 0}},
- {2796, {wxUpdateUIEvent, getEnabled, 0}},
- {2797, {wxUpdateUIEvent, getShown, 0}},
- {2798, {wxUpdateUIEvent, getSetChecked, 0}},
- {2799, {wxUpdateUIEvent, getSetEnabled, 0}},
- {2800, {wxUpdateUIEvent, getSetShown, 0}},
- {2801, {wxUpdateUIEvent, getSetText, 0}},
- {2802, {wxUpdateUIEvent, getText, 0}},
- {2803, {wxUpdateUIEvent, getMode, 0}},
- {2804, {wxUpdateUIEvent, getUpdateInterval, 0}},
- {2805, {wxUpdateUIEvent, resetUpdateTime, 0}},
- {2806, {wxUpdateUIEvent, setMode, 1}},
- {2807, {wxUpdateUIEvent, setText, 1}},
- {2808, {wxUpdateUIEvent, setUpdateInterval, 1}},
- {2809, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
- {2810, {wxPaletteChangedEvent, setChangedWindow, 1}},
- {2811, {wxPaletteChangedEvent, getChangedWindow, 0}},
- {2812, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
- {2813, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
- {2814, {wxNavigationKeyEvent, getDirection, 0}},
- {2815, {wxNavigationKeyEvent, setDirection, 1}},
- {2816, {wxNavigationKeyEvent, isWindowChange, 0}},
- {2817, {wxNavigationKeyEvent, setWindowChange, 1}},
- {2818, {wxNavigationKeyEvent, isFromTab, 0}},
- {2819, {wxNavigationKeyEvent, setFromTab, 1}},
- {2820, {wxNavigationKeyEvent, getCurrentFocus, 0}},
- {2821, {wxNavigationKeyEvent, setCurrentFocus, 1}},
- {2822, {wxHelpEvent, getOrigin, 0}},
- {2823, {wxHelpEvent, getPosition, 0}},
- {2824, {wxHelpEvent, setOrigin, 1}},
- {2825, {wxHelpEvent, setPosition, 1}},
- {2826, {wxContextMenuEvent, getPosition, 0}},
- {2827, {wxContextMenuEvent, setPosition, 1}},
- {2828, {wxIdleEvent, canSend, 1}},
- {2829, {wxIdleEvent, getMode, 0}},
- {2830, {wxIdleEvent, requestMore, 1}},
- {2831, {wxIdleEvent, moreRequested, 0}},
- {2832, {wxIdleEvent, setMode, 1}},
- {2833, {wxGridEvent, altDown, 0}},
- {2834, {wxGridEvent, controlDown, 0}},
- {2835, {wxGridEvent, getCol, 0}},
- {2836, {wxGridEvent, getPosition, 0}},
- {2837, {wxGridEvent, getRow, 0}},
- {2838, {wxGridEvent, metaDown, 0}},
- {2839, {wxGridEvent, selecting, 0}},
- {2840, {wxGridEvent, shiftDown, 0}},
- {2841, {wxNotifyEvent, allow, 0}},
- {2842, {wxNotifyEvent, isAllowed, 0}},
- {2843, {wxNotifyEvent, veto, 0}},
- {2844, {wxSashEvent, getEdge, 0}},
- {2845, {wxSashEvent, getDragRect, 0}},
- {2846, {wxSashEvent, getDragStatus, 0}},
- {2847, {wxListEvent, getCacheFrom, 0}},
- {2848, {wxListEvent, getCacheTo, 0}},
- {2849, {wxListEvent, getKeyCode, 0}},
- {2850, {wxListEvent, getIndex, 0}},
- {2851, {wxListEvent, getColumn, 0}},
- {2852, {wxListEvent, getPoint, 0}},
- {2853, {wxListEvent, getLabel, 0}},
- {2854, {wxListEvent, getText, 0}},
- {2855, {wxListEvent, getImage, 0}},
- {2856, {wxListEvent, getData, 0}},
- {2857, {wxListEvent, getMask, 0}},
- {2858, {wxListEvent, getItem, 0}},
- {2859, {wxListEvent, isEditCancelled, 0}},
- {2860, {wxDateEvent, getDate, 0}},
- {2861, {wxCalendarEvent, getWeekDay, 0}},
- {2862, {wxFileDirPickerEvent, getPath, 0}},
- {2863, {wxColourPickerEvent, getColour, 0}},
- {2864, {wxFontPickerEvent, getFont, 0}},
- {2865, {wxStyledTextEvent, getPosition, 0}},
- {2866, {wxStyledTextEvent, getKey, 0}},
- {2867, {wxStyledTextEvent, getModifiers, 0}},
- {2868, {wxStyledTextEvent, getModificationType, 0}},
- {2869, {wxStyledTextEvent, getText, 0}},
- {2870, {wxStyledTextEvent, getLength, 0}},
- {2871, {wxStyledTextEvent, getLinesAdded, 0}},
- {2872, {wxStyledTextEvent, getLine, 0}},
- {2873, {wxStyledTextEvent, getFoldLevelNow, 0}},
- {2874, {wxStyledTextEvent, getFoldLevelPrev, 0}},
- {2875, {wxStyledTextEvent, getMargin, 0}},
- {2876, {wxStyledTextEvent, getMessage, 0}},
- {2877, {wxStyledTextEvent, getWParam, 0}},
- {2878, {wxStyledTextEvent, getLParam, 0}},
- {2879, {wxStyledTextEvent, getListType, 0}},
- {2880, {wxStyledTextEvent, getX, 0}},
- {2881, {wxStyledTextEvent, getY, 0}},
- {2882, {wxStyledTextEvent, getDragText, 0}},
- {2883, {wxStyledTextEvent, getDragAllowMove, 0}},
- {2884, {wxStyledTextEvent, getDragResult, 0}},
- {2885, {wxStyledTextEvent, getShift, 0}},
- {2886, {wxStyledTextEvent, getControl, 0}},
- {2887, {wxStyledTextEvent, getAlt, 0}},
- {2888, {utils, getKeyState, 1}},
- {2889, {utils, getMousePosition, 2}},
- {2890, {utils, getMouseState, 0}},
- {2891, {utils, setDetectableAutoRepeat, 1}},
- {2892, {utils, bell, 0}},
- {2893, {utils, findMenuItemId, 3}},
- {2894, {utils, genericFindWindowAtPoint, 1}},
- {2895, {utils, findWindowAtPoint, 1}},
- {2896, {utils, beginBusyCursor, 1}},
- {2897, {utils, endBusyCursor, 0}},
- {2898, {utils, isBusy, 0}},
- {2899, {utils, shutdown, 1}},
- {2900, {utils, shell, 1}},
- {2901, {utils, launchDefaultBrowser, 2}},
- {2902, {utils, getEmailAddress, 0}},
- {2903, {utils, getUserId, 0}},
- {2904, {utils, getHomeDir, 0}},
- {2905, {utils, newId, 0}},
- {2906, {utils, registerId, 1}},
- {2907, {utils, getCurrentId, 0}},
- {2908, {utils, getOsDescription, 0}},
- {2909, {utils, isPlatformLittleEndian, 0}},
- {2910, {utils, isPlatform64Bit, 0}},
- {2911, {wxPrintout, new, 1}},
- {2912, {wxPrintout, destruct, 0}},
- {2913, {wxPrintout, getDC, 0}},
- {2914, {wxPrintout, getPageSizeMM, 2}},
- {2915, {wxPrintout, getPageSizePixels, 2}},
- {2916, {wxPrintout, getPaperRectPixels, 0}},
- {2917, {wxPrintout, getPPIPrinter, 2}},
- {2918, {wxPrintout, getPPIScreen, 2}},
- {2919, {wxPrintout, getTitle, 0}},
- {2920, {wxPrintout, isPreview, 0}},
- {2921, {wxPrintout, fitThisSizeToPaper, 1}},
- {2922, {wxPrintout, fitThisSizeToPage, 1}},
- {2923, {wxPrintout, fitThisSizeToPageMargins, 2}},
- {2924, {wxPrintout, mapScreenSizeToPaper, 0}},
- {2925, {wxPrintout, mapScreenSizeToPage, 0}},
- {2926, {wxPrintout, mapScreenSizeToPageMargins, 1}},
- {2927, {wxPrintout, mapScreenSizeToDevice, 0}},
- {2928, {wxPrintout, getLogicalPaperRect, 0}},
- {2929, {wxPrintout, getLogicalPageRect, 0}},
- {2930, {wxPrintout, getLogicalPageMarginsRect, 1}},
- {2931, {wxPrintout, setLogicalOrigin, 2}},
- {2932, {wxPrintout, offsetLogicalOrigin, 2}},
- {2933, {wxStyledTextCtrl, new_2, 2}},
- {2934, {wxStyledTextCtrl, new_0, 0}},
- {2935, {wxStyledTextCtrl, destruct, 0}},
- {2936, {wxStyledTextCtrl, create, 2}},
- {2937, {wxStyledTextCtrl, addText, 1}},
- {2938, {wxStyledTextCtrl, addStyledText, 1}},
- {2939, {wxStyledTextCtrl, insertText, 2}},
- {2940, {wxStyledTextCtrl, clearAll, 0}},
- {2941, {wxStyledTextCtrl, clearDocumentStyle, 0}},
- {2942, {wxStyledTextCtrl, getLength, 0}},
- {2943, {wxStyledTextCtrl, getCharAt, 1}},
- {2944, {wxStyledTextCtrl, getCurrentPos, 0}},
- {2945, {wxStyledTextCtrl, getAnchor, 0}},
- {2946, {wxStyledTextCtrl, getStyleAt, 1}},
- {2947, {wxStyledTextCtrl, redo, 0}},
- {2948, {wxStyledTextCtrl, setUndoCollection, 1}},
- {2949, {wxStyledTextCtrl, selectAll, 0}},
- {2950, {wxStyledTextCtrl, setSavePoint, 0}},
- {2951, {wxStyledTextCtrl, getStyledText, 2}},
- {2952, {wxStyledTextCtrl, canRedo, 0}},
- {2953, {wxStyledTextCtrl, markerLineFromHandle, 1}},
- {2954, {wxStyledTextCtrl, markerDeleteHandle, 1}},
- {2955, {wxStyledTextCtrl, getUndoCollection, 0}},
- {2956, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
- {2957, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
- {2958, {wxStyledTextCtrl, positionFromPoint, 1}},
- {2959, {wxStyledTextCtrl, positionFromPointClose, 2}},
- {2960, {wxStyledTextCtrl, gotoLine, 1}},
- {2961, {wxStyledTextCtrl, gotoPos, 1}},
- {2962, {wxStyledTextCtrl, setAnchor, 1}},
- {2963, {wxStyledTextCtrl, getCurLine, 1}},
- {2964, {wxStyledTextCtrl, getEndStyled, 0}},
- {2965, {wxStyledTextCtrl, convertEOLs, 1}},
- {2966, {wxStyledTextCtrl, getEOLMode, 0}},
- {2967, {wxStyledTextCtrl, setEOLMode, 1}},
- {2968, {wxStyledTextCtrl, startStyling, 2}},
- {2969, {wxStyledTextCtrl, setStyling, 2}},
- {2970, {wxStyledTextCtrl, getBufferedDraw, 0}},
- {2971, {wxStyledTextCtrl, setBufferedDraw, 1}},
- {2972, {wxStyledTextCtrl, setTabWidth, 1}},
- {2973, {wxStyledTextCtrl, getTabWidth, 0}},
- {2974, {wxStyledTextCtrl, setCodePage, 1}},
- {2975, {wxStyledTextCtrl, markerDefine, 3}},
- {2976, {wxStyledTextCtrl, markerSetForeground, 2}},
- {2977, {wxStyledTextCtrl, markerSetBackground, 2}},
- {2978, {wxStyledTextCtrl, markerAdd, 2}},
- {2979, {wxStyledTextCtrl, markerDelete, 2}},
- {2980, {wxStyledTextCtrl, markerDeleteAll, 1}},
- {2981, {wxStyledTextCtrl, markerGet, 1}},
- {2982, {wxStyledTextCtrl, markerNext, 2}},
- {2983, {wxStyledTextCtrl, markerPrevious, 2}},
- {2984, {wxStyledTextCtrl, markerDefineBitmap, 2}},
- {2985, {wxStyledTextCtrl, markerAddSet, 2}},
- {2986, {wxStyledTextCtrl, markerSetAlpha, 2}},
- {2987, {wxStyledTextCtrl, setMarginType, 2}},
- {2988, {wxStyledTextCtrl, getMarginType, 1}},
- {2989, {wxStyledTextCtrl, setMarginWidth, 2}},
- {2990, {wxStyledTextCtrl, getMarginWidth, 1}},
- {2991, {wxStyledTextCtrl, setMarginMask, 2}},
- {2992, {wxStyledTextCtrl, getMarginMask, 1}},
- {2993, {wxStyledTextCtrl, setMarginSensitive, 2}},
- {2994, {wxStyledTextCtrl, getMarginSensitive, 1}},
- {2995, {wxStyledTextCtrl, styleClearAll, 0}},
- {2996, {wxStyledTextCtrl, styleSetForeground, 2}},
- {2997, {wxStyledTextCtrl, styleSetBackground, 2}},
- {2998, {wxStyledTextCtrl, styleSetBold, 2}},
- {2999, {wxStyledTextCtrl, styleSetItalic, 2}},
- {3000, {wxStyledTextCtrl, styleSetSize, 2}},
- {3001, {wxStyledTextCtrl, styleSetFaceName, 2}},
- {3002, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
- {3003, {wxStyledTextCtrl, styleResetDefault, 0}},
- {3004, {wxStyledTextCtrl, styleSetUnderline, 2}},
- {3005, {wxStyledTextCtrl, styleSetCase, 2}},
- {3006, {wxStyledTextCtrl, styleSetHotSpot, 2}},
- {3007, {wxStyledTextCtrl, setSelForeground, 2}},
- {3008, {wxStyledTextCtrl, setSelBackground, 2}},
- {3009, {wxStyledTextCtrl, getSelAlpha, 0}},
- {3010, {wxStyledTextCtrl, setSelAlpha, 1}},
- {3011, {wxStyledTextCtrl, setCaretForeground, 1}},
- {3012, {wxStyledTextCtrl, cmdKeyAssign, 3}},
- {3013, {wxStyledTextCtrl, cmdKeyClear, 2}},
- {3014, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
- {3015, {wxStyledTextCtrl, setStyleBytes, 2}},
- {3016, {wxStyledTextCtrl, styleSetVisible, 2}},
- {3017, {wxStyledTextCtrl, getCaretPeriod, 0}},
- {3018, {wxStyledTextCtrl, setCaretPeriod, 1}},
- {3019, {wxStyledTextCtrl, setWordChars, 1}},
- {3020, {wxStyledTextCtrl, beginUndoAction, 0}},
- {3021, {wxStyledTextCtrl, endUndoAction, 0}},
- {3022, {wxStyledTextCtrl, indicatorSetStyle, 2}},
- {3023, {wxStyledTextCtrl, indicatorGetStyle, 1}},
- {3024, {wxStyledTextCtrl, indicatorSetForeground, 2}},
- {3025, {wxStyledTextCtrl, indicatorGetForeground, 1}},
- {3026, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
- {3027, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
- {3028, {wxStyledTextCtrl, getStyleBits, 0}},
- {3029, {wxStyledTextCtrl, setLineState, 2}},
- {3030, {wxStyledTextCtrl, getLineState, 1}},
- {3031, {wxStyledTextCtrl, getMaxLineState, 0}},
- {3032, {wxStyledTextCtrl, getCaretLineVisible, 0}},
- {3033, {wxStyledTextCtrl, setCaretLineVisible, 1}},
- {3034, {wxStyledTextCtrl, getCaretLineBackground, 0}},
- {3035, {wxStyledTextCtrl, setCaretLineBackground, 1}},
- {3036, {wxStyledTextCtrl, autoCompShow, 2}},
- {3037, {wxStyledTextCtrl, autoCompCancel, 0}},
- {3038, {wxStyledTextCtrl, autoCompActive, 0}},
- {3039, {wxStyledTextCtrl, autoCompPosStart, 0}},
- {3040, {wxStyledTextCtrl, autoCompComplete, 0}},
- {3041, {wxStyledTextCtrl, autoCompStops, 1}},
- {3042, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
- {3043, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
- {3044, {wxStyledTextCtrl, autoCompSelect, 1}},
- {3045, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
- {3046, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
- {3047, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
- {3048, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
- {3049, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
- {3050, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
- {3051, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
- {3052, {wxStyledTextCtrl, userListShow, 2}},
- {3053, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
- {3054, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
- {3055, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
- {3056, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
- {3057, {wxStyledTextCtrl, registerImage, 2}},
- {3058, {wxStyledTextCtrl, clearRegisteredImages, 0}},
- {3059, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
- {3060, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
- {3061, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
- {3062, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
- {3063, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
- {3064, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
- {3065, {wxStyledTextCtrl, setIndent, 1}},
- {3066, {wxStyledTextCtrl, getIndent, 0}},
- {3067, {wxStyledTextCtrl, setUseTabs, 1}},
- {3068, {wxStyledTextCtrl, getUseTabs, 0}},
- {3069, {wxStyledTextCtrl, setLineIndentation, 2}},
- {3070, {wxStyledTextCtrl, getLineIndentation, 1}},
- {3071, {wxStyledTextCtrl, getLineIndentPosition, 1}},
- {3072, {wxStyledTextCtrl, getColumn, 1}},
- {3073, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
- {3074, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
- {3075, {wxStyledTextCtrl, setIndentationGuides, 1}},
- {3076, {wxStyledTextCtrl, getIndentationGuides, 0}},
- {3077, {wxStyledTextCtrl, setHighlightGuide, 1}},
- {3078, {wxStyledTextCtrl, getHighlightGuide, 0}},
- {3079, {wxStyledTextCtrl, getLineEndPosition, 1}},
- {3080, {wxStyledTextCtrl, getCodePage, 0}},
- {3081, {wxStyledTextCtrl, getCaretForeground, 0}},
- {3082, {wxStyledTextCtrl, getReadOnly, 0}},
- {3083, {wxStyledTextCtrl, setCurrentPos, 1}},
- {3084, {wxStyledTextCtrl, setSelectionStart, 1}},
- {3085, {wxStyledTextCtrl, getSelectionStart, 0}},
- {3086, {wxStyledTextCtrl, setSelectionEnd, 1}},
- {3087, {wxStyledTextCtrl, getSelectionEnd, 0}},
- {3088, {wxStyledTextCtrl, setPrintMagnification, 1}},
- {3089, {wxStyledTextCtrl, getPrintMagnification, 0}},
- {3090, {wxStyledTextCtrl, setPrintColourMode, 1}},
- {3091, {wxStyledTextCtrl, getPrintColourMode, 0}},
- {3092, {wxStyledTextCtrl, findText, 4}},
- {3093, {wxStyledTextCtrl, formatRange, 7}},
- {3094, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
- {3095, {wxStyledTextCtrl, getLine, 1}},
- {3096, {wxStyledTextCtrl, getLineCount, 0}},
- {3097, {wxStyledTextCtrl, setMarginLeft, 1}},
- {3098, {wxStyledTextCtrl, getMarginLeft, 0}},
- {3099, {wxStyledTextCtrl, setMarginRight, 1}},
- {3100, {wxStyledTextCtrl, getMarginRight, 0}},
- {3101, {wxStyledTextCtrl, getModify, 0}},
- {3102, {wxStyledTextCtrl, setSelection, 2}},
- {3103, {wxStyledTextCtrl, getSelectedText, 0}},
- {3104, {wxStyledTextCtrl, getTextRange, 2}},
- {3105, {wxStyledTextCtrl, hideSelection, 1}},
- {3106, {wxStyledTextCtrl, lineFromPosition, 1}},
- {3107, {wxStyledTextCtrl, positionFromLine, 1}},
- {3108, {wxStyledTextCtrl, lineScroll, 2}},
- {3109, {wxStyledTextCtrl, ensureCaretVisible, 0}},
- {3110, {wxStyledTextCtrl, replaceSelection, 1}},
- {3111, {wxStyledTextCtrl, setReadOnly, 1}},
- {3112, {wxStyledTextCtrl, canPaste, 0}},
- {3113, {wxStyledTextCtrl, canUndo, 0}},
- {3114, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
- {3115, {wxStyledTextCtrl, undo, 0}},
- {3116, {wxStyledTextCtrl, cut, 0}},
- {3117, {wxStyledTextCtrl, copy, 0}},
- {3118, {wxStyledTextCtrl, paste, 0}},
- {3119, {wxStyledTextCtrl, clear, 0}},
- {3120, {wxStyledTextCtrl, setText, 1}},
- {3121, {wxStyledTextCtrl, getText, 0}},
- {3122, {wxStyledTextCtrl, getTextLength, 0}},
- {3123, {wxStyledTextCtrl, getOvertype, 0}},
- {3124, {wxStyledTextCtrl, setCaretWidth, 1}},
- {3125, {wxStyledTextCtrl, getCaretWidth, 0}},
- {3126, {wxStyledTextCtrl, setTargetStart, 1}},
- {3127, {wxStyledTextCtrl, getTargetStart, 0}},
- {3128, {wxStyledTextCtrl, setTargetEnd, 1}},
- {3129, {wxStyledTextCtrl, getTargetEnd, 0}},
- {3130, {wxStyledTextCtrl, replaceTarget, 1}},
- {3131, {wxStyledTextCtrl, searchInTarget, 1}},
- {3132, {wxStyledTextCtrl, setSearchFlags, 1}},
- {3133, {wxStyledTextCtrl, getSearchFlags, 0}},
- {3134, {wxStyledTextCtrl, callTipShow, 2}},
- {3135, {wxStyledTextCtrl, callTipCancel, 0}},
- {3136, {wxStyledTextCtrl, callTipActive, 0}},
- {3137, {wxStyledTextCtrl, callTipPosAtStart, 0}},
- {3138, {wxStyledTextCtrl, callTipSetHighlight, 2}},
- {3139, {wxStyledTextCtrl, callTipSetBackground, 1}},
- {3140, {wxStyledTextCtrl, callTipSetForeground, 1}},
- {3141, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
- {3142, {wxStyledTextCtrl, callTipUseStyle, 1}},
- {3143, {wxStyledTextCtrl, visibleFromDocLine, 1}},
- {3144, {wxStyledTextCtrl, docLineFromVisible, 1}},
- {3145, {wxStyledTextCtrl, wrapCount, 1}},
- {3146, {wxStyledTextCtrl, setFoldLevel, 2}},
- {3147, {wxStyledTextCtrl, getFoldLevel, 1}},
- {3148, {wxStyledTextCtrl, getLastChild, 2}},
- {3149, {wxStyledTextCtrl, getFoldParent, 1}},
- {3150, {wxStyledTextCtrl, showLines, 2}},
- {3151, {wxStyledTextCtrl, hideLines, 2}},
- {3152, {wxStyledTextCtrl, getLineVisible, 1}},
- {3153, {wxStyledTextCtrl, setFoldExpanded, 2}},
- {3154, {wxStyledTextCtrl, getFoldExpanded, 1}},
- {3155, {wxStyledTextCtrl, toggleFold, 1}},
- {3156, {wxStyledTextCtrl, ensureVisible, 1}},
- {3157, {wxStyledTextCtrl, setFoldFlags, 1}},
- {3158, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
- {3159, {wxStyledTextCtrl, setTabIndents, 1}},
- {3160, {wxStyledTextCtrl, getTabIndents, 0}},
- {3161, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
- {3162, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
- {3163, {wxStyledTextCtrl, setMouseDwellTime, 1}},
- {3164, {wxStyledTextCtrl, getMouseDwellTime, 0}},
- {3165, {wxStyledTextCtrl, wordStartPosition, 2}},
- {3166, {wxStyledTextCtrl, wordEndPosition, 2}},
- {3167, {wxStyledTextCtrl, setWrapMode, 1}},
- {3168, {wxStyledTextCtrl, getWrapMode, 0}},
- {3169, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
- {3170, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
- {3171, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
- {3172, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
- {3173, {wxStyledTextCtrl, setWrapStartIndent, 1}},
- {3174, {wxStyledTextCtrl, getWrapStartIndent, 0}},
- {3175, {wxStyledTextCtrl, setLayoutCache, 1}},
- {3176, {wxStyledTextCtrl, getLayoutCache, 0}},
- {3177, {wxStyledTextCtrl, setScrollWidth, 1}},
- {3178, {wxStyledTextCtrl, getScrollWidth, 0}},
- {3179, {wxStyledTextCtrl, textWidth, 2}},
- {3180, {wxStyledTextCtrl, getEndAtLastLine, 0}},
- {3181, {wxStyledTextCtrl, textHeight, 1}},
- {3182, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
- {3183, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
- {3184, {wxStyledTextCtrl, appendText, 1}},
- {3185, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
- {3186, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
- {3187, {wxStyledTextCtrl, targetFromSelection, 0}},
- {3188, {wxStyledTextCtrl, linesJoin, 0}},
- {3189, {wxStyledTextCtrl, linesSplit, 1}},
- {3190, {wxStyledTextCtrl, setFoldMarginColour, 2}},
- {3191, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
- {3192, {wxStyledTextCtrl, lineDown, 0}},
- {3193, {wxStyledTextCtrl, lineDownExtend, 0}},
- {3194, {wxStyledTextCtrl, lineUp, 0}},
- {3195, {wxStyledTextCtrl, lineUpExtend, 0}},
- {3196, {wxStyledTextCtrl, charLeft, 0}},
- {3197, {wxStyledTextCtrl, charLeftExtend, 0}},
- {3198, {wxStyledTextCtrl, charRight, 0}},
- {3199, {wxStyledTextCtrl, charRightExtend, 0}},
- {3200, {wxStyledTextCtrl, wordLeft, 0}},
- {3201, {wxStyledTextCtrl, wordLeftExtend, 0}},
- {3202, {wxStyledTextCtrl, wordRight, 0}},
- {3203, {wxStyledTextCtrl, wordRightExtend, 0}},
- {3204, {wxStyledTextCtrl, home, 0}},
- {3205, {wxStyledTextCtrl, homeExtend, 0}},
- {3206, {wxStyledTextCtrl, lineEnd, 0}},
- {3207, {wxStyledTextCtrl, lineEndExtend, 0}},
- {3208, {wxStyledTextCtrl, documentStart, 0}},
- {3209, {wxStyledTextCtrl, documentStartExtend, 0}},
- {3210, {wxStyledTextCtrl, documentEnd, 0}},
- {3211, {wxStyledTextCtrl, documentEndExtend, 0}},
- {3212, {wxStyledTextCtrl, pageUp, 0}},
- {3213, {wxStyledTextCtrl, pageUpExtend, 0}},
- {3214, {wxStyledTextCtrl, pageDown, 0}},
- {3215, {wxStyledTextCtrl, pageDownExtend, 0}},
- {3216, {wxStyledTextCtrl, editToggleOvertype, 0}},
- {3217, {wxStyledTextCtrl, cancel, 0}},
- {3218, {wxStyledTextCtrl, deleteBack, 0}},
- {3219, {wxStyledTextCtrl, tab, 0}},
- {3220, {wxStyledTextCtrl, backTab, 0}},
- {3221, {wxStyledTextCtrl, newLine, 0}},
- {3222, {wxStyledTextCtrl, formFeed, 0}},
- {3223, {wxStyledTextCtrl, vCHome, 0}},
- {3224, {wxStyledTextCtrl, vCHomeExtend, 0}},
- {3225, {wxStyledTextCtrl, zoomIn, 0}},
- {3226, {wxStyledTextCtrl, zoomOut, 0}},
- {3227, {wxStyledTextCtrl, delWordLeft, 0}},
- {3228, {wxStyledTextCtrl, delWordRight, 0}},
- {3229, {wxStyledTextCtrl, lineCut, 0}},
- {3230, {wxStyledTextCtrl, lineDelete, 0}},
- {3231, {wxStyledTextCtrl, lineTranspose, 0}},
- {3232, {wxStyledTextCtrl, lineDuplicate, 0}},
- {3233, {wxStyledTextCtrl, lowerCase, 0}},
- {3234, {wxStyledTextCtrl, upperCase, 0}},
- {3235, {wxStyledTextCtrl, lineScrollDown, 0}},
- {3236, {wxStyledTextCtrl, lineScrollUp, 0}},
- {3237, {wxStyledTextCtrl, deleteBackNotLine, 0}},
- {3238, {wxStyledTextCtrl, homeDisplay, 0}},
- {3239, {wxStyledTextCtrl, homeDisplayExtend, 0}},
- {3240, {wxStyledTextCtrl, lineEndDisplay, 0}},
- {3241, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
- {3242, {wxStyledTextCtrl, homeWrapExtend, 0}},
- {3243, {wxStyledTextCtrl, lineEndWrap, 0}},
- {3244, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
- {3245, {wxStyledTextCtrl, vCHomeWrap, 0}},
- {3246, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
- {3247, {wxStyledTextCtrl, lineCopy, 0}},
- {3248, {wxStyledTextCtrl, moveCaretInsideView, 0}},
- {3249, {wxStyledTextCtrl, lineLength, 1}},
- {3250, {wxStyledTextCtrl, braceHighlight, 2}},
- {3251, {wxStyledTextCtrl, braceBadLight, 1}},
- {3252, {wxStyledTextCtrl, braceMatch, 1}},
- {3253, {wxStyledTextCtrl, getViewEOL, 0}},
- {3254, {wxStyledTextCtrl, setViewEOL, 1}},
- {3255, {wxStyledTextCtrl, setModEventMask, 1}},
- {3256, {wxStyledTextCtrl, getEdgeColumn, 0}},
- {3257, {wxStyledTextCtrl, setEdgeColumn, 1}},
- {3258, {wxStyledTextCtrl, getEdgeMode, 0}},
- {3259, {wxStyledTextCtrl, getEdgeColour, 0}},
- {3260, {wxStyledTextCtrl, setEdgeColour, 1}},
- {3261, {wxStyledTextCtrl, searchAnchor, 0}},
- {3262, {wxStyledTextCtrl, searchNext, 2}},
- {3263, {wxStyledTextCtrl, searchPrev, 2}},
- {3264, {wxStyledTextCtrl, linesOnScreen, 0}},
- {3265, {wxStyledTextCtrl, usePopUp, 1}},
- {3266, {wxStyledTextCtrl, selectionIsRectangle, 0}},
- {3267, {wxStyledTextCtrl, setZoom, 1}},
- {3268, {wxStyledTextCtrl, getZoom, 0}},
- {3269, {wxStyledTextCtrl, getModEventMask, 0}},
- {3270, {wxStyledTextCtrl, setSTCFocus, 1}},
- {3271, {wxStyledTextCtrl, getSTCFocus, 0}},
- {3272, {wxStyledTextCtrl, setStatus, 1}},
- {3273, {wxStyledTextCtrl, getStatus, 0}},
- {3274, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
- {3275, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
- {3276, {wxStyledTextCtrl, setSTCCursor, 1}},
- {3277, {wxStyledTextCtrl, getSTCCursor, 0}},
- {3278, {wxStyledTextCtrl, setControlCharSymbol, 1}},
- {3279, {wxStyledTextCtrl, getControlCharSymbol, 0}},
- {3280, {wxStyledTextCtrl, wordPartLeft, 0}},
- {3281, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
- {3282, {wxStyledTextCtrl, wordPartRight, 0}},
- {3283, {wxStyledTextCtrl, wordPartRightExtend, 0}},
- {3284, {wxStyledTextCtrl, setVisiblePolicy, 2}},
- {3285, {wxStyledTextCtrl, delLineLeft, 0}},
- {3286, {wxStyledTextCtrl, delLineRight, 0}},
- {3287, {wxStyledTextCtrl, getXOffset, 0}},
- {3288, {wxStyledTextCtrl, chooseCaretX, 0}},
- {3289, {wxStyledTextCtrl, setXCaretPolicy, 2}},
- {3290, {wxStyledTextCtrl, setYCaretPolicy, 2}},
- {3291, {wxStyledTextCtrl, getPrintWrapMode, 0}},
- {3292, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
- {3293, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
- {3294, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
- {3295, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
- {3296, {wxStyledTextCtrl, paraDownExtend, 0}},
- {3297, {wxStyledTextCtrl, paraUp, 0}},
- {3298, {wxStyledTextCtrl, paraUpExtend, 0}},
- {3299, {wxStyledTextCtrl, positionBefore, 1}},
- {3300, {wxStyledTextCtrl, positionAfter, 1}},
- {3301, {wxStyledTextCtrl, copyRange, 2}},
- {3302, {wxStyledTextCtrl, copyText, 2}},
- {3303, {wxStyledTextCtrl, setSelectionMode, 1}},
- {3304, {wxStyledTextCtrl, getSelectionMode, 0}},
- {3305, {wxStyledTextCtrl, lineDownRectExtend, 0}},
- {3306, {wxStyledTextCtrl, lineUpRectExtend, 0}},
- {3307, {wxStyledTextCtrl, charLeftRectExtend, 0}},
- {3308, {wxStyledTextCtrl, charRightRectExtend, 0}},
- {3309, {wxStyledTextCtrl, homeRectExtend, 0}},
- {3310, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
- {3311, {wxStyledTextCtrl, lineEndRectExtend, 0}},
- {3312, {wxStyledTextCtrl, pageUpRectExtend, 0}},
- {3313, {wxStyledTextCtrl, pageDownRectExtend, 0}},
- {3314, {wxStyledTextCtrl, stutteredPageUp, 0}},
- {3315, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
- {3316, {wxStyledTextCtrl, stutteredPageDown, 0}},
- {3317, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
- {3318, {wxStyledTextCtrl, wordLeftEnd, 0}},
- {3319, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
- {3320, {wxStyledTextCtrl, wordRightEnd, 0}},
- {3321, {wxStyledTextCtrl, wordRightEndExtend, 0}},
- {3322, {wxStyledTextCtrl, setWhitespaceChars, 1}},
- {3323, {wxStyledTextCtrl, setCharsDefault, 0}},
- {3324, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
- {3325, {wxStyledTextCtrl, allocate, 1}},
- {3326, {wxStyledTextCtrl, findColumn, 2}},
- {3327, {wxStyledTextCtrl, getCaretSticky, 0}},
- {3328, {wxStyledTextCtrl, setCaretSticky, 1}},
- {3329, {wxStyledTextCtrl, toggleCaretSticky, 0}},
- {3330, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
- {3331, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
- {3332, {wxStyledTextCtrl, selectionDuplicate, 0}},
- {3333, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
- {3334, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
- {3335, {wxStyledTextCtrl, startRecord, 0}},
- {3336, {wxStyledTextCtrl, stopRecord, 0}},
- {3337, {wxStyledTextCtrl, setLexer, 1}},
- {3338, {wxStyledTextCtrl, getLexer, 0}},
- {3339, {wxStyledTextCtrl, colourise, 2}},
- {3340, {wxStyledTextCtrl, setProperty, 2}},
- {3341, {wxStyledTextCtrl, setKeyWords, 2}},
- {3342, {wxStyledTextCtrl, setLexerLanguage, 1}},
- {3343, {wxStyledTextCtrl, getProperty, 1}},
- {3344, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
- {3345, {wxStyledTextCtrl, getCurrentLine, 0}},
- {3346, {wxStyledTextCtrl, styleSetSpec, 2}},
- {3347, {wxStyledTextCtrl, styleSetFont, 2}},
- {3348, {wxStyledTextCtrl, styleSetFontAttr, 7}},
- {3349, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
- {3350, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
- {3351, {wxStyledTextCtrl, cmdKeyExecute, 1}},
- {3352, {wxStyledTextCtrl, setMargins, 2}},
- {3353, {wxStyledTextCtrl, getSelection, 2}},
- {3354, {wxStyledTextCtrl, pointFromPosition, 1}},
- {3355, {wxStyledTextCtrl, scrollToLine, 1}},
- {3356, {wxStyledTextCtrl, scrollToColumn, 1}},
- {3357, {wxStyledTextCtrl, sendMsg, 2}},
- {3358, {wxStyledTextCtrl, setVScrollBar, 1}},
- {3359, {wxStyledTextCtrl, setHScrollBar, 1}},
- {3360, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
- {3361, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
- {3362, {wxStyledTextCtrl, saveFile, 1}},
- {3363, {wxStyledTextCtrl, loadFile, 1}},
- {3364, {wxStyledTextCtrl, doDragOver, 3}},
- {3365, {wxStyledTextCtrl, doDropText, 3}},
- {3366, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
- {3367, {wxStyledTextCtrl, addTextRaw, 1}},
- {3368, {wxStyledTextCtrl, insertTextRaw, 2}},
- {3369, {wxStyledTextCtrl, getCurLineRaw, 1}},
- {3370, {wxStyledTextCtrl, getLineRaw, 1}},
- {3371, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
- {3372, {wxStyledTextCtrl, getTextRangeRaw, 2}},
- {3373, {wxStyledTextCtrl, setTextRaw, 1}},
- {3374, {wxStyledTextCtrl, getTextRaw, 0}},
- {3375, {wxStyledTextCtrl, appendTextRaw, 1}},
- {3376, {wxArtProvider, getBitmap, 2}},
- {3377, {wxArtProvider, getIcon, 2}},
- {3378, {wxTreeEvent, getKeyCode, 0}},
- {3379, {wxTreeEvent, getItem, 0}},
- {3380, {wxTreeEvent, getKeyEvent, 0}},
- {3381, {wxTreeEvent, getLabel, 0}},
- {3382, {wxTreeEvent, getOldItem, 0}},
- {3383, {wxTreeEvent, getPoint, 0}},
- {3384, {wxTreeEvent, isEditCancelled, 0}},
- {3385, {wxTreeEvent, setToolTip, 1}},
- {3386, {wxNotebookEvent, getOldSelection, 0}},
- {3387, {wxNotebookEvent, getSelection, 0}},
- {3388, {wxNotebookEvent, setOldSelection, 1}},
- {3389, {wxNotebookEvent, setSelection, 1}},
- {3390, {wxFileDataObject, new, 0}},
- {3391, {wxFileDataObject, addFile, 1}},
- {3392, {wxFileDataObject, getFilenames, 0}},
- {3393, {wxFileDataObject, 'Destroy', undefined}},
- {3394, {wxTextDataObject, new, 1}},
- {3395, {wxTextDataObject, getTextLength, 0}},
- {3396, {wxTextDataObject, getText, 0}},
- {3397, {wxTextDataObject, setText, 1}},
- {3398, {wxTextDataObject, 'Destroy', undefined}},
- {3399, {wxBitmapDataObject, new_1_1, 1}},
- {3400, {wxBitmapDataObject, new_1_0, 1}},
- {3401, {wxBitmapDataObject, getBitmap, 0}},
- {3402, {wxBitmapDataObject, setBitmap, 1}},
- {3403, {wxBitmapDataObject, 'Destroy', undefined}},
- {3405, {wxClipboard, new, 0}},
- {3406, {wxClipboard, destruct, 0}},
- {3407, {wxClipboard, addData, 1}},
- {3408, {wxClipboard, clear, 0}},
- {3409, {wxClipboard, close, 0}},
- {3410, {wxClipboard, flush, 0}},
- {3411, {wxClipboard, getData, 1}},
- {3412, {wxClipboard, isOpened, 0}},
- {3413, {wxClipboard, open, 0}},
- {3414, {wxClipboard, setData, 1}},
- {3416, {wxClipboard, usePrimarySelection, 1}},
- {3417, {wxClipboard, isSupported, 1}},
- {3418, {wxClipboard, get, 0}},
- {3419, {wxSpinEvent, getPosition, 0}},
- {3420, {wxSpinEvent, setPosition, 1}},
- {3421, {wxSplitterWindow, new_0, 0}},
- {3422, {wxSplitterWindow, new_2, 2}},
- {3423, {wxSplitterWindow, destruct, 0}},
- {3424, {wxSplitterWindow, create, 2}},
- {3425, {wxSplitterWindow, getMinimumPaneSize, 0}},
- {3426, {wxSplitterWindow, getSashGravity, 0}},
- {3427, {wxSplitterWindow, getSashPosition, 0}},
- {3428, {wxSplitterWindow, getSplitMode, 0}},
- {3429, {wxSplitterWindow, getWindow1, 0}},
- {3430, {wxSplitterWindow, getWindow2, 0}},
- {3431, {wxSplitterWindow, initialize, 1}},
- {3432, {wxSplitterWindow, isSplit, 0}},
- {3433, {wxSplitterWindow, replaceWindow, 2}},
- {3434, {wxSplitterWindow, setSashGravity, 1}},
- {3435, {wxSplitterWindow, setSashPosition, 2}},
- {3436, {wxSplitterWindow, setSashSize, 1}},
- {3437, {wxSplitterWindow, setMinimumPaneSize, 1}},
- {3438, {wxSplitterWindow, setSplitMode, 1}},
- {3439, {wxSplitterWindow, splitHorizontally, 3}},
- {3440, {wxSplitterWindow, splitVertically, 3}},
- {3441, {wxSplitterWindow, unsplit, 1}},
- {3442, {wxSplitterWindow, updateSize, 0}},
- {3443, {wxSplitterEvent, getSashPosition, 0}},
- {3444, {wxSplitterEvent, getX, 0}},
- {3445, {wxSplitterEvent, getY, 0}},
- {3446, {wxSplitterEvent, getWindowBeingRemoved, 0}},
- {3447, {wxSplitterEvent, setSashPosition, 1}},
- {3448, {wxHtmlWindow, new_0, 0}},
- {3449, {wxHtmlWindow, new_2, 2}},
- {3450, {wxHtmlWindow, appendToPage, 1}},
- {3451, {wxHtmlWindow, getOpenedAnchor, 0}},
- {3452, {wxHtmlWindow, getOpenedPage, 0}},
- {3453, {wxHtmlWindow, getOpenedPageTitle, 0}},
- {3454, {wxHtmlWindow, getRelatedFrame, 0}},
- {3455, {wxHtmlWindow, historyBack, 0}},
- {3456, {wxHtmlWindow, historyCanBack, 0}},
- {3457, {wxHtmlWindow, historyCanForward, 0}},
- {3458, {wxHtmlWindow, historyClear, 0}},
- {3459, {wxHtmlWindow, historyForward, 0}},
- {3460, {wxHtmlWindow, loadFile, 1}},
- {3461, {wxHtmlWindow, loadPage, 1}},
- {3462, {wxHtmlWindow, selectAll, 0}},
- {3463, {wxHtmlWindow, selectionToText, 0}},
- {3464, {wxHtmlWindow, selectLine, 1}},
- {3465, {wxHtmlWindow, selectWord, 1}},
- {3466, {wxHtmlWindow, setBorders, 1}},
- {3467, {wxHtmlWindow, setFonts, 3}},
- {3468, {wxHtmlWindow, setPage, 1}},
- {3469, {wxHtmlWindow, setRelatedFrame, 2}},
- {3470, {wxHtmlWindow, setRelatedStatusBar, 1}},
- {3471, {wxHtmlWindow, toText, 0}},
- {3472, {wxHtmlWindow, 'Destroy', undefined}},
- {3473, {wxHtmlLinkEvent, getLinkInfo, 0}},
- {3474, {wxAuiNotebookEvent, setSelection, 1}},
- {3475, {wxAuiNotebookEvent, getSelection, 0}},
- {3476, {wxAuiNotebookEvent, setOldSelection, 1}},
- {3477, {wxAuiNotebookEvent, getOldSelection, 0}},
- {3478, {wxAuiNotebookEvent, setDragSource, 1}},
- {3479, {wxAuiNotebookEvent, getDragSource, 0}},
- {3480, {wxAuiManagerEvent, setManager, 1}},
- {3481, {wxAuiManagerEvent, getManager, 0}},
- {3482, {wxAuiManagerEvent, setPane, 1}},
- {3483, {wxAuiManagerEvent, getPane, 0}},
- {3484, {wxAuiManagerEvent, setButton, 1}},
- {3485, {wxAuiManagerEvent, getButton, 0}},
- {3486, {wxAuiManagerEvent, setDC, 1}},
- {3487, {wxAuiManagerEvent, getDC, 0}},
- {3488, {wxAuiManagerEvent, veto, 1}},
- {3489, {wxAuiManagerEvent, getVeto, 0}},
- {3490, {wxAuiManagerEvent, setCanVeto, 1}},
- {3491, {wxAuiManagerEvent, canVeto, 0}},
- {3492, {wxLogNull, new, 0}},
- {3493, {wxLogNull, 'Destroy', undefined}},
+ {2018, {wxTreeCtrl, getFirstChild, 2}},
+ {2019, {wxTreeCtrl, getNextChild, 2}},
+ {2020, {wxTreeCtrl, getFirstVisibleItem, 0}},
+ {2021, {wxTreeCtrl, getImageList, 0}},
+ {2022, {wxTreeCtrl, getIndent, 0}},
+ {2023, {wxTreeCtrl, getItemBackgroundColour, 1}},
+ {2024, {wxTreeCtrl, getItemData, 1}},
+ {2025, {wxTreeCtrl, getItemFont, 1}},
+ {2026, {wxTreeCtrl, getItemImage_1, 1}},
+ {2027, {wxTreeCtrl, getItemImage_2, 2}},
+ {2028, {wxTreeCtrl, getItemText, 1}},
+ {2029, {wxTreeCtrl, getItemTextColour, 1}},
+ {2030, {wxTreeCtrl, getLastChild, 1}},
+ {2031, {wxTreeCtrl, getNextSibling, 1}},
+ {2032, {wxTreeCtrl, getNextVisible, 1}},
+ {2033, {wxTreeCtrl, getItemParent, 1}},
+ {2034, {wxTreeCtrl, getPrevSibling, 1}},
+ {2035, {wxTreeCtrl, getPrevVisible, 1}},
+ {2036, {wxTreeCtrl, getRootItem, 0}},
+ {2037, {wxTreeCtrl, getSelection, 0}},
+ {2038, {wxTreeCtrl, getSelections, 1}},
+ {2039, {wxTreeCtrl, getStateImageList, 0}},
+ {2040, {wxTreeCtrl, hitTest, 1}},
+ {2042, {wxTreeCtrl, insertItem, 4}},
+ {2043, {wxTreeCtrl, isBold, 1}},
+ {2044, {wxTreeCtrl, isExpanded, 1}},
+ {2045, {wxTreeCtrl, isSelected, 1}},
+ {2046, {wxTreeCtrl, isVisible, 1}},
+ {2047, {wxTreeCtrl, itemHasChildren, 1}},
+ {2048, {wxTreeCtrl, prependItem, 3}},
+ {2049, {wxTreeCtrl, scrollTo, 1}},
+ {2050, {wxTreeCtrl, selectItem_1, 1}},
+ {2051, {wxTreeCtrl, selectItem_2, 2}},
+ {2052, {wxTreeCtrl, setIndent, 1}},
+ {2053, {wxTreeCtrl, setImageList, 1}},
+ {2054, {wxTreeCtrl, setItemBackgroundColour, 2}},
+ {2055, {wxTreeCtrl, setItemBold, 2}},
+ {2056, {wxTreeCtrl, setItemData, 2}},
+ {2057, {wxTreeCtrl, setItemDropHighlight, 2}},
+ {2058, {wxTreeCtrl, setItemFont, 2}},
+ {2059, {wxTreeCtrl, setItemHasChildren, 2}},
+ {2060, {wxTreeCtrl, setItemImage_2, 2}},
+ {2061, {wxTreeCtrl, setItemImage_3, 3}},
+ {2062, {wxTreeCtrl, setItemText, 2}},
+ {2063, {wxTreeCtrl, setItemTextColour, 2}},
+ {2064, {wxTreeCtrl, setStateImageList, 1}},
+ {2065, {wxTreeCtrl, setWindowStyle, 1}},
+ {2066, {wxTreeCtrl, sortChildren, 1}},
+ {2067, {wxTreeCtrl, toggle, 1}},
+ {2068, {wxTreeCtrl, toggleItemSelection, 1}},
+ {2069, {wxTreeCtrl, unselect, 0}},
+ {2070, {wxTreeCtrl, unselectAll, 0}},
+ {2071, {wxTreeCtrl, unselectItem, 1}},
+ {2072, {wxScrollBar, new_0, 0}},
+ {2073, {wxScrollBar, new_3, 3}},
+ {2074, {wxScrollBar, destruct, 0}},
+ {2075, {wxScrollBar, create, 3}},
+ {2076, {wxScrollBar, getRange, 0}},
+ {2077, {wxScrollBar, getPageSize, 0}},
+ {2078, {wxScrollBar, getThumbPosition, 0}},
+ {2079, {wxScrollBar, getThumbSize, 0}},
+ {2080, {wxScrollBar, setThumbPosition, 1}},
+ {2081, {wxScrollBar, setScrollbar, 5}},
+ {2083, {wxSpinButton, new_2, 2}},
+ {2084, {wxSpinButton, new_0, 0}},
+ {2085, {wxSpinButton, create, 2}},
+ {2086, {wxSpinButton, getMax, 0}},
+ {2087, {wxSpinButton, getMin, 0}},
+ {2088, {wxSpinButton, getValue, 0}},
+ {2089, {wxSpinButton, setRange, 2}},
+ {2090, {wxSpinButton, setValue, 1}},
+ {2091, {wxSpinButton, 'Destroy', undefined}},
+ {2092, {wxSpinCtrl, new_0, 0}},
+ {2093, {wxSpinCtrl, new_2, 2}},
+ {2095, {wxSpinCtrl, create, 2}},
+ {2098, {wxSpinCtrl, setValue_1_1, 1}},
+ {2099, {wxSpinCtrl, setValue_1_0, 1}},
+ {2101, {wxSpinCtrl, getValue, 0}},
+ {2103, {wxSpinCtrl, setRange, 2}},
+ {2104, {wxSpinCtrl, setSelection, 2}},
+ {2106, {wxSpinCtrl, getMin, 0}},
+ {2108, {wxSpinCtrl, getMax, 0}},
+ {2109, {wxSpinCtrl, 'Destroy', undefined}},
+ {2110, {wxStaticText, new_0, 0}},
+ {2111, {wxStaticText, new_4, 4}},
+ {2112, {wxStaticText, create, 4}},
+ {2113, {wxStaticText, getLabel, 0}},
+ {2114, {wxStaticText, setLabel, 1}},
+ {2115, {wxStaticText, wrap, 1}},
+ {2116, {wxStaticText, 'Destroy', undefined}},
+ {2117, {wxStaticBitmap, new_0, 0}},
+ {2118, {wxStaticBitmap, new_4, 4}},
+ {2119, {wxStaticBitmap, create, 4}},
+ {2120, {wxStaticBitmap, getBitmap, 0}},
+ {2121, {wxStaticBitmap, setBitmap, 1}},
+ {2122, {wxStaticBitmap, 'Destroy', undefined}},
+ {2123, {wxRadioBox, new, 7}},
+ {2125, {wxRadioBox, destruct, 0}},
+ {2126, {wxRadioBox, create, 7}},
+ {2127, {wxRadioBox, enable_2, 2}},
+ {2128, {wxRadioBox, enable_1, 1}},
+ {2129, {wxRadioBox, getSelection, 0}},
+ {2130, {wxRadioBox, getString, 1}},
+ {2131, {wxRadioBox, setSelection, 1}},
+ {2132, {wxRadioBox, show_2, 2}},
+ {2133, {wxRadioBox, show_1, 1}},
+ {2134, {wxRadioBox, getColumnCount, 0}},
+ {2135, {wxRadioBox, getItemHelpText, 1}},
+ {2136, {wxRadioBox, getItemToolTip, 1}},
+ {2138, {wxRadioBox, getItemFromPoint, 1}},
+ {2139, {wxRadioBox, getRowCount, 0}},
+ {2140, {wxRadioBox, isItemEnabled, 1}},
+ {2141, {wxRadioBox, isItemShown, 1}},
+ {2142, {wxRadioBox, setItemHelpText, 2}},
+ {2143, {wxRadioBox, setItemToolTip, 2}},
+ {2144, {wxRadioButton, new_0, 0}},
+ {2145, {wxRadioButton, new_4, 4}},
+ {2146, {wxRadioButton, create, 4}},
+ {2147, {wxRadioButton, getValue, 0}},
+ {2148, {wxRadioButton, setValue, 1}},
+ {2149, {wxRadioButton, 'Destroy', undefined}},
+ {2151, {wxSlider, new_6, 6}},
+ {2152, {wxSlider, new_0, 0}},
+ {2153, {wxSlider, create, 6}},
+ {2154, {wxSlider, getLineSize, 0}},
+ {2155, {wxSlider, getMax, 0}},
+ {2156, {wxSlider, getMin, 0}},
+ {2157, {wxSlider, getPageSize, 0}},
+ {2158, {wxSlider, getThumbLength, 0}},
+ {2159, {wxSlider, getValue, 0}},
+ {2160, {wxSlider, setLineSize, 1}},
+ {2161, {wxSlider, setPageSize, 1}},
+ {2162, {wxSlider, setRange, 2}},
+ {2163, {wxSlider, setThumbLength, 1}},
+ {2164, {wxSlider, setValue, 1}},
+ {2165, {wxSlider, 'Destroy', undefined}},
+ {2167, {wxDialog, new_4, 4}},
+ {2168, {wxDialog, new_0, 0}},
+ {2170, {wxDialog, destruct, 0}},
+ {2171, {wxDialog, create, 4}},
+ {2172, {wxDialog, createButtonSizer, 1}},
+ {2173, {wxDialog, createStdDialogButtonSizer, 1}},
+ {2174, {wxDialog, endModal, 1}},
+ {2175, {wxDialog, getAffirmativeId, 0}},
+ {2176, {wxDialog, getReturnCode, 0}},
+ {2177, {wxDialog, isModal, 0}},
+ {2178, {wxDialog, setAffirmativeId, 1}},
+ {2179, {wxDialog, setReturnCode, 1}},
+ {2180, {wxDialog, show, 1}},
+ {2181, {wxDialog, showModal, 0}},
+ {2182, {wxColourDialog, new_0, 0}},
+ {2183, {wxColourDialog, new_2, 2}},
+ {2184, {wxColourDialog, destruct, 0}},
+ {2185, {wxColourDialog, create, 2}},
+ {2186, {wxColourDialog, getColourData, 0}},
+ {2187, {wxColourData, new_0, 0}},
+ {2188, {wxColourData, new_1, 1}},
+ {2189, {wxColourData, destruct, 0}},
+ {2190, {wxColourData, getChooseFull, 0}},
+ {2191, {wxColourData, getColour, 0}},
+ {2193, {wxColourData, getCustomColour, 1}},
+ {2194, {wxColourData, setChooseFull, 1}},
+ {2195, {wxColourData, setColour, 1}},
+ {2196, {wxColourData, setCustomColour, 2}},
+ {2197, {wxPalette, new_0, 0}},
+ {2198, {wxPalette, new_4, 4}},
+ {2200, {wxPalette, destruct, 0}},
+ {2201, {wxPalette, create, 4}},
+ {2202, {wxPalette, getColoursCount, 0}},
+ {2203, {wxPalette, getPixel, 3}},
+ {2204, {wxPalette, getRGB, 4}},
+ {2205, {wxPalette, isOk, 0}},
+ {2209, {wxDirDialog, new, 2}},
+ {2210, {wxDirDialog, destruct, 0}},
+ {2211, {wxDirDialog, getPath, 0}},
+ {2212, {wxDirDialog, getMessage, 0}},
+ {2213, {wxDirDialog, setMessage, 1}},
+ {2214, {wxDirDialog, setPath, 1}},
+ {2218, {wxFileDialog, new, 2}},
+ {2219, {wxFileDialog, destruct, 0}},
+ {2220, {wxFileDialog, getDirectory, 0}},
+ {2221, {wxFileDialog, getFilename, 0}},
+ {2222, {wxFileDialog, getFilenames, 1}},
+ {2223, {wxFileDialog, getFilterIndex, 0}},
+ {2224, {wxFileDialog, getMessage, 0}},
+ {2225, {wxFileDialog, getPath, 0}},
+ {2226, {wxFileDialog, getPaths, 1}},
+ {2227, {wxFileDialog, getWildcard, 0}},
+ {2228, {wxFileDialog, setDirectory, 1}},
+ {2229, {wxFileDialog, setFilename, 1}},
+ {2230, {wxFileDialog, setFilterIndex, 1}},
+ {2231, {wxFileDialog, setMessage, 1}},
+ {2232, {wxFileDialog, setPath, 1}},
+ {2233, {wxFileDialog, setWildcard, 1}},
+ {2234, {wxPickerBase, setInternalMargin, 1}},
+ {2235, {wxPickerBase, getInternalMargin, 0}},
+ {2236, {wxPickerBase, setTextCtrlProportion, 1}},
+ {2237, {wxPickerBase, setPickerCtrlProportion, 1}},
+ {2238, {wxPickerBase, getTextCtrlProportion, 0}},
+ {2239, {wxPickerBase, getPickerCtrlProportion, 0}},
+ {2240, {wxPickerBase, hasTextCtrl, 0}},
+ {2241, {wxPickerBase, getTextCtrl, 0}},
+ {2242, {wxPickerBase, isTextCtrlGrowable, 0}},
+ {2243, {wxPickerBase, setPickerCtrlGrowable, 1}},
+ {2244, {wxPickerBase, setTextCtrlGrowable, 1}},
+ {2245, {wxPickerBase, isPickerCtrlGrowable, 0}},
+ {2246, {wxFilePickerCtrl, new_0, 0}},
+ {2247, {wxFilePickerCtrl, new_3, 3}},
+ {2248, {wxFilePickerCtrl, create, 3}},
+ {2249, {wxFilePickerCtrl, getPath, 0}},
+ {2250, {wxFilePickerCtrl, setPath, 1}},
+ {2251, {wxFilePickerCtrl, 'Destroy', undefined}},
+ {2252, {wxDirPickerCtrl, new_0, 0}},
+ {2253, {wxDirPickerCtrl, new_3, 3}},
+ {2254, {wxDirPickerCtrl, create, 3}},
+ {2255, {wxDirPickerCtrl, getPath, 0}},
+ {2256, {wxDirPickerCtrl, setPath, 1}},
+ {2257, {wxDirPickerCtrl, 'Destroy', undefined}},
+ {2258, {wxColourPickerCtrl, new_0, 0}},
+ {2259, {wxColourPickerCtrl, new_3, 3}},
+ {2260, {wxColourPickerCtrl, create, 3}},
+ {2261, {wxColourPickerCtrl, getColour, 0}},
+ {2262, {wxColourPickerCtrl, setColour_1_1, 1}},
+ {2263, {wxColourPickerCtrl, setColour_1_0, 1}},
+ {2264, {wxColourPickerCtrl, 'Destroy', undefined}},
+ {2265, {wxDatePickerCtrl, new_0, 0}},
+ {2266, {wxDatePickerCtrl, new_3, 3}},
+ {2267, {wxDatePickerCtrl, getRange, 2}},
+ {2268, {wxDatePickerCtrl, getValue, 0}},
+ {2269, {wxDatePickerCtrl, setRange, 2}},
+ {2270, {wxDatePickerCtrl, setValue, 1}},
+ {2271, {wxDatePickerCtrl, 'Destroy', undefined}},
+ {2272, {wxFontPickerCtrl, new_0, 0}},
+ {2273, {wxFontPickerCtrl, new_3, 3}},
+ {2274, {wxFontPickerCtrl, create, 3}},
+ {2275, {wxFontPickerCtrl, getSelectedFont, 0}},
+ {2276, {wxFontPickerCtrl, setSelectedFont, 1}},
+ {2277, {wxFontPickerCtrl, getMaxPointSize, 0}},
+ {2278, {wxFontPickerCtrl, setMaxPointSize, 1}},
+ {2279, {wxFontPickerCtrl, 'Destroy', undefined}},
+ {2282, {wxFindReplaceDialog, new_0, 0}},
+ {2283, {wxFindReplaceDialog, new_4, 4}},
+ {2284, {wxFindReplaceDialog, destruct, 0}},
+ {2285, {wxFindReplaceDialog, create, 4}},
+ {2286, {wxFindReplaceDialog, getData, 0}},
+ {2287, {wxFindReplaceData, new_0, 0}},
+ {2288, {wxFindReplaceData, new_1, 1}},
+ {2289, {wxFindReplaceData, getFindString, 0}},
+ {2290, {wxFindReplaceData, getReplaceString, 0}},
+ {2291, {wxFindReplaceData, getFlags, 0}},
+ {2292, {wxFindReplaceData, setFlags, 1}},
+ {2293, {wxFindReplaceData, setFindString, 1}},
+ {2294, {wxFindReplaceData, setReplaceString, 1}},
+ {2295, {wxFindReplaceData, 'Destroy', undefined}},
+ {2296, {wxMultiChoiceDialog, new_0, 0}},
+ {2298, {wxMultiChoiceDialog, new_5, 5}},
+ {2299, {wxMultiChoiceDialog, getSelections, 0}},
+ {2300, {wxMultiChoiceDialog, setSelections, 1}},
+ {2301, {wxMultiChoiceDialog, 'Destroy', undefined}},
+ {2302, {wxSingleChoiceDialog, new_0, 0}},
+ {2304, {wxSingleChoiceDialog, new_5, 5}},
+ {2305, {wxSingleChoiceDialog, getSelection, 0}},
+ {2306, {wxSingleChoiceDialog, getStringSelection, 0}},
+ {2307, {wxSingleChoiceDialog, setSelection, 1}},
+ {2308, {wxSingleChoiceDialog, 'Destroy', undefined}},
+ {2309, {wxTextEntryDialog, new, 3}},
+ {2310, {wxTextEntryDialog, getValue, 0}},
+ {2311, {wxTextEntryDialog, setValue, 1}},
+ {2312, {wxTextEntryDialog, 'Destroy', undefined}},
+ {2313, {wxPasswordEntryDialog, new, 3}},
+ {2314, {wxPasswordEntryDialog, 'Destroy', undefined}},
+ {2315, {wxFontData, new_0, 0}},
+ {2316, {wxFontData, new_1, 1}},
+ {2317, {wxFontData, destruct, 0}},
+ {2318, {wxFontData, enableEffects, 1}},
+ {2319, {wxFontData, getAllowSymbols, 0}},
+ {2320, {wxFontData, getColour, 0}},
+ {2321, {wxFontData, getChosenFont, 0}},
+ {2322, {wxFontData, getEnableEffects, 0}},
+ {2323, {wxFontData, getInitialFont, 0}},
+ {2324, {wxFontData, getShowHelp, 0}},
+ {2325, {wxFontData, setAllowSymbols, 1}},
+ {2326, {wxFontData, setChosenFont, 1}},
+ {2327, {wxFontData, setColour, 1}},
+ {2328, {wxFontData, setInitialFont, 1}},
+ {2329, {wxFontData, setRange, 2}},
+ {2330, {wxFontData, setShowHelp, 1}},
+ {2334, {wxFontDialog, new_0, 0}},
+ {2336, {wxFontDialog, new_2, 2}},
+ {2338, {wxFontDialog, create, 2}},
+ {2339, {wxFontDialog, getFontData, 0}},
+ {2341, {wxFontDialog, 'Destroy', undefined}},
+ {2342, {wxProgressDialog, new, 3}},
+ {2343, {wxProgressDialog, destruct, 0}},
+ {2344, {wxProgressDialog, resume, 0}},
+ {2345, {wxProgressDialog, update_2, 2}},
+ {2346, {wxProgressDialog, update_0, 0}},
+ {2347, {wxMessageDialog, new, 3}},
+ {2348, {wxMessageDialog, destruct, 0}},
+ {2349, {wxPageSetupDialog, new, 2}},
+ {2350, {wxPageSetupDialog, destruct, 0}},
+ {2351, {wxPageSetupDialog, getPageSetupData, 0}},
+ {2352, {wxPageSetupDialog, showModal, 0}},
+ {2353, {wxPageSetupDialogData, new_0, 0}},
+ {2354, {wxPageSetupDialogData, new_1_0, 1}},
+ {2355, {wxPageSetupDialogData, new_1_1, 1}},
+ {2356, {wxPageSetupDialogData, destruct, 0}},
+ {2357, {wxPageSetupDialogData, enableHelp, 1}},
+ {2358, {wxPageSetupDialogData, enableMargins, 1}},
+ {2359, {wxPageSetupDialogData, enableOrientation, 1}},
+ {2360, {wxPageSetupDialogData, enablePaper, 1}},
+ {2361, {wxPageSetupDialogData, enablePrinter, 1}},
+ {2362, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
+ {2363, {wxPageSetupDialogData, getEnableMargins, 0}},
+ {2364, {wxPageSetupDialogData, getEnableOrientation, 0}},
+ {2365, {wxPageSetupDialogData, getEnablePaper, 0}},
+ {2366, {wxPageSetupDialogData, getEnablePrinter, 0}},
+ {2367, {wxPageSetupDialogData, getEnableHelp, 0}},
+ {2368, {wxPageSetupDialogData, getDefaultInfo, 0}},
+ {2369, {wxPageSetupDialogData, getMarginTopLeft, 0}},
+ {2370, {wxPageSetupDialogData, getMarginBottomRight, 0}},
+ {2371, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
+ {2372, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
+ {2373, {wxPageSetupDialogData, getPaperId, 0}},
+ {2374, {wxPageSetupDialogData, getPaperSize, 0}},
+ {2376, {wxPageSetupDialogData, getPrintData, 0}},
+ {2377, {wxPageSetupDialogData, isOk, 0}},
+ {2378, {wxPageSetupDialogData, setDefaultInfo, 1}},
+ {2379, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
+ {2380, {wxPageSetupDialogData, setMarginTopLeft, 1}},
+ {2381, {wxPageSetupDialogData, setMarginBottomRight, 1}},
+ {2382, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
+ {2383, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
+ {2384, {wxPageSetupDialogData, setPaperId, 1}},
+ {2385, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
+ {2386, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
+ {2387, {wxPageSetupDialogData, setPrintData, 1}},
+ {2388, {wxPrintDialog, new_2_0, 2}},
+ {2389, {wxPrintDialog, new_2_1, 2}},
+ {2390, {wxPrintDialog, destruct, 0}},
+ {2391, {wxPrintDialog, getPrintDialogData, 0}},
+ {2392, {wxPrintDialog, getPrintDC, 0}},
+ {2393, {wxPrintDialogData, new_0, 0}},
+ {2394, {wxPrintDialogData, new_1_1, 1}},
+ {2395, {wxPrintDialogData, new_1_0, 1}},
+ {2396, {wxPrintDialogData, destruct, 0}},
+ {2397, {wxPrintDialogData, enableHelp, 1}},
+ {2398, {wxPrintDialogData, enablePageNumbers, 1}},
+ {2399, {wxPrintDialogData, enablePrintToFile, 1}},
+ {2400, {wxPrintDialogData, enableSelection, 1}},
+ {2401, {wxPrintDialogData, getAllPages, 0}},
+ {2402, {wxPrintDialogData, getCollate, 0}},
+ {2403, {wxPrintDialogData, getFromPage, 0}},
+ {2404, {wxPrintDialogData, getMaxPage, 0}},
+ {2405, {wxPrintDialogData, getMinPage, 0}},
+ {2406, {wxPrintDialogData, getNoCopies, 0}},
+ {2407, {wxPrintDialogData, getPrintData, 0}},
+ {2408, {wxPrintDialogData, getPrintToFile, 0}},
+ {2409, {wxPrintDialogData, getSelection, 0}},
+ {2410, {wxPrintDialogData, getToPage, 0}},
+ {2411, {wxPrintDialogData, isOk, 0}},
+ {2412, {wxPrintDialogData, setCollate, 1}},
+ {2413, {wxPrintDialogData, setFromPage, 1}},
+ {2414, {wxPrintDialogData, setMaxPage, 1}},
+ {2415, {wxPrintDialogData, setMinPage, 1}},
+ {2416, {wxPrintDialogData, setNoCopies, 1}},
+ {2417, {wxPrintDialogData, setPrintData, 1}},
+ {2418, {wxPrintDialogData, setPrintToFile, 1}},
+ {2419, {wxPrintDialogData, setSelection, 1}},
+ {2420, {wxPrintDialogData, setToPage, 1}},
+ {2421, {wxPrintData, new_0, 0}},
+ {2422, {wxPrintData, new_1, 1}},
+ {2423, {wxPrintData, destruct, 0}},
+ {2424, {wxPrintData, getCollate, 0}},
+ {2425, {wxPrintData, getBin, 0}},
+ {2426, {wxPrintData, getColour, 0}},
+ {2427, {wxPrintData, getDuplex, 0}},
+ {2428, {wxPrintData, getNoCopies, 0}},
+ {2429, {wxPrintData, getOrientation, 0}},
+ {2430, {wxPrintData, getPaperId, 0}},
+ {2431, {wxPrintData, getPrinterName, 0}},
+ {2432, {wxPrintData, getQuality, 0}},
+ {2433, {wxPrintData, isOk, 0}},
+ {2434, {wxPrintData, setBin, 1}},
+ {2435, {wxPrintData, setCollate, 1}},
+ {2436, {wxPrintData, setColour, 1}},
+ {2437, {wxPrintData, setDuplex, 1}},
+ {2438, {wxPrintData, setNoCopies, 1}},
+ {2439, {wxPrintData, setOrientation, 1}},
+ {2440, {wxPrintData, setPaperId, 1}},
+ {2441, {wxPrintData, setPrinterName, 1}},
+ {2442, {wxPrintData, setQuality, 1}},
+ {2445, {wxPrintPreview, new_2, 2}},
+ {2446, {wxPrintPreview, new_3, 3}},
+ {2448, {wxPrintPreview, destruct, 0}},
+ {2449, {wxPrintPreview, getCanvas, 0}},
+ {2450, {wxPrintPreview, getCurrentPage, 0}},
+ {2451, {wxPrintPreview, getFrame, 0}},
+ {2452, {wxPrintPreview, getMaxPage, 0}},
+ {2453, {wxPrintPreview, getMinPage, 0}},
+ {2454, {wxPrintPreview, getPrintout, 0}},
+ {2455, {wxPrintPreview, getPrintoutForPrinting, 0}},
+ {2456, {wxPrintPreview, isOk, 0}},
+ {2457, {wxPrintPreview, paintPage, 2}},
+ {2458, {wxPrintPreview, print, 1}},
+ {2459, {wxPrintPreview, renderPage, 1}},
+ {2460, {wxPrintPreview, setCanvas, 1}},
+ {2461, {wxPrintPreview, setCurrentPage, 1}},
+ {2462, {wxPrintPreview, setFrame, 1}},
+ {2463, {wxPrintPreview, setPrintout, 1}},
+ {2464, {wxPrintPreview, setZoom, 1}},
+ {2465, {wxPreviewFrame, new, 3}},
+ {2466, {wxPreviewFrame, destruct, 0}},
+ {2467, {wxPreviewFrame, createControlBar, 0}},
+ {2468, {wxPreviewFrame, createCanvas, 0}},
+ {2469, {wxPreviewFrame, initialize, 0}},
+ {2470, {wxPreviewFrame, onCloseWindow, 1}},
+ {2471, {wxPreviewControlBar, new, 4}},
+ {2472, {wxPreviewControlBar, destruct, 0}},
+ {2473, {wxPreviewControlBar, createButtons, 0}},
+ {2474, {wxPreviewControlBar, getPrintPreview, 0}},
+ {2475, {wxPreviewControlBar, getZoomControl, 0}},
+ {2476, {wxPreviewControlBar, setZoomControl, 1}},
+ {2478, {wxPrinter, new, 1}},
+ {2479, {wxPrinter, createAbortWindow, 2}},
+ {2480, {wxPrinter, getAbort, 0}},
+ {2481, {wxPrinter, getLastError, 0}},
+ {2482, {wxPrinter, getPrintDialogData, 0}},
+ {2483, {wxPrinter, print, 3}},
+ {2484, {wxPrinter, printDialog, 1}},
+ {2485, {wxPrinter, reportError, 3}},
+ {2486, {wxPrinter, setup, 1}},
+ {2487, {wxPrinter, 'Destroy', undefined}},
+ {2488, {wxXmlResource, new_1, 1}},
+ {2489, {wxXmlResource, new_2, 2}},
+ {2490, {wxXmlResource, destruct, 0}},
+ {2491, {wxXmlResource, attachUnknownControl, 3}},
+ {2492, {wxXmlResource, clearHandlers, 0}},
+ {2493, {wxXmlResource, compareVersion, 4}},
+ {2494, {wxXmlResource, get, 0}},
+ {2495, {wxXmlResource, getFlags, 0}},
+ {2496, {wxXmlResource, getVersion, 0}},
+ {2497, {wxXmlResource, getXRCID, 2}},
+ {2498, {wxXmlResource, initAllHandlers, 0}},
+ {2499, {wxXmlResource, load, 1}},
+ {2500, {wxXmlResource, loadBitmap, 1}},
+ {2501, {wxXmlResource, loadDialog_2, 2}},
+ {2502, {wxXmlResource, loadDialog_3, 3}},
+ {2503, {wxXmlResource, loadFrame_2, 2}},
+ {2504, {wxXmlResource, loadFrame_3, 3}},
+ {2505, {wxXmlResource, loadIcon, 1}},
+ {2506, {wxXmlResource, loadMenu, 1}},
+ {2507, {wxXmlResource, loadMenuBar_2, 2}},
+ {2508, {wxXmlResource, loadMenuBar_1, 1}},
+ {2509, {wxXmlResource, loadPanel_2, 2}},
+ {2510, {wxXmlResource, loadPanel_3, 3}},
+ {2511, {wxXmlResource, loadToolBar, 2}},
+ {2512, {wxXmlResource, set, 1}},
+ {2513, {wxXmlResource, setFlags, 1}},
+ {2514, {wxXmlResource, unload, 1}},
+ {2515, {wxXmlResource, xrcctrl, 3}},
+ {2516, {wxHtmlEasyPrinting, new, 1}},
+ {2517, {wxHtmlEasyPrinting, destruct, 0}},
+ {2518, {wxHtmlEasyPrinting, getPrintData, 0}},
+ {2519, {wxHtmlEasyPrinting, getPageSetupData, 0}},
+ {2520, {wxHtmlEasyPrinting, previewFile, 1}},
+ {2521, {wxHtmlEasyPrinting, previewText, 2}},
+ {2522, {wxHtmlEasyPrinting, printFile, 1}},
+ {2523, {wxHtmlEasyPrinting, printText, 2}},
+ {2524, {wxHtmlEasyPrinting, pageSetup, 0}},
+ {2525, {wxHtmlEasyPrinting, setFonts, 3}},
+ {2526, {wxHtmlEasyPrinting, setHeader, 2}},
+ {2527, {wxHtmlEasyPrinting, setFooter, 2}},
+ {2529, {wxGLCanvas, new_2, 2}},
+ {2530, {wxGLCanvas, new_3_1, 3}},
+ {2531, {wxGLCanvas, new_3_0, 3}},
+ {2532, {wxGLCanvas, getContext, 0}},
+ {2534, {wxGLCanvas, setCurrent, 0}},
+ {2535, {wxGLCanvas, swapBuffers, 0}},
+ {2536, {wxGLCanvas, 'Destroy', undefined}},
+ {2537, {wxAuiManager, new, 1}},
+ {2538, {wxAuiManager, destruct, 0}},
+ {2539, {wxAuiManager, addPane_2_1, 2}},
+ {2540, {wxAuiManager, addPane_3, 3}},
+ {2541, {wxAuiManager, addPane_2_0, 2}},
+ {2542, {wxAuiManager, detachPane, 1}},
+ {2543, {wxAuiManager, getAllPanes, 0}},
+ {2544, {wxAuiManager, getArtProvider, 0}},
+ {2545, {wxAuiManager, getDockSizeConstraint, 2}},
+ {2546, {wxAuiManager, getFlags, 0}},
+ {2547, {wxAuiManager, getManagedWindow, 0}},
+ {2548, {wxAuiManager, getManager, 1}},
+ {2549, {wxAuiManager, getPane_1_1, 1}},
+ {2550, {wxAuiManager, getPane_1_0, 1}},
+ {2551, {wxAuiManager, hideHint, 0}},
+ {2552, {wxAuiManager, insertPane, 3}},
+ {2553, {wxAuiManager, loadPaneInfo, 2}},
+ {2554, {wxAuiManager, loadPerspective, 2}},
+ {2555, {wxAuiManager, savePaneInfo, 1}},
+ {2556, {wxAuiManager, savePerspective, 0}},
+ {2557, {wxAuiManager, setArtProvider, 1}},
+ {2558, {wxAuiManager, setDockSizeConstraint, 2}},
+ {2559, {wxAuiManager, setFlags, 1}},
+ {2560, {wxAuiManager, setManagedWindow, 1}},
+ {2561, {wxAuiManager, showHint, 1}},
+ {2562, {wxAuiManager, unInit, 0}},
+ {2563, {wxAuiManager, update, 0}},
+ {2564, {wxAuiPaneInfo, new_0, 0}},
+ {2565, {wxAuiPaneInfo, new_1, 1}},
+ {2566, {wxAuiPaneInfo, destruct, 0}},
+ {2567, {wxAuiPaneInfo, bestSize_1, 1}},
+ {2568, {wxAuiPaneInfo, bestSize_2, 2}},
+ {2569, {wxAuiPaneInfo, bottom, 0}},
+ {2570, {wxAuiPaneInfo, bottomDockable, 1}},
+ {2571, {wxAuiPaneInfo, caption, 1}},
+ {2572, {wxAuiPaneInfo, captionVisible, 1}},
+ {2573, {wxAuiPaneInfo, centre, 0}},
+ {2574, {wxAuiPaneInfo, centrePane, 0}},
+ {2575, {wxAuiPaneInfo, closeButton, 1}},
+ {2576, {wxAuiPaneInfo, defaultPane, 0}},
+ {2577, {wxAuiPaneInfo, destroyOnClose, 1}},
+ {2578, {wxAuiPaneInfo, direction, 1}},
+ {2579, {wxAuiPaneInfo, dock, 0}},
+ {2580, {wxAuiPaneInfo, dockable, 1}},
+ {2581, {wxAuiPaneInfo, fixed, 0}},
+ {2582, {wxAuiPaneInfo, float, 0}},
+ {2583, {wxAuiPaneInfo, floatable, 1}},
+ {2584, {wxAuiPaneInfo, floatingPosition_1, 1}},
+ {2585, {wxAuiPaneInfo, floatingPosition_2, 2}},
+ {2586, {wxAuiPaneInfo, floatingSize_1, 1}},
+ {2587, {wxAuiPaneInfo, floatingSize_2, 2}},
+ {2588, {wxAuiPaneInfo, gripper, 1}},
+ {2589, {wxAuiPaneInfo, gripperTop, 1}},
+ {2590, {wxAuiPaneInfo, hasBorder, 0}},
+ {2591, {wxAuiPaneInfo, hasCaption, 0}},
+ {2592, {wxAuiPaneInfo, hasCloseButton, 0}},
+ {2593, {wxAuiPaneInfo, hasFlag, 1}},
+ {2594, {wxAuiPaneInfo, hasGripper, 0}},
+ {2595, {wxAuiPaneInfo, hasGripperTop, 0}},
+ {2596, {wxAuiPaneInfo, hasMaximizeButton, 0}},
+ {2597, {wxAuiPaneInfo, hasMinimizeButton, 0}},
+ {2598, {wxAuiPaneInfo, hasPinButton, 0}},
+ {2599, {wxAuiPaneInfo, hide, 0}},
+ {2600, {wxAuiPaneInfo, isBottomDockable, 0}},
+ {2601, {wxAuiPaneInfo, isDocked, 0}},
+ {2602, {wxAuiPaneInfo, isFixed, 0}},
+ {2603, {wxAuiPaneInfo, isFloatable, 0}},
+ {2604, {wxAuiPaneInfo, isFloating, 0}},
+ {2605, {wxAuiPaneInfo, isLeftDockable, 0}},
+ {2606, {wxAuiPaneInfo, isMovable, 0}},
+ {2607, {wxAuiPaneInfo, isOk, 0}},
+ {2608, {wxAuiPaneInfo, isResizable, 0}},
+ {2609, {wxAuiPaneInfo, isRightDockable, 0}},
+ {2610, {wxAuiPaneInfo, isShown, 0}},
+ {2611, {wxAuiPaneInfo, isToolbar, 0}},
+ {2612, {wxAuiPaneInfo, isTopDockable, 0}},
+ {2613, {wxAuiPaneInfo, layer, 1}},
+ {2614, {wxAuiPaneInfo, left, 0}},
+ {2615, {wxAuiPaneInfo, leftDockable, 1}},
+ {2616, {wxAuiPaneInfo, maxSize_1, 1}},
+ {2617, {wxAuiPaneInfo, maxSize_2, 2}},
+ {2618, {wxAuiPaneInfo, maximizeButton, 1}},
+ {2619, {wxAuiPaneInfo, minSize_1, 1}},
+ {2620, {wxAuiPaneInfo, minSize_2, 2}},
+ {2621, {wxAuiPaneInfo, minimizeButton, 1}},
+ {2622, {wxAuiPaneInfo, movable, 1}},
+ {2623, {wxAuiPaneInfo, name, 1}},
+ {2624, {wxAuiPaneInfo, paneBorder, 1}},
+ {2625, {wxAuiPaneInfo, pinButton, 1}},
+ {2626, {wxAuiPaneInfo, position, 1}},
+ {2627, {wxAuiPaneInfo, resizable, 1}},
+ {2628, {wxAuiPaneInfo, right, 0}},
+ {2629, {wxAuiPaneInfo, rightDockable, 1}},
+ {2630, {wxAuiPaneInfo, row, 1}},
+ {2631, {wxAuiPaneInfo, safeSet, 1}},
+ {2632, {wxAuiPaneInfo, setFlag, 2}},
+ {2633, {wxAuiPaneInfo, show, 1}},
+ {2634, {wxAuiPaneInfo, toolbarPane, 0}},
+ {2635, {wxAuiPaneInfo, top, 0}},
+ {2636, {wxAuiPaneInfo, topDockable, 1}},
+ {2637, {wxAuiPaneInfo, window, 1}},
+ {2638, {wxAuiNotebook, new_0, 0}},
+ {2639, {wxAuiNotebook, new_2, 2}},
+ {2640, {wxAuiNotebook, addPage, 3}},
+ {2641, {wxAuiNotebook, create, 2}},
+ {2642, {wxAuiNotebook, deletePage, 1}},
+ {2643, {wxAuiNotebook, getArtProvider, 0}},
+ {2644, {wxAuiNotebook, getPage, 1}},
+ {2645, {wxAuiNotebook, getPageBitmap, 1}},
+ {2646, {wxAuiNotebook, getPageCount, 0}},
+ {2647, {wxAuiNotebook, getPageIndex, 1}},
+ {2648, {wxAuiNotebook, getPageText, 1}},
+ {2649, {wxAuiNotebook, getSelection, 0}},
+ {2650, {wxAuiNotebook, insertPage, 4}},
+ {2651, {wxAuiNotebook, removePage, 1}},
+ {2652, {wxAuiNotebook, setArtProvider, 1}},
+ {2653, {wxAuiNotebook, setFont, 1}},
+ {2654, {wxAuiNotebook, setPageBitmap, 2}},
+ {2655, {wxAuiNotebook, setPageText, 2}},
+ {2656, {wxAuiNotebook, setSelection, 1}},
+ {2657, {wxAuiNotebook, setTabCtrlHeight, 1}},
+ {2658, {wxAuiNotebook, setUniformBitmapSize, 1}},
+ {2659, {wxAuiNotebook, 'Destroy', undefined}},
+ {2660, {wxMDIParentFrame, new_0, 0}},
+ {2661, {wxMDIParentFrame, new_4, 4}},
+ {2662, {wxMDIParentFrame, destruct, 0}},
+ {2663, {wxMDIParentFrame, activateNext, 0}},
+ {2664, {wxMDIParentFrame, activatePrevious, 0}},
+ {2665, {wxMDIParentFrame, arrangeIcons, 0}},
+ {2666, {wxMDIParentFrame, cascade, 0}},
+ {2667, {wxMDIParentFrame, create, 4}},
+ {2668, {wxMDIParentFrame, getActiveChild, 0}},
+ {2669, {wxMDIParentFrame, getClientWindow, 0}},
+ {2670, {wxMDIParentFrame, tile, 1}},
+ {2671, {wxMDIChildFrame, new_0, 0}},
+ {2672, {wxMDIChildFrame, new_4, 4}},
+ {2673, {wxMDIChildFrame, destruct, 0}},
+ {2674, {wxMDIChildFrame, activate, 0}},
+ {2675, {wxMDIChildFrame, create, 4}},
+ {2676, {wxMDIChildFrame, maximize, 1}},
+ {2677, {wxMDIChildFrame, restore, 0}},
+ {2678, {wxMDIClientWindow, new_0, 0}},
+ {2679, {wxMDIClientWindow, new_2, 2}},
+ {2680, {wxMDIClientWindow, destruct, 0}},
+ {2681, {wxMDIClientWindow, createClient, 2}},
+ {2682, {wxLayoutAlgorithm, new, 0}},
+ {2683, {wxLayoutAlgorithm, layoutFrame, 2}},
+ {2684, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
+ {2685, {wxLayoutAlgorithm, layoutWindow, 2}},
+ {2686, {wxLayoutAlgorithm, 'Destroy', undefined}},
+ {2687, {wxEvent, getId, 0}},
+ {2688, {wxEvent, getSkipped, 0}},
+ {2689, {wxEvent, getTimestamp, 0}},
+ {2690, {wxEvent, isCommandEvent, 0}},
+ {2691, {wxEvent, resumePropagation, 1}},
+ {2692, {wxEvent, shouldPropagate, 0}},
+ {2693, {wxEvent, skip, 1}},
+ {2694, {wxEvent, stopPropagation, 0}},
+ {2695, {wxCommandEvent, getClientData, 0}},
+ {2696, {wxCommandEvent, getExtraLong, 0}},
+ {2697, {wxCommandEvent, getInt, 0}},
+ {2698, {wxCommandEvent, getSelection, 0}},
+ {2699, {wxCommandEvent, getString, 0}},
+ {2700, {wxCommandEvent, isChecked, 0}},
+ {2701, {wxCommandEvent, isSelection, 0}},
+ {2702, {wxCommandEvent, setInt, 1}},
+ {2703, {wxCommandEvent, setString, 1}},
+ {2704, {wxScrollEvent, getOrientation, 0}},
+ {2705, {wxScrollEvent, getPosition, 0}},
+ {2706, {wxScrollWinEvent, getOrientation, 0}},
+ {2707, {wxScrollWinEvent, getPosition, 0}},
+ {2708, {wxMouseEvent, altDown, 0}},
+ {2709, {wxMouseEvent, button, 1}},
+ {2710, {wxMouseEvent, buttonDClick, 1}},
+ {2711, {wxMouseEvent, buttonDown, 1}},
+ {2712, {wxMouseEvent, buttonUp, 1}},
+ {2713, {wxMouseEvent, cmdDown, 0}},
+ {2714, {wxMouseEvent, controlDown, 0}},
+ {2715, {wxMouseEvent, dragging, 0}},
+ {2716, {wxMouseEvent, entering, 0}},
+ {2717, {wxMouseEvent, getButton, 0}},
+ {2720, {wxMouseEvent, getPosition, 0}},
+ {2721, {wxMouseEvent, getLogicalPosition, 1}},
+ {2722, {wxMouseEvent, getLinesPerAction, 0}},
+ {2723, {wxMouseEvent, getWheelRotation, 0}},
+ {2724, {wxMouseEvent, getWheelDelta, 0}},
+ {2725, {wxMouseEvent, getX, 0}},
+ {2726, {wxMouseEvent, getY, 0}},
+ {2727, {wxMouseEvent, isButton, 0}},
+ {2728, {wxMouseEvent, isPageScroll, 0}},
+ {2729, {wxMouseEvent, leaving, 0}},
+ {2730, {wxMouseEvent, leftDClick, 0}},
+ {2731, {wxMouseEvent, leftDown, 0}},
+ {2732, {wxMouseEvent, leftIsDown, 0}},
+ {2733, {wxMouseEvent, leftUp, 0}},
+ {2734, {wxMouseEvent, metaDown, 0}},
+ {2735, {wxMouseEvent, middleDClick, 0}},
+ {2736, {wxMouseEvent, middleDown, 0}},
+ {2737, {wxMouseEvent, middleIsDown, 0}},
+ {2738, {wxMouseEvent, middleUp, 0}},
+ {2739, {wxMouseEvent, moving, 0}},
+ {2740, {wxMouseEvent, rightDClick, 0}},
+ {2741, {wxMouseEvent, rightDown, 0}},
+ {2742, {wxMouseEvent, rightIsDown, 0}},
+ {2743, {wxMouseEvent, rightUp, 0}},
+ {2744, {wxMouseEvent, shiftDown, 0}},
+ {2745, {wxSetCursorEvent, getCursor, 0}},
+ {2746, {wxSetCursorEvent, getX, 0}},
+ {2747, {wxSetCursorEvent, getY, 0}},
+ {2748, {wxSetCursorEvent, hasCursor, 0}},
+ {2749, {wxSetCursorEvent, setCursor, 1}},
+ {2750, {wxKeyEvent, altDown, 0}},
+ {2751, {wxKeyEvent, cmdDown, 0}},
+ {2752, {wxKeyEvent, controlDown, 0}},
+ {2753, {wxKeyEvent, getKeyCode, 0}},
+ {2754, {wxKeyEvent, getModifiers, 0}},
+ {2757, {wxKeyEvent, getPosition, 0}},
+ {2758, {wxKeyEvent, getRawKeyCode, 0}},
+ {2759, {wxKeyEvent, getRawKeyFlags, 0}},
+ {2760, {wxKeyEvent, getUnicodeKey, 0}},
+ {2761, {wxKeyEvent, getX, 0}},
+ {2762, {wxKeyEvent, getY, 0}},
+ {2763, {wxKeyEvent, hasModifiers, 0}},
+ {2764, {wxKeyEvent, metaDown, 0}},
+ {2765, {wxKeyEvent, shiftDown, 0}},
+ {2766, {wxSizeEvent, getSize, 0}},
+ {2767, {wxMoveEvent, getPosition, 0}},
+ {2768, {wxEraseEvent, getDC, 0}},
+ {2769, {wxFocusEvent, getWindow, 0}},
+ {2770, {wxChildFocusEvent, getWindow, 0}},
+ {2771, {wxMenuEvent, getMenu, 0}},
+ {2772, {wxMenuEvent, getMenuId, 0}},
+ {2773, {wxMenuEvent, isPopup, 0}},
+ {2774, {wxCloseEvent, canVeto, 0}},
+ {2775, {wxCloseEvent, getLoggingOff, 0}},
+ {2776, {wxCloseEvent, setCanVeto, 1}},
+ {2777, {wxCloseEvent, setLoggingOff, 1}},
+ {2778, {wxCloseEvent, veto, 1}},
+ {2779, {wxShowEvent, setShow, 1}},
+ {2780, {wxShowEvent, getShow, 0}},
+ {2781, {wxIconizeEvent, iconized, 0}},
+ {2782, {wxJoystickEvent, buttonDown, 1}},
+ {2783, {wxJoystickEvent, buttonIsDown, 1}},
+ {2784, {wxJoystickEvent, buttonUp, 1}},
+ {2785, {wxJoystickEvent, getButtonChange, 0}},
+ {2786, {wxJoystickEvent, getButtonState, 0}},
+ {2787, {wxJoystickEvent, getJoystick, 0}},
+ {2788, {wxJoystickEvent, getPosition, 0}},
+ {2789, {wxJoystickEvent, getZPosition, 0}},
+ {2790, {wxJoystickEvent, isButton, 0}},
+ {2791, {wxJoystickEvent, isMove, 0}},
+ {2792, {wxJoystickEvent, isZMove, 0}},
+ {2793, {wxUpdateUIEvent, canUpdate, 1}},
+ {2794, {wxUpdateUIEvent, check, 1}},
+ {2795, {wxUpdateUIEvent, enable, 1}},
+ {2796, {wxUpdateUIEvent, show, 1}},
+ {2797, {wxUpdateUIEvent, getChecked, 0}},
+ {2798, {wxUpdateUIEvent, getEnabled, 0}},
+ {2799, {wxUpdateUIEvent, getShown, 0}},
+ {2800, {wxUpdateUIEvent, getSetChecked, 0}},
+ {2801, {wxUpdateUIEvent, getSetEnabled, 0}},
+ {2802, {wxUpdateUIEvent, getSetShown, 0}},
+ {2803, {wxUpdateUIEvent, getSetText, 0}},
+ {2804, {wxUpdateUIEvent, getText, 0}},
+ {2805, {wxUpdateUIEvent, getMode, 0}},
+ {2806, {wxUpdateUIEvent, getUpdateInterval, 0}},
+ {2807, {wxUpdateUIEvent, resetUpdateTime, 0}},
+ {2808, {wxUpdateUIEvent, setMode, 1}},
+ {2809, {wxUpdateUIEvent, setText, 1}},
+ {2810, {wxUpdateUIEvent, setUpdateInterval, 1}},
+ {2811, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
+ {2812, {wxPaletteChangedEvent, setChangedWindow, 1}},
+ {2813, {wxPaletteChangedEvent, getChangedWindow, 0}},
+ {2814, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
+ {2815, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
+ {2816, {wxNavigationKeyEvent, getDirection, 0}},
+ {2817, {wxNavigationKeyEvent, setDirection, 1}},
+ {2818, {wxNavigationKeyEvent, isWindowChange, 0}},
+ {2819, {wxNavigationKeyEvent, setWindowChange, 1}},
+ {2820, {wxNavigationKeyEvent, isFromTab, 0}},
+ {2821, {wxNavigationKeyEvent, setFromTab, 1}},
+ {2822, {wxNavigationKeyEvent, getCurrentFocus, 0}},
+ {2823, {wxNavigationKeyEvent, setCurrentFocus, 1}},
+ {2824, {wxHelpEvent, getOrigin, 0}},
+ {2825, {wxHelpEvent, getPosition, 0}},
+ {2826, {wxHelpEvent, setOrigin, 1}},
+ {2827, {wxHelpEvent, setPosition, 1}},
+ {2828, {wxContextMenuEvent, getPosition, 0}},
+ {2829, {wxContextMenuEvent, setPosition, 1}},
+ {2830, {wxIdleEvent, canSend, 1}},
+ {2831, {wxIdleEvent, getMode, 0}},
+ {2832, {wxIdleEvent, requestMore, 1}},
+ {2833, {wxIdleEvent, moreRequested, 0}},
+ {2834, {wxIdleEvent, setMode, 1}},
+ {2835, {wxGridEvent, altDown, 0}},
+ {2836, {wxGridEvent, controlDown, 0}},
+ {2837, {wxGridEvent, getCol, 0}},
+ {2838, {wxGridEvent, getPosition, 0}},
+ {2839, {wxGridEvent, getRow, 0}},
+ {2840, {wxGridEvent, metaDown, 0}},
+ {2841, {wxGridEvent, selecting, 0}},
+ {2842, {wxGridEvent, shiftDown, 0}},
+ {2843, {wxNotifyEvent, allow, 0}},
+ {2844, {wxNotifyEvent, isAllowed, 0}},
+ {2845, {wxNotifyEvent, veto, 0}},
+ {2846, {wxSashEvent, getEdge, 0}},
+ {2847, {wxSashEvent, getDragRect, 0}},
+ {2848, {wxSashEvent, getDragStatus, 0}},
+ {2849, {wxListEvent, getCacheFrom, 0}},
+ {2850, {wxListEvent, getCacheTo, 0}},
+ {2851, {wxListEvent, getKeyCode, 0}},
+ {2852, {wxListEvent, getIndex, 0}},
+ {2853, {wxListEvent, getColumn, 0}},
+ {2854, {wxListEvent, getPoint, 0}},
+ {2855, {wxListEvent, getLabel, 0}},
+ {2856, {wxListEvent, getText, 0}},
+ {2857, {wxListEvent, getImage, 0}},
+ {2858, {wxListEvent, getData, 0}},
+ {2859, {wxListEvent, getMask, 0}},
+ {2860, {wxListEvent, getItem, 0}},
+ {2861, {wxListEvent, isEditCancelled, 0}},
+ {2862, {wxDateEvent, getDate, 0}},
+ {2863, {wxCalendarEvent, getWeekDay, 0}},
+ {2864, {wxFileDirPickerEvent, getPath, 0}},
+ {2865, {wxColourPickerEvent, getColour, 0}},
+ {2866, {wxFontPickerEvent, getFont, 0}},
+ {2867, {wxStyledTextEvent, getPosition, 0}},
+ {2868, {wxStyledTextEvent, getKey, 0}},
+ {2869, {wxStyledTextEvent, getModifiers, 0}},
+ {2870, {wxStyledTextEvent, getModificationType, 0}},
+ {2871, {wxStyledTextEvent, getText, 0}},
+ {2872, {wxStyledTextEvent, getLength, 0}},
+ {2873, {wxStyledTextEvent, getLinesAdded, 0}},
+ {2874, {wxStyledTextEvent, getLine, 0}},
+ {2875, {wxStyledTextEvent, getFoldLevelNow, 0}},
+ {2876, {wxStyledTextEvent, getFoldLevelPrev, 0}},
+ {2877, {wxStyledTextEvent, getMargin, 0}},
+ {2878, {wxStyledTextEvent, getMessage, 0}},
+ {2879, {wxStyledTextEvent, getWParam, 0}},
+ {2880, {wxStyledTextEvent, getLParam, 0}},
+ {2881, {wxStyledTextEvent, getListType, 0}},
+ {2882, {wxStyledTextEvent, getX, 0}},
+ {2883, {wxStyledTextEvent, getY, 0}},
+ {2884, {wxStyledTextEvent, getDragText, 0}},
+ {2885, {wxStyledTextEvent, getDragAllowMove, 0}},
+ {2886, {wxStyledTextEvent, getDragResult, 0}},
+ {2887, {wxStyledTextEvent, getShift, 0}},
+ {2888, {wxStyledTextEvent, getControl, 0}},
+ {2889, {wxStyledTextEvent, getAlt, 0}},
+ {2890, {utils, getKeyState, 1}},
+ {2891, {utils, getMousePosition, 2}},
+ {2892, {utils, getMouseState, 0}},
+ {2893, {utils, setDetectableAutoRepeat, 1}},
+ {2894, {utils, bell, 0}},
+ {2895, {utils, findMenuItemId, 3}},
+ {2896, {utils, genericFindWindowAtPoint, 1}},
+ {2897, {utils, findWindowAtPoint, 1}},
+ {2898, {utils, beginBusyCursor, 1}},
+ {2899, {utils, endBusyCursor, 0}},
+ {2900, {utils, isBusy, 0}},
+ {2901, {utils, shutdown, 1}},
+ {2902, {utils, shell, 1}},
+ {2903, {utils, launchDefaultBrowser, 2}},
+ {2904, {utils, getEmailAddress, 0}},
+ {2905, {utils, getUserId, 0}},
+ {2906, {utils, getHomeDir, 0}},
+ {2907, {utils, newId, 0}},
+ {2908, {utils, registerId, 1}},
+ {2909, {utils, getCurrentId, 0}},
+ {2910, {utils, getOsDescription, 0}},
+ {2911, {utils, isPlatformLittleEndian, 0}},
+ {2912, {utils, isPlatform64Bit, 0}},
+ {2913, {wxPrintout, new, 1}},
+ {2914, {wxPrintout, destruct, 0}},
+ {2915, {wxPrintout, getDC, 0}},
+ {2916, {wxPrintout, getPageSizeMM, 2}},
+ {2917, {wxPrintout, getPageSizePixels, 2}},
+ {2918, {wxPrintout, getPaperRectPixels, 0}},
+ {2919, {wxPrintout, getPPIPrinter, 2}},
+ {2920, {wxPrintout, getPPIScreen, 2}},
+ {2921, {wxPrintout, getTitle, 0}},
+ {2922, {wxPrintout, isPreview, 0}},
+ {2923, {wxPrintout, fitThisSizeToPaper, 1}},
+ {2924, {wxPrintout, fitThisSizeToPage, 1}},
+ {2925, {wxPrintout, fitThisSizeToPageMargins, 2}},
+ {2926, {wxPrintout, mapScreenSizeToPaper, 0}},
+ {2927, {wxPrintout, mapScreenSizeToPage, 0}},
+ {2928, {wxPrintout, mapScreenSizeToPageMargins, 1}},
+ {2929, {wxPrintout, mapScreenSizeToDevice, 0}},
+ {2930, {wxPrintout, getLogicalPaperRect, 0}},
+ {2931, {wxPrintout, getLogicalPageRect, 0}},
+ {2932, {wxPrintout, getLogicalPageMarginsRect, 1}},
+ {2933, {wxPrintout, setLogicalOrigin, 2}},
+ {2934, {wxPrintout, offsetLogicalOrigin, 2}},
+ {2935, {wxStyledTextCtrl, new_2, 2}},
+ {2936, {wxStyledTextCtrl, new_0, 0}},
+ {2937, {wxStyledTextCtrl, destruct, 0}},
+ {2938, {wxStyledTextCtrl, create, 2}},
+ {2939, {wxStyledTextCtrl, addText, 1}},
+ {2940, {wxStyledTextCtrl, addStyledText, 1}},
+ {2941, {wxStyledTextCtrl, insertText, 2}},
+ {2942, {wxStyledTextCtrl, clearAll, 0}},
+ {2943, {wxStyledTextCtrl, clearDocumentStyle, 0}},
+ {2944, {wxStyledTextCtrl, getLength, 0}},
+ {2945, {wxStyledTextCtrl, getCharAt, 1}},
+ {2946, {wxStyledTextCtrl, getCurrentPos, 0}},
+ {2947, {wxStyledTextCtrl, getAnchor, 0}},
+ {2948, {wxStyledTextCtrl, getStyleAt, 1}},
+ {2949, {wxStyledTextCtrl, redo, 0}},
+ {2950, {wxStyledTextCtrl, setUndoCollection, 1}},
+ {2951, {wxStyledTextCtrl, selectAll, 0}},
+ {2952, {wxStyledTextCtrl, setSavePoint, 0}},
+ {2953, {wxStyledTextCtrl, getStyledText, 2}},
+ {2954, {wxStyledTextCtrl, canRedo, 0}},
+ {2955, {wxStyledTextCtrl, markerLineFromHandle, 1}},
+ {2956, {wxStyledTextCtrl, markerDeleteHandle, 1}},
+ {2957, {wxStyledTextCtrl, getUndoCollection, 0}},
+ {2958, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
+ {2959, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
+ {2960, {wxStyledTextCtrl, positionFromPoint, 1}},
+ {2961, {wxStyledTextCtrl, positionFromPointClose, 2}},
+ {2962, {wxStyledTextCtrl, gotoLine, 1}},
+ {2963, {wxStyledTextCtrl, gotoPos, 1}},
+ {2964, {wxStyledTextCtrl, setAnchor, 1}},
+ {2965, {wxStyledTextCtrl, getCurLine, 1}},
+ {2966, {wxStyledTextCtrl, getEndStyled, 0}},
+ {2967, {wxStyledTextCtrl, convertEOLs, 1}},
+ {2968, {wxStyledTextCtrl, getEOLMode, 0}},
+ {2969, {wxStyledTextCtrl, setEOLMode, 1}},
+ {2970, {wxStyledTextCtrl, startStyling, 2}},
+ {2971, {wxStyledTextCtrl, setStyling, 2}},
+ {2972, {wxStyledTextCtrl, getBufferedDraw, 0}},
+ {2973, {wxStyledTextCtrl, setBufferedDraw, 1}},
+ {2974, {wxStyledTextCtrl, setTabWidth, 1}},
+ {2975, {wxStyledTextCtrl, getTabWidth, 0}},
+ {2976, {wxStyledTextCtrl, setCodePage, 1}},
+ {2977, {wxStyledTextCtrl, markerDefine, 3}},
+ {2978, {wxStyledTextCtrl, markerSetForeground, 2}},
+ {2979, {wxStyledTextCtrl, markerSetBackground, 2}},
+ {2980, {wxStyledTextCtrl, markerAdd, 2}},
+ {2981, {wxStyledTextCtrl, markerDelete, 2}},
+ {2982, {wxStyledTextCtrl, markerDeleteAll, 1}},
+ {2983, {wxStyledTextCtrl, markerGet, 1}},
+ {2984, {wxStyledTextCtrl, markerNext, 2}},
+ {2985, {wxStyledTextCtrl, markerPrevious, 2}},
+ {2986, {wxStyledTextCtrl, markerDefineBitmap, 2}},
+ {2987, {wxStyledTextCtrl, markerAddSet, 2}},
+ {2988, {wxStyledTextCtrl, markerSetAlpha, 2}},
+ {2989, {wxStyledTextCtrl, setMarginType, 2}},
+ {2990, {wxStyledTextCtrl, getMarginType, 1}},
+ {2991, {wxStyledTextCtrl, setMarginWidth, 2}},
+ {2992, {wxStyledTextCtrl, getMarginWidth, 1}},
+ {2993, {wxStyledTextCtrl, setMarginMask, 2}},
+ {2994, {wxStyledTextCtrl, getMarginMask, 1}},
+ {2995, {wxStyledTextCtrl, setMarginSensitive, 2}},
+ {2996, {wxStyledTextCtrl, getMarginSensitive, 1}},
+ {2997, {wxStyledTextCtrl, styleClearAll, 0}},
+ {2998, {wxStyledTextCtrl, styleSetForeground, 2}},
+ {2999, {wxStyledTextCtrl, styleSetBackground, 2}},
+ {3000, {wxStyledTextCtrl, styleSetBold, 2}},
+ {3001, {wxStyledTextCtrl, styleSetItalic, 2}},
+ {3002, {wxStyledTextCtrl, styleSetSize, 2}},
+ {3003, {wxStyledTextCtrl, styleSetFaceName, 2}},
+ {3004, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
+ {3005, {wxStyledTextCtrl, styleResetDefault, 0}},
+ {3006, {wxStyledTextCtrl, styleSetUnderline, 2}},
+ {3007, {wxStyledTextCtrl, styleSetCase, 2}},
+ {3008, {wxStyledTextCtrl, styleSetHotSpot, 2}},
+ {3009, {wxStyledTextCtrl, setSelForeground, 2}},
+ {3010, {wxStyledTextCtrl, setSelBackground, 2}},
+ {3011, {wxStyledTextCtrl, getSelAlpha, 0}},
+ {3012, {wxStyledTextCtrl, setSelAlpha, 1}},
+ {3013, {wxStyledTextCtrl, setCaretForeground, 1}},
+ {3014, {wxStyledTextCtrl, cmdKeyAssign, 3}},
+ {3015, {wxStyledTextCtrl, cmdKeyClear, 2}},
+ {3016, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
+ {3017, {wxStyledTextCtrl, setStyleBytes, 2}},
+ {3018, {wxStyledTextCtrl, styleSetVisible, 2}},
+ {3019, {wxStyledTextCtrl, getCaretPeriod, 0}},
+ {3020, {wxStyledTextCtrl, setCaretPeriod, 1}},
+ {3021, {wxStyledTextCtrl, setWordChars, 1}},
+ {3022, {wxStyledTextCtrl, beginUndoAction, 0}},
+ {3023, {wxStyledTextCtrl, endUndoAction, 0}},
+ {3024, {wxStyledTextCtrl, indicatorSetStyle, 2}},
+ {3025, {wxStyledTextCtrl, indicatorGetStyle, 1}},
+ {3026, {wxStyledTextCtrl, indicatorSetForeground, 2}},
+ {3027, {wxStyledTextCtrl, indicatorGetForeground, 1}},
+ {3028, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
+ {3029, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
+ {3030, {wxStyledTextCtrl, getStyleBits, 0}},
+ {3031, {wxStyledTextCtrl, setLineState, 2}},
+ {3032, {wxStyledTextCtrl, getLineState, 1}},
+ {3033, {wxStyledTextCtrl, getMaxLineState, 0}},
+ {3034, {wxStyledTextCtrl, getCaretLineVisible, 0}},
+ {3035, {wxStyledTextCtrl, setCaretLineVisible, 1}},
+ {3036, {wxStyledTextCtrl, getCaretLineBackground, 0}},
+ {3037, {wxStyledTextCtrl, setCaretLineBackground, 1}},
+ {3038, {wxStyledTextCtrl, autoCompShow, 2}},
+ {3039, {wxStyledTextCtrl, autoCompCancel, 0}},
+ {3040, {wxStyledTextCtrl, autoCompActive, 0}},
+ {3041, {wxStyledTextCtrl, autoCompPosStart, 0}},
+ {3042, {wxStyledTextCtrl, autoCompComplete, 0}},
+ {3043, {wxStyledTextCtrl, autoCompStops, 1}},
+ {3044, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
+ {3045, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
+ {3046, {wxStyledTextCtrl, autoCompSelect, 1}},
+ {3047, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
+ {3048, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
+ {3049, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
+ {3050, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
+ {3051, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
+ {3052, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
+ {3053, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
+ {3054, {wxStyledTextCtrl, userListShow, 2}},
+ {3055, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
+ {3056, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
+ {3057, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
+ {3058, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
+ {3059, {wxStyledTextCtrl, registerImage, 2}},
+ {3060, {wxStyledTextCtrl, clearRegisteredImages, 0}},
+ {3061, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
+ {3062, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
+ {3063, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
+ {3064, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
+ {3065, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
+ {3066, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
+ {3067, {wxStyledTextCtrl, setIndent, 1}},
+ {3068, {wxStyledTextCtrl, getIndent, 0}},
+ {3069, {wxStyledTextCtrl, setUseTabs, 1}},
+ {3070, {wxStyledTextCtrl, getUseTabs, 0}},
+ {3071, {wxStyledTextCtrl, setLineIndentation, 2}},
+ {3072, {wxStyledTextCtrl, getLineIndentation, 1}},
+ {3073, {wxStyledTextCtrl, getLineIndentPosition, 1}},
+ {3074, {wxStyledTextCtrl, getColumn, 1}},
+ {3075, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
+ {3076, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
+ {3077, {wxStyledTextCtrl, setIndentationGuides, 1}},
+ {3078, {wxStyledTextCtrl, getIndentationGuides, 0}},
+ {3079, {wxStyledTextCtrl, setHighlightGuide, 1}},
+ {3080, {wxStyledTextCtrl, getHighlightGuide, 0}},
+ {3081, {wxStyledTextCtrl, getLineEndPosition, 1}},
+ {3082, {wxStyledTextCtrl, getCodePage, 0}},
+ {3083, {wxStyledTextCtrl, getCaretForeground, 0}},
+ {3084, {wxStyledTextCtrl, getReadOnly, 0}},
+ {3085, {wxStyledTextCtrl, setCurrentPos, 1}},
+ {3086, {wxStyledTextCtrl, setSelectionStart, 1}},
+ {3087, {wxStyledTextCtrl, getSelectionStart, 0}},
+ {3088, {wxStyledTextCtrl, setSelectionEnd, 1}},
+ {3089, {wxStyledTextCtrl, getSelectionEnd, 0}},
+ {3090, {wxStyledTextCtrl, setPrintMagnification, 1}},
+ {3091, {wxStyledTextCtrl, getPrintMagnification, 0}},
+ {3092, {wxStyledTextCtrl, setPrintColourMode, 1}},
+ {3093, {wxStyledTextCtrl, getPrintColourMode, 0}},
+ {3094, {wxStyledTextCtrl, findText, 4}},
+ {3095, {wxStyledTextCtrl, formatRange, 7}},
+ {3096, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
+ {3097, {wxStyledTextCtrl, getLine, 1}},
+ {3098, {wxStyledTextCtrl, getLineCount, 0}},
+ {3099, {wxStyledTextCtrl, setMarginLeft, 1}},
+ {3100, {wxStyledTextCtrl, getMarginLeft, 0}},
+ {3101, {wxStyledTextCtrl, setMarginRight, 1}},
+ {3102, {wxStyledTextCtrl, getMarginRight, 0}},
+ {3103, {wxStyledTextCtrl, getModify, 0}},
+ {3104, {wxStyledTextCtrl, setSelection, 2}},
+ {3105, {wxStyledTextCtrl, getSelectedText, 0}},
+ {3106, {wxStyledTextCtrl, getTextRange, 2}},
+ {3107, {wxStyledTextCtrl, hideSelection, 1}},
+ {3108, {wxStyledTextCtrl, lineFromPosition, 1}},
+ {3109, {wxStyledTextCtrl, positionFromLine, 1}},
+ {3110, {wxStyledTextCtrl, lineScroll, 2}},
+ {3111, {wxStyledTextCtrl, ensureCaretVisible, 0}},
+ {3112, {wxStyledTextCtrl, replaceSelection, 1}},
+ {3113, {wxStyledTextCtrl, setReadOnly, 1}},
+ {3114, {wxStyledTextCtrl, canPaste, 0}},
+ {3115, {wxStyledTextCtrl, canUndo, 0}},
+ {3116, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
+ {3117, {wxStyledTextCtrl, undo, 0}},
+ {3118, {wxStyledTextCtrl, cut, 0}},
+ {3119, {wxStyledTextCtrl, copy, 0}},
+ {3120, {wxStyledTextCtrl, paste, 0}},
+ {3121, {wxStyledTextCtrl, clear, 0}},
+ {3122, {wxStyledTextCtrl, setText, 1}},
+ {3123, {wxStyledTextCtrl, getText, 0}},
+ {3124, {wxStyledTextCtrl, getTextLength, 0}},
+ {3125, {wxStyledTextCtrl, getOvertype, 0}},
+ {3126, {wxStyledTextCtrl, setCaretWidth, 1}},
+ {3127, {wxStyledTextCtrl, getCaretWidth, 0}},
+ {3128, {wxStyledTextCtrl, setTargetStart, 1}},
+ {3129, {wxStyledTextCtrl, getTargetStart, 0}},
+ {3130, {wxStyledTextCtrl, setTargetEnd, 1}},
+ {3131, {wxStyledTextCtrl, getTargetEnd, 0}},
+ {3132, {wxStyledTextCtrl, replaceTarget, 1}},
+ {3133, {wxStyledTextCtrl, searchInTarget, 1}},
+ {3134, {wxStyledTextCtrl, setSearchFlags, 1}},
+ {3135, {wxStyledTextCtrl, getSearchFlags, 0}},
+ {3136, {wxStyledTextCtrl, callTipShow, 2}},
+ {3137, {wxStyledTextCtrl, callTipCancel, 0}},
+ {3138, {wxStyledTextCtrl, callTipActive, 0}},
+ {3139, {wxStyledTextCtrl, callTipPosAtStart, 0}},
+ {3140, {wxStyledTextCtrl, callTipSetHighlight, 2}},
+ {3141, {wxStyledTextCtrl, callTipSetBackground, 1}},
+ {3142, {wxStyledTextCtrl, callTipSetForeground, 1}},
+ {3143, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
+ {3144, {wxStyledTextCtrl, callTipUseStyle, 1}},
+ {3145, {wxStyledTextCtrl, visibleFromDocLine, 1}},
+ {3146, {wxStyledTextCtrl, docLineFromVisible, 1}},
+ {3147, {wxStyledTextCtrl, wrapCount, 1}},
+ {3148, {wxStyledTextCtrl, setFoldLevel, 2}},
+ {3149, {wxStyledTextCtrl, getFoldLevel, 1}},
+ {3150, {wxStyledTextCtrl, getLastChild, 2}},
+ {3151, {wxStyledTextCtrl, getFoldParent, 1}},
+ {3152, {wxStyledTextCtrl, showLines, 2}},
+ {3153, {wxStyledTextCtrl, hideLines, 2}},
+ {3154, {wxStyledTextCtrl, getLineVisible, 1}},
+ {3155, {wxStyledTextCtrl, setFoldExpanded, 2}},
+ {3156, {wxStyledTextCtrl, getFoldExpanded, 1}},
+ {3157, {wxStyledTextCtrl, toggleFold, 1}},
+ {3158, {wxStyledTextCtrl, ensureVisible, 1}},
+ {3159, {wxStyledTextCtrl, setFoldFlags, 1}},
+ {3160, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
+ {3161, {wxStyledTextCtrl, setTabIndents, 1}},
+ {3162, {wxStyledTextCtrl, getTabIndents, 0}},
+ {3163, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
+ {3164, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
+ {3165, {wxStyledTextCtrl, setMouseDwellTime, 1}},
+ {3166, {wxStyledTextCtrl, getMouseDwellTime, 0}},
+ {3167, {wxStyledTextCtrl, wordStartPosition, 2}},
+ {3168, {wxStyledTextCtrl, wordEndPosition, 2}},
+ {3169, {wxStyledTextCtrl, setWrapMode, 1}},
+ {3170, {wxStyledTextCtrl, getWrapMode, 0}},
+ {3171, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
+ {3172, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
+ {3173, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
+ {3174, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
+ {3175, {wxStyledTextCtrl, setWrapStartIndent, 1}},
+ {3176, {wxStyledTextCtrl, getWrapStartIndent, 0}},
+ {3177, {wxStyledTextCtrl, setLayoutCache, 1}},
+ {3178, {wxStyledTextCtrl, getLayoutCache, 0}},
+ {3179, {wxStyledTextCtrl, setScrollWidth, 1}},
+ {3180, {wxStyledTextCtrl, getScrollWidth, 0}},
+ {3181, {wxStyledTextCtrl, textWidth, 2}},
+ {3182, {wxStyledTextCtrl, getEndAtLastLine, 0}},
+ {3183, {wxStyledTextCtrl, textHeight, 1}},
+ {3184, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
+ {3185, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
+ {3186, {wxStyledTextCtrl, appendText, 1}},
+ {3187, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
+ {3188, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
+ {3189, {wxStyledTextCtrl, targetFromSelection, 0}},
+ {3190, {wxStyledTextCtrl, linesJoin, 0}},
+ {3191, {wxStyledTextCtrl, linesSplit, 1}},
+ {3192, {wxStyledTextCtrl, setFoldMarginColour, 2}},
+ {3193, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
+ {3194, {wxStyledTextCtrl, lineDown, 0}},
+ {3195, {wxStyledTextCtrl, lineDownExtend, 0}},
+ {3196, {wxStyledTextCtrl, lineUp, 0}},
+ {3197, {wxStyledTextCtrl, lineUpExtend, 0}},
+ {3198, {wxStyledTextCtrl, charLeft, 0}},
+ {3199, {wxStyledTextCtrl, charLeftExtend, 0}},
+ {3200, {wxStyledTextCtrl, charRight, 0}},
+ {3201, {wxStyledTextCtrl, charRightExtend, 0}},
+ {3202, {wxStyledTextCtrl, wordLeft, 0}},
+ {3203, {wxStyledTextCtrl, wordLeftExtend, 0}},
+ {3204, {wxStyledTextCtrl, wordRight, 0}},
+ {3205, {wxStyledTextCtrl, wordRightExtend, 0}},
+ {3206, {wxStyledTextCtrl, home, 0}},
+ {3207, {wxStyledTextCtrl, homeExtend, 0}},
+ {3208, {wxStyledTextCtrl, lineEnd, 0}},
+ {3209, {wxStyledTextCtrl, lineEndExtend, 0}},
+ {3210, {wxStyledTextCtrl, documentStart, 0}},
+ {3211, {wxStyledTextCtrl, documentStartExtend, 0}},
+ {3212, {wxStyledTextCtrl, documentEnd, 0}},
+ {3213, {wxStyledTextCtrl, documentEndExtend, 0}},
+ {3214, {wxStyledTextCtrl, pageUp, 0}},
+ {3215, {wxStyledTextCtrl, pageUpExtend, 0}},
+ {3216, {wxStyledTextCtrl, pageDown, 0}},
+ {3217, {wxStyledTextCtrl, pageDownExtend, 0}},
+ {3218, {wxStyledTextCtrl, editToggleOvertype, 0}},
+ {3219, {wxStyledTextCtrl, cancel, 0}},
+ {3220, {wxStyledTextCtrl, deleteBack, 0}},
+ {3221, {wxStyledTextCtrl, tab, 0}},
+ {3222, {wxStyledTextCtrl, backTab, 0}},
+ {3223, {wxStyledTextCtrl, newLine, 0}},
+ {3224, {wxStyledTextCtrl, formFeed, 0}},
+ {3225, {wxStyledTextCtrl, vCHome, 0}},
+ {3226, {wxStyledTextCtrl, vCHomeExtend, 0}},
+ {3227, {wxStyledTextCtrl, zoomIn, 0}},
+ {3228, {wxStyledTextCtrl, zoomOut, 0}},
+ {3229, {wxStyledTextCtrl, delWordLeft, 0}},
+ {3230, {wxStyledTextCtrl, delWordRight, 0}},
+ {3231, {wxStyledTextCtrl, lineCut, 0}},
+ {3232, {wxStyledTextCtrl, lineDelete, 0}},
+ {3233, {wxStyledTextCtrl, lineTranspose, 0}},
+ {3234, {wxStyledTextCtrl, lineDuplicate, 0}},
+ {3235, {wxStyledTextCtrl, lowerCase, 0}},
+ {3236, {wxStyledTextCtrl, upperCase, 0}},
+ {3237, {wxStyledTextCtrl, lineScrollDown, 0}},
+ {3238, {wxStyledTextCtrl, lineScrollUp, 0}},
+ {3239, {wxStyledTextCtrl, deleteBackNotLine, 0}},
+ {3240, {wxStyledTextCtrl, homeDisplay, 0}},
+ {3241, {wxStyledTextCtrl, homeDisplayExtend, 0}},
+ {3242, {wxStyledTextCtrl, lineEndDisplay, 0}},
+ {3243, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
+ {3244, {wxStyledTextCtrl, homeWrapExtend, 0}},
+ {3245, {wxStyledTextCtrl, lineEndWrap, 0}},
+ {3246, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
+ {3247, {wxStyledTextCtrl, vCHomeWrap, 0}},
+ {3248, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
+ {3249, {wxStyledTextCtrl, lineCopy, 0}},
+ {3250, {wxStyledTextCtrl, moveCaretInsideView, 0}},
+ {3251, {wxStyledTextCtrl, lineLength, 1}},
+ {3252, {wxStyledTextCtrl, braceHighlight, 2}},
+ {3253, {wxStyledTextCtrl, braceBadLight, 1}},
+ {3254, {wxStyledTextCtrl, braceMatch, 1}},
+ {3255, {wxStyledTextCtrl, getViewEOL, 0}},
+ {3256, {wxStyledTextCtrl, setViewEOL, 1}},
+ {3257, {wxStyledTextCtrl, setModEventMask, 1}},
+ {3258, {wxStyledTextCtrl, getEdgeColumn, 0}},
+ {3259, {wxStyledTextCtrl, setEdgeColumn, 1}},
+ {3260, {wxStyledTextCtrl, getEdgeMode, 0}},
+ {3261, {wxStyledTextCtrl, getEdgeColour, 0}},
+ {3262, {wxStyledTextCtrl, setEdgeColour, 1}},
+ {3263, {wxStyledTextCtrl, searchAnchor, 0}},
+ {3264, {wxStyledTextCtrl, searchNext, 2}},
+ {3265, {wxStyledTextCtrl, searchPrev, 2}},
+ {3266, {wxStyledTextCtrl, linesOnScreen, 0}},
+ {3267, {wxStyledTextCtrl, usePopUp, 1}},
+ {3268, {wxStyledTextCtrl, selectionIsRectangle, 0}},
+ {3269, {wxStyledTextCtrl, setZoom, 1}},
+ {3270, {wxStyledTextCtrl, getZoom, 0}},
+ {3271, {wxStyledTextCtrl, getModEventMask, 0}},
+ {3272, {wxStyledTextCtrl, setSTCFocus, 1}},
+ {3273, {wxStyledTextCtrl, getSTCFocus, 0}},
+ {3274, {wxStyledTextCtrl, setStatus, 1}},
+ {3275, {wxStyledTextCtrl, getStatus, 0}},
+ {3276, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
+ {3277, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
+ {3278, {wxStyledTextCtrl, setSTCCursor, 1}},
+ {3279, {wxStyledTextCtrl, getSTCCursor, 0}},
+ {3280, {wxStyledTextCtrl, setControlCharSymbol, 1}},
+ {3281, {wxStyledTextCtrl, getControlCharSymbol, 0}},
+ {3282, {wxStyledTextCtrl, wordPartLeft, 0}},
+ {3283, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
+ {3284, {wxStyledTextCtrl, wordPartRight, 0}},
+ {3285, {wxStyledTextCtrl, wordPartRightExtend, 0}},
+ {3286, {wxStyledTextCtrl, setVisiblePolicy, 2}},
+ {3287, {wxStyledTextCtrl, delLineLeft, 0}},
+ {3288, {wxStyledTextCtrl, delLineRight, 0}},
+ {3289, {wxStyledTextCtrl, getXOffset, 0}},
+ {3290, {wxStyledTextCtrl, chooseCaretX, 0}},
+ {3291, {wxStyledTextCtrl, setXCaretPolicy, 2}},
+ {3292, {wxStyledTextCtrl, setYCaretPolicy, 2}},
+ {3293, {wxStyledTextCtrl, getPrintWrapMode, 0}},
+ {3294, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
+ {3295, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
+ {3296, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
+ {3297, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
+ {3298, {wxStyledTextCtrl, paraDownExtend, 0}},
+ {3299, {wxStyledTextCtrl, paraUp, 0}},
+ {3300, {wxStyledTextCtrl, paraUpExtend, 0}},
+ {3301, {wxStyledTextCtrl, positionBefore, 1}},
+ {3302, {wxStyledTextCtrl, positionAfter, 1}},
+ {3303, {wxStyledTextCtrl, copyRange, 2}},
+ {3304, {wxStyledTextCtrl, copyText, 2}},
+ {3305, {wxStyledTextCtrl, setSelectionMode, 1}},
+ {3306, {wxStyledTextCtrl, getSelectionMode, 0}},
+ {3307, {wxStyledTextCtrl, lineDownRectExtend, 0}},
+ {3308, {wxStyledTextCtrl, lineUpRectExtend, 0}},
+ {3309, {wxStyledTextCtrl, charLeftRectExtend, 0}},
+ {3310, {wxStyledTextCtrl, charRightRectExtend, 0}},
+ {3311, {wxStyledTextCtrl, homeRectExtend, 0}},
+ {3312, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
+ {3313, {wxStyledTextCtrl, lineEndRectExtend, 0}},
+ {3314, {wxStyledTextCtrl, pageUpRectExtend, 0}},
+ {3315, {wxStyledTextCtrl, pageDownRectExtend, 0}},
+ {3316, {wxStyledTextCtrl, stutteredPageUp, 0}},
+ {3317, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
+ {3318, {wxStyledTextCtrl, stutteredPageDown, 0}},
+ {3319, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
+ {3320, {wxStyledTextCtrl, wordLeftEnd, 0}},
+ {3321, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
+ {3322, {wxStyledTextCtrl, wordRightEnd, 0}},
+ {3323, {wxStyledTextCtrl, wordRightEndExtend, 0}},
+ {3324, {wxStyledTextCtrl, setWhitespaceChars, 1}},
+ {3325, {wxStyledTextCtrl, setCharsDefault, 0}},
+ {3326, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
+ {3327, {wxStyledTextCtrl, allocate, 1}},
+ {3328, {wxStyledTextCtrl, findColumn, 2}},
+ {3329, {wxStyledTextCtrl, getCaretSticky, 0}},
+ {3330, {wxStyledTextCtrl, setCaretSticky, 1}},
+ {3331, {wxStyledTextCtrl, toggleCaretSticky, 0}},
+ {3332, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
+ {3333, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
+ {3334, {wxStyledTextCtrl, selectionDuplicate, 0}},
+ {3335, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
+ {3336, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
+ {3337, {wxStyledTextCtrl, startRecord, 0}},
+ {3338, {wxStyledTextCtrl, stopRecord, 0}},
+ {3339, {wxStyledTextCtrl, setLexer, 1}},
+ {3340, {wxStyledTextCtrl, getLexer, 0}},
+ {3341, {wxStyledTextCtrl, colourise, 2}},
+ {3342, {wxStyledTextCtrl, setProperty, 2}},
+ {3343, {wxStyledTextCtrl, setKeyWords, 2}},
+ {3344, {wxStyledTextCtrl, setLexerLanguage, 1}},
+ {3345, {wxStyledTextCtrl, getProperty, 1}},
+ {3346, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
+ {3347, {wxStyledTextCtrl, getCurrentLine, 0}},
+ {3348, {wxStyledTextCtrl, styleSetSpec, 2}},
+ {3349, {wxStyledTextCtrl, styleSetFont, 2}},
+ {3350, {wxStyledTextCtrl, styleSetFontAttr, 7}},
+ {3351, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
+ {3352, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
+ {3353, {wxStyledTextCtrl, cmdKeyExecute, 1}},
+ {3354, {wxStyledTextCtrl, setMargins, 2}},
+ {3355, {wxStyledTextCtrl, getSelection, 2}},
+ {3356, {wxStyledTextCtrl, pointFromPosition, 1}},
+ {3357, {wxStyledTextCtrl, scrollToLine, 1}},
+ {3358, {wxStyledTextCtrl, scrollToColumn, 1}},
+ {3359, {wxStyledTextCtrl, sendMsg, 2}},
+ {3360, {wxStyledTextCtrl, setVScrollBar, 1}},
+ {3361, {wxStyledTextCtrl, setHScrollBar, 1}},
+ {3362, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
+ {3363, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
+ {3364, {wxStyledTextCtrl, saveFile, 1}},
+ {3365, {wxStyledTextCtrl, loadFile, 1}},
+ {3366, {wxStyledTextCtrl, doDragOver, 3}},
+ {3367, {wxStyledTextCtrl, doDropText, 3}},
+ {3368, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
+ {3369, {wxStyledTextCtrl, addTextRaw, 1}},
+ {3370, {wxStyledTextCtrl, insertTextRaw, 2}},
+ {3371, {wxStyledTextCtrl, getCurLineRaw, 1}},
+ {3372, {wxStyledTextCtrl, getLineRaw, 1}},
+ {3373, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
+ {3374, {wxStyledTextCtrl, getTextRangeRaw, 2}},
+ {3375, {wxStyledTextCtrl, setTextRaw, 1}},
+ {3376, {wxStyledTextCtrl, getTextRaw, 0}},
+ {3377, {wxStyledTextCtrl, appendTextRaw, 1}},
+ {3378, {wxArtProvider, getBitmap, 2}},
+ {3379, {wxArtProvider, getIcon, 2}},
+ {3380, {wxTreeEvent, getKeyCode, 0}},
+ {3381, {wxTreeEvent, getItem, 0}},
+ {3382, {wxTreeEvent, getKeyEvent, 0}},
+ {3383, {wxTreeEvent, getLabel, 0}},
+ {3384, {wxTreeEvent, getOldItem, 0}},
+ {3385, {wxTreeEvent, getPoint, 0}},
+ {3386, {wxTreeEvent, isEditCancelled, 0}},
+ {3387, {wxTreeEvent, setToolTip, 1}},
+ {3388, {wxNotebookEvent, getOldSelection, 0}},
+ {3389, {wxNotebookEvent, getSelection, 0}},
+ {3390, {wxNotebookEvent, setOldSelection, 1}},
+ {3391, {wxNotebookEvent, setSelection, 1}},
+ {3392, {wxFileDataObject, new, 0}},
+ {3393, {wxFileDataObject, addFile, 1}},
+ {3394, {wxFileDataObject, getFilenames, 0}},
+ {3395, {wxFileDataObject, 'Destroy', undefined}},
+ {3396, {wxTextDataObject, new, 1}},
+ {3397, {wxTextDataObject, getTextLength, 0}},
+ {3398, {wxTextDataObject, getText, 0}},
+ {3399, {wxTextDataObject, setText, 1}},
+ {3400, {wxTextDataObject, 'Destroy', undefined}},
+ {3401, {wxBitmapDataObject, new_1_1, 1}},
+ {3402, {wxBitmapDataObject, new_1_0, 1}},
+ {3403, {wxBitmapDataObject, getBitmap, 0}},
+ {3404, {wxBitmapDataObject, setBitmap, 1}},
+ {3405, {wxBitmapDataObject, 'Destroy', undefined}},
+ {3407, {wxClipboard, new, 0}},
+ {3408, {wxClipboard, destruct, 0}},
+ {3409, {wxClipboard, addData, 1}},
+ {3410, {wxClipboard, clear, 0}},
+ {3411, {wxClipboard, close, 0}},
+ {3412, {wxClipboard, flush, 0}},
+ {3413, {wxClipboard, getData, 1}},
+ {3414, {wxClipboard, isOpened, 0}},
+ {3415, {wxClipboard, open, 0}},
+ {3416, {wxClipboard, setData, 1}},
+ {3418, {wxClipboard, usePrimarySelection, 1}},
+ {3419, {wxClipboard, isSupported, 1}},
+ {3420, {wxClipboard, get, 0}},
+ {3421, {wxSpinEvent, getPosition, 0}},
+ {3422, {wxSpinEvent, setPosition, 1}},
+ {3423, {wxSplitterWindow, new_0, 0}},
+ {3424, {wxSplitterWindow, new_2, 2}},
+ {3425, {wxSplitterWindow, destruct, 0}},
+ {3426, {wxSplitterWindow, create, 2}},
+ {3427, {wxSplitterWindow, getMinimumPaneSize, 0}},
+ {3428, {wxSplitterWindow, getSashGravity, 0}},
+ {3429, {wxSplitterWindow, getSashPosition, 0}},
+ {3430, {wxSplitterWindow, getSplitMode, 0}},
+ {3431, {wxSplitterWindow, getWindow1, 0}},
+ {3432, {wxSplitterWindow, getWindow2, 0}},
+ {3433, {wxSplitterWindow, initialize, 1}},
+ {3434, {wxSplitterWindow, isSplit, 0}},
+ {3435, {wxSplitterWindow, replaceWindow, 2}},
+ {3436, {wxSplitterWindow, setSashGravity, 1}},
+ {3437, {wxSplitterWindow, setSashPosition, 2}},
+ {3438, {wxSplitterWindow, setSashSize, 1}},
+ {3439, {wxSplitterWindow, setMinimumPaneSize, 1}},
+ {3440, {wxSplitterWindow, setSplitMode, 1}},
+ {3441, {wxSplitterWindow, splitHorizontally, 3}},
+ {3442, {wxSplitterWindow, splitVertically, 3}},
+ {3443, {wxSplitterWindow, unsplit, 1}},
+ {3444, {wxSplitterWindow, updateSize, 0}},
+ {3445, {wxSplitterEvent, getSashPosition, 0}},
+ {3446, {wxSplitterEvent, getX, 0}},
+ {3447, {wxSplitterEvent, getY, 0}},
+ {3448, {wxSplitterEvent, getWindowBeingRemoved, 0}},
+ {3449, {wxSplitterEvent, setSashPosition, 1}},
+ {3450, {wxHtmlWindow, new_0, 0}},
+ {3451, {wxHtmlWindow, new_2, 2}},
+ {3452, {wxHtmlWindow, appendToPage, 1}},
+ {3453, {wxHtmlWindow, getOpenedAnchor, 0}},
+ {3454, {wxHtmlWindow, getOpenedPage, 0}},
+ {3455, {wxHtmlWindow, getOpenedPageTitle, 0}},
+ {3456, {wxHtmlWindow, getRelatedFrame, 0}},
+ {3457, {wxHtmlWindow, historyBack, 0}},
+ {3458, {wxHtmlWindow, historyCanBack, 0}},
+ {3459, {wxHtmlWindow, historyCanForward, 0}},
+ {3460, {wxHtmlWindow, historyClear, 0}},
+ {3461, {wxHtmlWindow, historyForward, 0}},
+ {3462, {wxHtmlWindow, loadFile, 1}},
+ {3463, {wxHtmlWindow, loadPage, 1}},
+ {3464, {wxHtmlWindow, selectAll, 0}},
+ {3465, {wxHtmlWindow, selectionToText, 0}},
+ {3466, {wxHtmlWindow, selectLine, 1}},
+ {3467, {wxHtmlWindow, selectWord, 1}},
+ {3468, {wxHtmlWindow, setBorders, 1}},
+ {3469, {wxHtmlWindow, setFonts, 3}},
+ {3470, {wxHtmlWindow, setPage, 1}},
+ {3471, {wxHtmlWindow, setRelatedFrame, 2}},
+ {3472, {wxHtmlWindow, setRelatedStatusBar, 1}},
+ {3473, {wxHtmlWindow, toText, 0}},
+ {3474, {wxHtmlWindow, 'Destroy', undefined}},
+ {3475, {wxHtmlLinkEvent, getLinkInfo, 0}},
+ {3476, {wxAuiNotebookEvent, setSelection, 1}},
+ {3477, {wxAuiNotebookEvent, getSelection, 0}},
+ {3478, {wxAuiNotebookEvent, setOldSelection, 1}},
+ {3479, {wxAuiNotebookEvent, getOldSelection, 0}},
+ {3480, {wxAuiNotebookEvent, setDragSource, 1}},
+ {3481, {wxAuiNotebookEvent, getDragSource, 0}},
+ {3482, {wxAuiManagerEvent, setManager, 1}},
+ {3483, {wxAuiManagerEvent, getManager, 0}},
+ {3484, {wxAuiManagerEvent, setPane, 1}},
+ {3485, {wxAuiManagerEvent, getPane, 0}},
+ {3486, {wxAuiManagerEvent, setButton, 1}},
+ {3487, {wxAuiManagerEvent, getButton, 0}},
+ {3488, {wxAuiManagerEvent, setDC, 1}},
+ {3489, {wxAuiManagerEvent, getDC, 0}},
+ {3490, {wxAuiManagerEvent, veto, 1}},
+ {3491, {wxAuiManagerEvent, getVeto, 0}},
+ {3492, {wxAuiManagerEvent, setCanVeto, 1}},
+ {3493, {wxAuiManagerEvent, canVeto, 0}},
+ {3494, {wxLogNull, new, 0}},
+ {3495, {wxLogNull, 'Destroy', undefined}},
{-1, {mod, func, -1}}
].
diff --git a/lib/wx/src/gen/wxe_funcs.hrl b/lib/wx/src/gen/wxe_funcs.hrl
index eef90961db..98e7fbb767 100644
--- a/lib/wx/src/gen/wxe_funcs.hrl
+++ b/lib/wx/src/gen/wxe_funcs.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%% This file is generated DO NOT EDIT
@@ -1839,1435 +1839,1436 @@
-define(wxTreeCtrl_GetChildrenCount, 2015).
-define(wxTreeCtrl_GetCount, 2016).
-define(wxTreeCtrl_GetEditControl, 2017).
--define(wxTreeCtrl_GetFirstVisibleItem, 2018).
--define(wxTreeCtrl_GetImageList, 2019).
--define(wxTreeCtrl_GetIndent, 2020).
--define(wxTreeCtrl_GetItemBackgroundColour, 2021).
--define(wxTreeCtrl_GetItemData, 2022).
--define(wxTreeCtrl_GetItemFont, 2023).
--define(wxTreeCtrl_GetItemImage_1, 2024).
--define(wxTreeCtrl_GetItemImage_2, 2025).
--define(wxTreeCtrl_GetItemText, 2026).
--define(wxTreeCtrl_GetItemTextColour, 2027).
--define(wxTreeCtrl_GetLastChild, 2028).
--define(wxTreeCtrl_GetNextSibling, 2029).
--define(wxTreeCtrl_GetNextVisible, 2030).
--define(wxTreeCtrl_GetItemParent, 2031).
--define(wxTreeCtrl_GetPrevSibling, 2032).
--define(wxTreeCtrl_GetPrevVisible, 2033).
--define(wxTreeCtrl_GetRootItem, 2034).
--define(wxTreeCtrl_GetSelection, 2035).
--define(wxTreeCtrl_GetSelections, 2036).
--define(wxTreeCtrl_GetStateImageList, 2037).
--define(wxTreeCtrl_HitTest, 2038).
--define(wxTreeCtrl_InsertItem_4_1, 2039).
--define(wxTreeCtrl_InsertItem_4_0, 2040).
--define(wxTreeCtrl_IsBold, 2041).
--define(wxTreeCtrl_IsExpanded, 2042).
--define(wxTreeCtrl_IsSelected, 2043).
--define(wxTreeCtrl_IsVisible, 2044).
--define(wxTreeCtrl_ItemHasChildren, 2045).
--define(wxTreeCtrl_PrependItem, 2046).
--define(wxTreeCtrl_ScrollTo, 2047).
--define(wxTreeCtrl_SelectItem_1, 2048).
--define(wxTreeCtrl_SelectItem_2, 2049).
--define(wxTreeCtrl_SetIndent, 2050).
--define(wxTreeCtrl_SetImageList, 2051).
--define(wxTreeCtrl_SetItemBackgroundColour, 2052).
--define(wxTreeCtrl_SetItemBold, 2053).
--define(wxTreeCtrl_SetItemData, 2054).
--define(wxTreeCtrl_SetItemDropHighlight, 2055).
--define(wxTreeCtrl_SetItemFont, 2056).
--define(wxTreeCtrl_SetItemHasChildren, 2057).
--define(wxTreeCtrl_SetItemImage_2, 2058).
--define(wxTreeCtrl_SetItemImage_3, 2059).
--define(wxTreeCtrl_SetItemText, 2060).
--define(wxTreeCtrl_SetItemTextColour, 2061).
--define(wxTreeCtrl_SetStateImageList, 2062).
--define(wxTreeCtrl_SetWindowStyle, 2063).
--define(wxTreeCtrl_SortChildren, 2064).
--define(wxTreeCtrl_Toggle, 2065).
--define(wxTreeCtrl_ToggleItemSelection, 2066).
--define(wxTreeCtrl_Unselect, 2067).
--define(wxTreeCtrl_UnselectAll, 2068).
--define(wxTreeCtrl_UnselectItem, 2069).
--define(wxScrollBar_new_0, 2070).
--define(wxScrollBar_new_3, 2071).
--define(wxScrollBar_destruct, 2072).
--define(wxScrollBar_Create, 2073).
--define(wxScrollBar_GetRange, 2074).
--define(wxScrollBar_GetPageSize, 2075).
--define(wxScrollBar_GetThumbPosition, 2076).
--define(wxScrollBar_GetThumbSize, 2077).
--define(wxScrollBar_SetThumbPosition, 2078).
--define(wxScrollBar_SetScrollbar, 2079).
--define(wxSpinButton_new_2, 2081).
--define(wxSpinButton_new_0, 2082).
--define(wxSpinButton_Create, 2083).
--define(wxSpinButton_GetMax, 2084).
--define(wxSpinButton_GetMin, 2085).
--define(wxSpinButton_GetValue, 2086).
--define(wxSpinButton_SetRange, 2087).
--define(wxSpinButton_SetValue, 2088).
--define(wxSpinButton_destroy, 2089).
--define(wxSpinCtrl_new_0, 2090).
--define(wxSpinCtrl_new_2, 2091).
--define(wxSpinCtrl_Create, 2093).
--define(wxSpinCtrl_SetValue_1_1, 2096).
--define(wxSpinCtrl_SetValue_1_0, 2097).
--define(wxSpinCtrl_GetValue, 2099).
--define(wxSpinCtrl_SetRange, 2101).
--define(wxSpinCtrl_SetSelection, 2102).
--define(wxSpinCtrl_GetMin, 2104).
--define(wxSpinCtrl_GetMax, 2106).
--define(wxSpinCtrl_destroy, 2107).
--define(wxStaticText_new_0, 2108).
--define(wxStaticText_new_4, 2109).
--define(wxStaticText_Create, 2110).
--define(wxStaticText_GetLabel, 2111).
--define(wxStaticText_SetLabel, 2112).
--define(wxStaticText_Wrap, 2113).
--define(wxStaticText_destroy, 2114).
--define(wxStaticBitmap_new_0, 2115).
--define(wxStaticBitmap_new_4, 2116).
--define(wxStaticBitmap_Create, 2117).
--define(wxStaticBitmap_GetBitmap, 2118).
--define(wxStaticBitmap_SetBitmap, 2119).
--define(wxStaticBitmap_destroy, 2120).
--define(wxRadioBox_new, 2121).
--define(wxRadioBox_destruct, 2123).
--define(wxRadioBox_Create, 2124).
--define(wxRadioBox_Enable_2, 2125).
--define(wxRadioBox_Enable_1, 2126).
--define(wxRadioBox_GetSelection, 2127).
--define(wxRadioBox_GetString, 2128).
--define(wxRadioBox_SetSelection, 2129).
--define(wxRadioBox_Show_2, 2130).
--define(wxRadioBox_Show_1, 2131).
--define(wxRadioBox_GetColumnCount, 2132).
--define(wxRadioBox_GetItemHelpText, 2133).
--define(wxRadioBox_GetItemToolTip, 2134).
--define(wxRadioBox_GetItemFromPoint, 2136).
--define(wxRadioBox_GetRowCount, 2137).
--define(wxRadioBox_IsItemEnabled, 2138).
--define(wxRadioBox_IsItemShown, 2139).
--define(wxRadioBox_SetItemHelpText, 2140).
--define(wxRadioBox_SetItemToolTip, 2141).
--define(wxRadioButton_new_0, 2142).
--define(wxRadioButton_new_4, 2143).
--define(wxRadioButton_Create, 2144).
--define(wxRadioButton_GetValue, 2145).
--define(wxRadioButton_SetValue, 2146).
--define(wxRadioButton_destroy, 2147).
--define(wxSlider_new_6, 2149).
--define(wxSlider_new_0, 2150).
--define(wxSlider_Create, 2151).
--define(wxSlider_GetLineSize, 2152).
--define(wxSlider_GetMax, 2153).
--define(wxSlider_GetMin, 2154).
--define(wxSlider_GetPageSize, 2155).
--define(wxSlider_GetThumbLength, 2156).
--define(wxSlider_GetValue, 2157).
--define(wxSlider_SetLineSize, 2158).
--define(wxSlider_SetPageSize, 2159).
--define(wxSlider_SetRange, 2160).
--define(wxSlider_SetThumbLength, 2161).
--define(wxSlider_SetValue, 2162).
--define(wxSlider_destroy, 2163).
--define(wxDialog_new_4, 2165).
--define(wxDialog_new_0, 2166).
--define(wxDialog_destruct, 2168).
--define(wxDialog_Create, 2169).
--define(wxDialog_CreateButtonSizer, 2170).
--define(wxDialog_CreateStdDialogButtonSizer, 2171).
--define(wxDialog_EndModal, 2172).
--define(wxDialog_GetAffirmativeId, 2173).
--define(wxDialog_GetReturnCode, 2174).
--define(wxDialog_IsModal, 2175).
--define(wxDialog_SetAffirmativeId, 2176).
--define(wxDialog_SetReturnCode, 2177).
--define(wxDialog_Show, 2178).
--define(wxDialog_ShowModal, 2179).
--define(wxColourDialog_new_0, 2180).
--define(wxColourDialog_new_2, 2181).
--define(wxColourDialog_destruct, 2182).
--define(wxColourDialog_Create, 2183).
--define(wxColourDialog_GetColourData, 2184).
--define(wxColourData_new_0, 2185).
--define(wxColourData_new_1, 2186).
--define(wxColourData_destruct, 2187).
--define(wxColourData_GetChooseFull, 2188).
--define(wxColourData_GetColour, 2189).
--define(wxColourData_GetCustomColour, 2191).
--define(wxColourData_SetChooseFull, 2192).
--define(wxColourData_SetColour, 2193).
--define(wxColourData_SetCustomColour, 2194).
--define(wxPalette_new_0, 2195).
--define(wxPalette_new_4, 2196).
--define(wxPalette_destruct, 2198).
--define(wxPalette_Create, 2199).
--define(wxPalette_GetColoursCount, 2200).
--define(wxPalette_GetPixel, 2201).
--define(wxPalette_GetRGB, 2202).
--define(wxPalette_IsOk, 2203).
--define(wxDirDialog_new, 2207).
--define(wxDirDialog_destruct, 2208).
--define(wxDirDialog_GetPath, 2209).
--define(wxDirDialog_GetMessage, 2210).
--define(wxDirDialog_SetMessage, 2211).
--define(wxDirDialog_SetPath, 2212).
--define(wxFileDialog_new, 2216).
--define(wxFileDialog_destruct, 2217).
--define(wxFileDialog_GetDirectory, 2218).
--define(wxFileDialog_GetFilename, 2219).
--define(wxFileDialog_GetFilenames, 2220).
--define(wxFileDialog_GetFilterIndex, 2221).
--define(wxFileDialog_GetMessage, 2222).
--define(wxFileDialog_GetPath, 2223).
--define(wxFileDialog_GetPaths, 2224).
--define(wxFileDialog_GetWildcard, 2225).
--define(wxFileDialog_SetDirectory, 2226).
--define(wxFileDialog_SetFilename, 2227).
--define(wxFileDialog_SetFilterIndex, 2228).
--define(wxFileDialog_SetMessage, 2229).
--define(wxFileDialog_SetPath, 2230).
--define(wxFileDialog_SetWildcard, 2231).
--define(wxPickerBase_SetInternalMargin, 2232).
--define(wxPickerBase_GetInternalMargin, 2233).
--define(wxPickerBase_SetTextCtrlProportion, 2234).
--define(wxPickerBase_SetPickerCtrlProportion, 2235).
--define(wxPickerBase_GetTextCtrlProportion, 2236).
--define(wxPickerBase_GetPickerCtrlProportion, 2237).
--define(wxPickerBase_HasTextCtrl, 2238).
--define(wxPickerBase_GetTextCtrl, 2239).
--define(wxPickerBase_IsTextCtrlGrowable, 2240).
--define(wxPickerBase_SetPickerCtrlGrowable, 2241).
--define(wxPickerBase_SetTextCtrlGrowable, 2242).
--define(wxPickerBase_IsPickerCtrlGrowable, 2243).
--define(wxFilePickerCtrl_new_0, 2244).
--define(wxFilePickerCtrl_new_3, 2245).
--define(wxFilePickerCtrl_Create, 2246).
--define(wxFilePickerCtrl_GetPath, 2247).
--define(wxFilePickerCtrl_SetPath, 2248).
--define(wxFilePickerCtrl_destroy, 2249).
--define(wxDirPickerCtrl_new_0, 2250).
--define(wxDirPickerCtrl_new_3, 2251).
--define(wxDirPickerCtrl_Create, 2252).
--define(wxDirPickerCtrl_GetPath, 2253).
--define(wxDirPickerCtrl_SetPath, 2254).
--define(wxDirPickerCtrl_destroy, 2255).
--define(wxColourPickerCtrl_new_0, 2256).
--define(wxColourPickerCtrl_new_3, 2257).
--define(wxColourPickerCtrl_Create, 2258).
--define(wxColourPickerCtrl_GetColour, 2259).
--define(wxColourPickerCtrl_SetColour_1_1, 2260).
--define(wxColourPickerCtrl_SetColour_1_0, 2261).
--define(wxColourPickerCtrl_destroy, 2262).
--define(wxDatePickerCtrl_new_0, 2263).
--define(wxDatePickerCtrl_new_3, 2264).
--define(wxDatePickerCtrl_GetRange, 2265).
--define(wxDatePickerCtrl_GetValue, 2266).
--define(wxDatePickerCtrl_SetRange, 2267).
--define(wxDatePickerCtrl_SetValue, 2268).
--define(wxDatePickerCtrl_destroy, 2269).
--define(wxFontPickerCtrl_new_0, 2270).
--define(wxFontPickerCtrl_new_3, 2271).
--define(wxFontPickerCtrl_Create, 2272).
--define(wxFontPickerCtrl_GetSelectedFont, 2273).
--define(wxFontPickerCtrl_SetSelectedFont, 2274).
--define(wxFontPickerCtrl_GetMaxPointSize, 2275).
--define(wxFontPickerCtrl_SetMaxPointSize, 2276).
--define(wxFontPickerCtrl_destroy, 2277).
--define(wxFindReplaceDialog_new_0, 2280).
--define(wxFindReplaceDialog_new_4, 2281).
--define(wxFindReplaceDialog_destruct, 2282).
--define(wxFindReplaceDialog_Create, 2283).
--define(wxFindReplaceDialog_GetData, 2284).
--define(wxFindReplaceData_new_0, 2285).
--define(wxFindReplaceData_new_1, 2286).
--define(wxFindReplaceData_GetFindString, 2287).
--define(wxFindReplaceData_GetReplaceString, 2288).
--define(wxFindReplaceData_GetFlags, 2289).
--define(wxFindReplaceData_SetFlags, 2290).
--define(wxFindReplaceData_SetFindString, 2291).
--define(wxFindReplaceData_SetReplaceString, 2292).
--define(wxFindReplaceData_destroy, 2293).
--define(wxMultiChoiceDialog_new_0, 2294).
--define(wxMultiChoiceDialog_new_5, 2296).
--define(wxMultiChoiceDialog_GetSelections, 2297).
--define(wxMultiChoiceDialog_SetSelections, 2298).
--define(wxMultiChoiceDialog_destroy, 2299).
--define(wxSingleChoiceDialog_new_0, 2300).
--define(wxSingleChoiceDialog_new_5, 2302).
--define(wxSingleChoiceDialog_GetSelection, 2303).
--define(wxSingleChoiceDialog_GetStringSelection, 2304).
--define(wxSingleChoiceDialog_SetSelection, 2305).
--define(wxSingleChoiceDialog_destroy, 2306).
--define(wxTextEntryDialog_new, 2307).
--define(wxTextEntryDialog_GetValue, 2308).
--define(wxTextEntryDialog_SetValue, 2309).
--define(wxTextEntryDialog_destroy, 2310).
--define(wxPasswordEntryDialog_new, 2311).
--define(wxPasswordEntryDialog_destroy, 2312).
--define(wxFontData_new_0, 2313).
--define(wxFontData_new_1, 2314).
--define(wxFontData_destruct, 2315).
--define(wxFontData_EnableEffects, 2316).
--define(wxFontData_GetAllowSymbols, 2317).
--define(wxFontData_GetColour, 2318).
--define(wxFontData_GetChosenFont, 2319).
--define(wxFontData_GetEnableEffects, 2320).
--define(wxFontData_GetInitialFont, 2321).
--define(wxFontData_GetShowHelp, 2322).
--define(wxFontData_SetAllowSymbols, 2323).
--define(wxFontData_SetChosenFont, 2324).
--define(wxFontData_SetColour, 2325).
--define(wxFontData_SetInitialFont, 2326).
--define(wxFontData_SetRange, 2327).
--define(wxFontData_SetShowHelp, 2328).
--define(wxFontDialog_new_0, 2332).
--define(wxFontDialog_new_2, 2334).
--define(wxFontDialog_Create, 2336).
--define(wxFontDialog_GetFontData, 2337).
--define(wxFontDialog_destroy, 2339).
--define(wxProgressDialog_new, 2340).
--define(wxProgressDialog_destruct, 2341).
--define(wxProgressDialog_Resume, 2342).
--define(wxProgressDialog_Update_2, 2343).
--define(wxProgressDialog_Update_0, 2344).
--define(wxMessageDialog_new, 2345).
--define(wxMessageDialog_destruct, 2346).
--define(wxPageSetupDialog_new, 2347).
--define(wxPageSetupDialog_destruct, 2348).
--define(wxPageSetupDialog_GetPageSetupData, 2349).
--define(wxPageSetupDialog_ShowModal, 2350).
--define(wxPageSetupDialogData_new_0, 2351).
--define(wxPageSetupDialogData_new_1_0, 2352).
--define(wxPageSetupDialogData_new_1_1, 2353).
--define(wxPageSetupDialogData_destruct, 2354).
--define(wxPageSetupDialogData_EnableHelp, 2355).
--define(wxPageSetupDialogData_EnableMargins, 2356).
--define(wxPageSetupDialogData_EnableOrientation, 2357).
--define(wxPageSetupDialogData_EnablePaper, 2358).
--define(wxPageSetupDialogData_EnablePrinter, 2359).
--define(wxPageSetupDialogData_GetDefaultMinMargins, 2360).
--define(wxPageSetupDialogData_GetEnableMargins, 2361).
--define(wxPageSetupDialogData_GetEnableOrientation, 2362).
--define(wxPageSetupDialogData_GetEnablePaper, 2363).
--define(wxPageSetupDialogData_GetEnablePrinter, 2364).
--define(wxPageSetupDialogData_GetEnableHelp, 2365).
--define(wxPageSetupDialogData_GetDefaultInfo, 2366).
--define(wxPageSetupDialogData_GetMarginTopLeft, 2367).
--define(wxPageSetupDialogData_GetMarginBottomRight, 2368).
--define(wxPageSetupDialogData_GetMinMarginTopLeft, 2369).
--define(wxPageSetupDialogData_GetMinMarginBottomRight, 2370).
--define(wxPageSetupDialogData_GetPaperId, 2371).
--define(wxPageSetupDialogData_GetPaperSize, 2372).
--define(wxPageSetupDialogData_GetPrintData, 2374).
--define(wxPageSetupDialogData_IsOk, 2375).
--define(wxPageSetupDialogData_SetDefaultInfo, 2376).
--define(wxPageSetupDialogData_SetDefaultMinMargins, 2377).
--define(wxPageSetupDialogData_SetMarginTopLeft, 2378).
--define(wxPageSetupDialogData_SetMarginBottomRight, 2379).
--define(wxPageSetupDialogData_SetMinMarginTopLeft, 2380).
--define(wxPageSetupDialogData_SetMinMarginBottomRight, 2381).
--define(wxPageSetupDialogData_SetPaperId, 2382).
--define(wxPageSetupDialogData_SetPaperSize_1_1, 2383).
--define(wxPageSetupDialogData_SetPaperSize_1_0, 2384).
--define(wxPageSetupDialogData_SetPrintData, 2385).
--define(wxPrintDialog_new_2_0, 2386).
--define(wxPrintDialog_new_2_1, 2387).
--define(wxPrintDialog_destruct, 2388).
--define(wxPrintDialog_GetPrintDialogData, 2389).
--define(wxPrintDialog_GetPrintDC, 2390).
--define(wxPrintDialogData_new_0, 2391).
--define(wxPrintDialogData_new_1_1, 2392).
--define(wxPrintDialogData_new_1_0, 2393).
--define(wxPrintDialogData_destruct, 2394).
--define(wxPrintDialogData_EnableHelp, 2395).
--define(wxPrintDialogData_EnablePageNumbers, 2396).
--define(wxPrintDialogData_EnablePrintToFile, 2397).
--define(wxPrintDialogData_EnableSelection, 2398).
--define(wxPrintDialogData_GetAllPages, 2399).
--define(wxPrintDialogData_GetCollate, 2400).
--define(wxPrintDialogData_GetFromPage, 2401).
--define(wxPrintDialogData_GetMaxPage, 2402).
--define(wxPrintDialogData_GetMinPage, 2403).
--define(wxPrintDialogData_GetNoCopies, 2404).
--define(wxPrintDialogData_GetPrintData, 2405).
--define(wxPrintDialogData_GetPrintToFile, 2406).
--define(wxPrintDialogData_GetSelection, 2407).
--define(wxPrintDialogData_GetToPage, 2408).
--define(wxPrintDialogData_IsOk, 2409).
--define(wxPrintDialogData_SetCollate, 2410).
--define(wxPrintDialogData_SetFromPage, 2411).
--define(wxPrintDialogData_SetMaxPage, 2412).
--define(wxPrintDialogData_SetMinPage, 2413).
--define(wxPrintDialogData_SetNoCopies, 2414).
--define(wxPrintDialogData_SetPrintData, 2415).
--define(wxPrintDialogData_SetPrintToFile, 2416).
--define(wxPrintDialogData_SetSelection, 2417).
--define(wxPrintDialogData_SetToPage, 2418).
--define(wxPrintData_new_0, 2419).
--define(wxPrintData_new_1, 2420).
--define(wxPrintData_destruct, 2421).
--define(wxPrintData_GetCollate, 2422).
--define(wxPrintData_GetBin, 2423).
--define(wxPrintData_GetColour, 2424).
--define(wxPrintData_GetDuplex, 2425).
--define(wxPrintData_GetNoCopies, 2426).
--define(wxPrintData_GetOrientation, 2427).
--define(wxPrintData_GetPaperId, 2428).
--define(wxPrintData_GetPrinterName, 2429).
--define(wxPrintData_GetQuality, 2430).
--define(wxPrintData_IsOk, 2431).
--define(wxPrintData_SetBin, 2432).
--define(wxPrintData_SetCollate, 2433).
--define(wxPrintData_SetColour, 2434).
--define(wxPrintData_SetDuplex, 2435).
--define(wxPrintData_SetNoCopies, 2436).
--define(wxPrintData_SetOrientation, 2437).
--define(wxPrintData_SetPaperId, 2438).
--define(wxPrintData_SetPrinterName, 2439).
--define(wxPrintData_SetQuality, 2440).
--define(wxPrintPreview_new_2, 2443).
--define(wxPrintPreview_new_3, 2444).
--define(wxPrintPreview_destruct, 2446).
--define(wxPrintPreview_GetCanvas, 2447).
--define(wxPrintPreview_GetCurrentPage, 2448).
--define(wxPrintPreview_GetFrame, 2449).
--define(wxPrintPreview_GetMaxPage, 2450).
--define(wxPrintPreview_GetMinPage, 2451).
--define(wxPrintPreview_GetPrintout, 2452).
--define(wxPrintPreview_GetPrintoutForPrinting, 2453).
--define(wxPrintPreview_IsOk, 2454).
--define(wxPrintPreview_PaintPage, 2455).
--define(wxPrintPreview_Print, 2456).
--define(wxPrintPreview_RenderPage, 2457).
--define(wxPrintPreview_SetCanvas, 2458).
--define(wxPrintPreview_SetCurrentPage, 2459).
--define(wxPrintPreview_SetFrame, 2460).
--define(wxPrintPreview_SetPrintout, 2461).
--define(wxPrintPreview_SetZoom, 2462).
--define(wxPreviewFrame_new, 2463).
--define(wxPreviewFrame_destruct, 2464).
--define(wxPreviewFrame_CreateControlBar, 2465).
--define(wxPreviewFrame_CreateCanvas, 2466).
--define(wxPreviewFrame_Initialize, 2467).
--define(wxPreviewFrame_OnCloseWindow, 2468).
--define(wxPreviewControlBar_new, 2469).
--define(wxPreviewControlBar_destruct, 2470).
--define(wxPreviewControlBar_CreateButtons, 2471).
--define(wxPreviewControlBar_GetPrintPreview, 2472).
--define(wxPreviewControlBar_GetZoomControl, 2473).
--define(wxPreviewControlBar_SetZoomControl, 2474).
--define(wxPrinter_new, 2476).
--define(wxPrinter_CreateAbortWindow, 2477).
--define(wxPrinter_GetAbort, 2478).
--define(wxPrinter_GetLastError, 2479).
--define(wxPrinter_GetPrintDialogData, 2480).
--define(wxPrinter_Print, 2481).
--define(wxPrinter_PrintDialog, 2482).
--define(wxPrinter_ReportError, 2483).
--define(wxPrinter_Setup, 2484).
--define(wxPrinter_destroy, 2485).
--define(wxXmlResource_new_1, 2486).
--define(wxXmlResource_new_2, 2487).
--define(wxXmlResource_destruct, 2488).
--define(wxXmlResource_AttachUnknownControl, 2489).
--define(wxXmlResource_ClearHandlers, 2490).
--define(wxXmlResource_CompareVersion, 2491).
--define(wxXmlResource_Get, 2492).
--define(wxXmlResource_GetFlags, 2493).
--define(wxXmlResource_GetVersion, 2494).
--define(wxXmlResource_GetXRCID, 2495).
--define(wxXmlResource_InitAllHandlers, 2496).
--define(wxXmlResource_Load, 2497).
--define(wxXmlResource_LoadBitmap, 2498).
--define(wxXmlResource_LoadDialog_2, 2499).
--define(wxXmlResource_LoadDialog_3, 2500).
--define(wxXmlResource_LoadFrame_2, 2501).
--define(wxXmlResource_LoadFrame_3, 2502).
--define(wxXmlResource_LoadIcon, 2503).
--define(wxXmlResource_LoadMenu, 2504).
--define(wxXmlResource_LoadMenuBar_2, 2505).
--define(wxXmlResource_LoadMenuBar_1, 2506).
--define(wxXmlResource_LoadPanel_2, 2507).
--define(wxXmlResource_LoadPanel_3, 2508).
--define(wxXmlResource_LoadToolBar, 2509).
--define(wxXmlResource_Set, 2510).
--define(wxXmlResource_SetFlags, 2511).
--define(wxXmlResource_Unload, 2512).
--define(wxXmlResource_xrcctrl, 2513).
--define(wxHtmlEasyPrinting_new, 2514).
--define(wxHtmlEasyPrinting_destruct, 2515).
--define(wxHtmlEasyPrinting_GetPrintData, 2516).
--define(wxHtmlEasyPrinting_GetPageSetupData, 2517).
--define(wxHtmlEasyPrinting_PreviewFile, 2518).
--define(wxHtmlEasyPrinting_PreviewText, 2519).
--define(wxHtmlEasyPrinting_PrintFile, 2520).
--define(wxHtmlEasyPrinting_PrintText, 2521).
--define(wxHtmlEasyPrinting_PageSetup, 2522).
--define(wxHtmlEasyPrinting_SetFonts, 2523).
--define(wxHtmlEasyPrinting_SetHeader, 2524).
--define(wxHtmlEasyPrinting_SetFooter, 2525).
--define(wxGLCanvas_new_2, 2527).
--define(wxGLCanvas_new_3_1, 2528).
--define(wxGLCanvas_new_3_0, 2529).
--define(wxGLCanvas_GetContext, 2530).
--define(wxGLCanvas_SetCurrent, 2532).
--define(wxGLCanvas_SwapBuffers, 2533).
--define(wxGLCanvas_destroy, 2534).
--define(wxAuiManager_new, 2535).
--define(wxAuiManager_destruct, 2536).
--define(wxAuiManager_AddPane_2_1, 2537).
--define(wxAuiManager_AddPane_3, 2538).
--define(wxAuiManager_AddPane_2_0, 2539).
--define(wxAuiManager_DetachPane, 2540).
--define(wxAuiManager_GetAllPanes, 2541).
--define(wxAuiManager_GetArtProvider, 2542).
--define(wxAuiManager_GetDockSizeConstraint, 2543).
--define(wxAuiManager_GetFlags, 2544).
--define(wxAuiManager_GetManagedWindow, 2545).
--define(wxAuiManager_GetManager, 2546).
--define(wxAuiManager_GetPane_1_1, 2547).
--define(wxAuiManager_GetPane_1_0, 2548).
--define(wxAuiManager_HideHint, 2549).
--define(wxAuiManager_InsertPane, 2550).
--define(wxAuiManager_LoadPaneInfo, 2551).
--define(wxAuiManager_LoadPerspective, 2552).
--define(wxAuiManager_SavePaneInfo, 2553).
--define(wxAuiManager_SavePerspective, 2554).
--define(wxAuiManager_SetArtProvider, 2555).
--define(wxAuiManager_SetDockSizeConstraint, 2556).
--define(wxAuiManager_SetFlags, 2557).
--define(wxAuiManager_SetManagedWindow, 2558).
--define(wxAuiManager_ShowHint, 2559).
--define(wxAuiManager_UnInit, 2560).
--define(wxAuiManager_Update, 2561).
--define(wxAuiPaneInfo_new_0, 2562).
--define(wxAuiPaneInfo_new_1, 2563).
--define(wxAuiPaneInfo_destruct, 2564).
--define(wxAuiPaneInfo_BestSize_1, 2565).
--define(wxAuiPaneInfo_BestSize_2, 2566).
--define(wxAuiPaneInfo_Bottom, 2567).
--define(wxAuiPaneInfo_BottomDockable, 2568).
--define(wxAuiPaneInfo_Caption, 2569).
--define(wxAuiPaneInfo_CaptionVisible, 2570).
--define(wxAuiPaneInfo_Centre, 2571).
--define(wxAuiPaneInfo_CentrePane, 2572).
--define(wxAuiPaneInfo_CloseButton, 2573).
--define(wxAuiPaneInfo_DefaultPane, 2574).
--define(wxAuiPaneInfo_DestroyOnClose, 2575).
--define(wxAuiPaneInfo_Direction, 2576).
--define(wxAuiPaneInfo_Dock, 2577).
--define(wxAuiPaneInfo_Dockable, 2578).
--define(wxAuiPaneInfo_Fixed, 2579).
--define(wxAuiPaneInfo_Float, 2580).
--define(wxAuiPaneInfo_Floatable, 2581).
--define(wxAuiPaneInfo_FloatingPosition_1, 2582).
--define(wxAuiPaneInfo_FloatingPosition_2, 2583).
--define(wxAuiPaneInfo_FloatingSize_1, 2584).
--define(wxAuiPaneInfo_FloatingSize_2, 2585).
--define(wxAuiPaneInfo_Gripper, 2586).
--define(wxAuiPaneInfo_GripperTop, 2587).
--define(wxAuiPaneInfo_HasBorder, 2588).
--define(wxAuiPaneInfo_HasCaption, 2589).
--define(wxAuiPaneInfo_HasCloseButton, 2590).
--define(wxAuiPaneInfo_HasFlag, 2591).
--define(wxAuiPaneInfo_HasGripper, 2592).
--define(wxAuiPaneInfo_HasGripperTop, 2593).
--define(wxAuiPaneInfo_HasMaximizeButton, 2594).
--define(wxAuiPaneInfo_HasMinimizeButton, 2595).
--define(wxAuiPaneInfo_HasPinButton, 2596).
--define(wxAuiPaneInfo_Hide, 2597).
--define(wxAuiPaneInfo_IsBottomDockable, 2598).
--define(wxAuiPaneInfo_IsDocked, 2599).
--define(wxAuiPaneInfo_IsFixed, 2600).
--define(wxAuiPaneInfo_IsFloatable, 2601).
--define(wxAuiPaneInfo_IsFloating, 2602).
--define(wxAuiPaneInfo_IsLeftDockable, 2603).
--define(wxAuiPaneInfo_IsMovable, 2604).
--define(wxAuiPaneInfo_IsOk, 2605).
--define(wxAuiPaneInfo_IsResizable, 2606).
--define(wxAuiPaneInfo_IsRightDockable, 2607).
--define(wxAuiPaneInfo_IsShown, 2608).
--define(wxAuiPaneInfo_IsToolbar, 2609).
--define(wxAuiPaneInfo_IsTopDockable, 2610).
--define(wxAuiPaneInfo_Layer, 2611).
--define(wxAuiPaneInfo_Left, 2612).
--define(wxAuiPaneInfo_LeftDockable, 2613).
--define(wxAuiPaneInfo_MaxSize_1, 2614).
--define(wxAuiPaneInfo_MaxSize_2, 2615).
--define(wxAuiPaneInfo_MaximizeButton, 2616).
--define(wxAuiPaneInfo_MinSize_1, 2617).
--define(wxAuiPaneInfo_MinSize_2, 2618).
--define(wxAuiPaneInfo_MinimizeButton, 2619).
--define(wxAuiPaneInfo_Movable, 2620).
--define(wxAuiPaneInfo_Name, 2621).
--define(wxAuiPaneInfo_PaneBorder, 2622).
--define(wxAuiPaneInfo_PinButton, 2623).
--define(wxAuiPaneInfo_Position, 2624).
--define(wxAuiPaneInfo_Resizable, 2625).
--define(wxAuiPaneInfo_Right, 2626).
--define(wxAuiPaneInfo_RightDockable, 2627).
--define(wxAuiPaneInfo_Row, 2628).
--define(wxAuiPaneInfo_SafeSet, 2629).
--define(wxAuiPaneInfo_SetFlag, 2630).
--define(wxAuiPaneInfo_Show, 2631).
--define(wxAuiPaneInfo_ToolbarPane, 2632).
--define(wxAuiPaneInfo_Top, 2633).
--define(wxAuiPaneInfo_TopDockable, 2634).
--define(wxAuiPaneInfo_Window, 2635).
--define(wxAuiNotebook_new_0, 2636).
--define(wxAuiNotebook_new_2, 2637).
--define(wxAuiNotebook_AddPage, 2638).
--define(wxAuiNotebook_Create, 2639).
--define(wxAuiNotebook_DeletePage, 2640).
--define(wxAuiNotebook_GetArtProvider, 2641).
--define(wxAuiNotebook_GetPage, 2642).
--define(wxAuiNotebook_GetPageBitmap, 2643).
--define(wxAuiNotebook_GetPageCount, 2644).
--define(wxAuiNotebook_GetPageIndex, 2645).
--define(wxAuiNotebook_GetPageText, 2646).
--define(wxAuiNotebook_GetSelection, 2647).
--define(wxAuiNotebook_InsertPage, 2648).
--define(wxAuiNotebook_RemovePage, 2649).
--define(wxAuiNotebook_SetArtProvider, 2650).
--define(wxAuiNotebook_SetFont, 2651).
--define(wxAuiNotebook_SetPageBitmap, 2652).
--define(wxAuiNotebook_SetPageText, 2653).
--define(wxAuiNotebook_SetSelection, 2654).
--define(wxAuiNotebook_SetTabCtrlHeight, 2655).
--define(wxAuiNotebook_SetUniformBitmapSize, 2656).
--define(wxAuiNotebook_destroy, 2657).
--define(wxMDIParentFrame_new_0, 2658).
--define(wxMDIParentFrame_new_4, 2659).
--define(wxMDIParentFrame_destruct, 2660).
--define(wxMDIParentFrame_ActivateNext, 2661).
--define(wxMDIParentFrame_ActivatePrevious, 2662).
--define(wxMDIParentFrame_ArrangeIcons, 2663).
--define(wxMDIParentFrame_Cascade, 2664).
--define(wxMDIParentFrame_Create, 2665).
--define(wxMDIParentFrame_GetActiveChild, 2666).
--define(wxMDIParentFrame_GetClientWindow, 2667).
--define(wxMDIParentFrame_Tile, 2668).
--define(wxMDIChildFrame_new_0, 2669).
--define(wxMDIChildFrame_new_4, 2670).
--define(wxMDIChildFrame_destruct, 2671).
--define(wxMDIChildFrame_Activate, 2672).
--define(wxMDIChildFrame_Create, 2673).
--define(wxMDIChildFrame_Maximize, 2674).
--define(wxMDIChildFrame_Restore, 2675).
--define(wxMDIClientWindow_new_0, 2676).
--define(wxMDIClientWindow_new_2, 2677).
--define(wxMDIClientWindow_destruct, 2678).
--define(wxMDIClientWindow_CreateClient, 2679).
--define(wxLayoutAlgorithm_new, 2680).
--define(wxLayoutAlgorithm_LayoutFrame, 2681).
--define(wxLayoutAlgorithm_LayoutMDIFrame, 2682).
--define(wxLayoutAlgorithm_LayoutWindow, 2683).
--define(wxLayoutAlgorithm_destroy, 2684).
--define(wxEvent_GetId, 2685).
--define(wxEvent_GetSkipped, 2686).
--define(wxEvent_GetTimestamp, 2687).
--define(wxEvent_IsCommandEvent, 2688).
--define(wxEvent_ResumePropagation, 2689).
--define(wxEvent_ShouldPropagate, 2690).
--define(wxEvent_Skip, 2691).
--define(wxEvent_StopPropagation, 2692).
--define(wxCommandEvent_getClientData, 2693).
--define(wxCommandEvent_GetExtraLong, 2694).
--define(wxCommandEvent_GetInt, 2695).
--define(wxCommandEvent_GetSelection, 2696).
--define(wxCommandEvent_GetString, 2697).
--define(wxCommandEvent_IsChecked, 2698).
--define(wxCommandEvent_IsSelection, 2699).
--define(wxCommandEvent_SetInt, 2700).
--define(wxCommandEvent_SetString, 2701).
--define(wxScrollEvent_GetOrientation, 2702).
--define(wxScrollEvent_GetPosition, 2703).
--define(wxScrollWinEvent_GetOrientation, 2704).
--define(wxScrollWinEvent_GetPosition, 2705).
--define(wxMouseEvent_AltDown, 2706).
--define(wxMouseEvent_Button, 2707).
--define(wxMouseEvent_ButtonDClick, 2708).
--define(wxMouseEvent_ButtonDown, 2709).
--define(wxMouseEvent_ButtonUp, 2710).
--define(wxMouseEvent_CmdDown, 2711).
--define(wxMouseEvent_ControlDown, 2712).
--define(wxMouseEvent_Dragging, 2713).
--define(wxMouseEvent_Entering, 2714).
--define(wxMouseEvent_GetButton, 2715).
--define(wxMouseEvent_GetPosition, 2718).
--define(wxMouseEvent_GetLogicalPosition, 2719).
--define(wxMouseEvent_GetLinesPerAction, 2720).
--define(wxMouseEvent_GetWheelRotation, 2721).
--define(wxMouseEvent_GetWheelDelta, 2722).
--define(wxMouseEvent_GetX, 2723).
--define(wxMouseEvent_GetY, 2724).
--define(wxMouseEvent_IsButton, 2725).
--define(wxMouseEvent_IsPageScroll, 2726).
--define(wxMouseEvent_Leaving, 2727).
--define(wxMouseEvent_LeftDClick, 2728).
--define(wxMouseEvent_LeftDown, 2729).
--define(wxMouseEvent_LeftIsDown, 2730).
--define(wxMouseEvent_LeftUp, 2731).
--define(wxMouseEvent_MetaDown, 2732).
--define(wxMouseEvent_MiddleDClick, 2733).
--define(wxMouseEvent_MiddleDown, 2734).
--define(wxMouseEvent_MiddleIsDown, 2735).
--define(wxMouseEvent_MiddleUp, 2736).
--define(wxMouseEvent_Moving, 2737).
--define(wxMouseEvent_RightDClick, 2738).
--define(wxMouseEvent_RightDown, 2739).
--define(wxMouseEvent_RightIsDown, 2740).
--define(wxMouseEvent_RightUp, 2741).
--define(wxMouseEvent_ShiftDown, 2742).
--define(wxSetCursorEvent_GetCursor, 2743).
--define(wxSetCursorEvent_GetX, 2744).
--define(wxSetCursorEvent_GetY, 2745).
--define(wxSetCursorEvent_HasCursor, 2746).
--define(wxSetCursorEvent_SetCursor, 2747).
--define(wxKeyEvent_AltDown, 2748).
--define(wxKeyEvent_CmdDown, 2749).
--define(wxKeyEvent_ControlDown, 2750).
--define(wxKeyEvent_GetKeyCode, 2751).
--define(wxKeyEvent_GetModifiers, 2752).
--define(wxKeyEvent_GetPosition, 2755).
--define(wxKeyEvent_GetRawKeyCode, 2756).
--define(wxKeyEvent_GetRawKeyFlags, 2757).
--define(wxKeyEvent_GetUnicodeKey, 2758).
--define(wxKeyEvent_GetX, 2759).
--define(wxKeyEvent_GetY, 2760).
--define(wxKeyEvent_HasModifiers, 2761).
--define(wxKeyEvent_MetaDown, 2762).
--define(wxKeyEvent_ShiftDown, 2763).
--define(wxSizeEvent_GetSize, 2764).
--define(wxMoveEvent_GetPosition, 2765).
--define(wxEraseEvent_GetDC, 2766).
--define(wxFocusEvent_GetWindow, 2767).
--define(wxChildFocusEvent_GetWindow, 2768).
--define(wxMenuEvent_GetMenu, 2769).
--define(wxMenuEvent_GetMenuId, 2770).
--define(wxMenuEvent_IsPopup, 2771).
--define(wxCloseEvent_CanVeto, 2772).
--define(wxCloseEvent_GetLoggingOff, 2773).
--define(wxCloseEvent_SetCanVeto, 2774).
--define(wxCloseEvent_SetLoggingOff, 2775).
--define(wxCloseEvent_Veto, 2776).
--define(wxShowEvent_SetShow, 2777).
--define(wxShowEvent_GetShow, 2778).
--define(wxIconizeEvent_Iconized, 2779).
--define(wxJoystickEvent_ButtonDown, 2780).
--define(wxJoystickEvent_ButtonIsDown, 2781).
--define(wxJoystickEvent_ButtonUp, 2782).
--define(wxJoystickEvent_GetButtonChange, 2783).
--define(wxJoystickEvent_GetButtonState, 2784).
--define(wxJoystickEvent_GetJoystick, 2785).
--define(wxJoystickEvent_GetPosition, 2786).
--define(wxJoystickEvent_GetZPosition, 2787).
--define(wxJoystickEvent_IsButton, 2788).
--define(wxJoystickEvent_IsMove, 2789).
--define(wxJoystickEvent_IsZMove, 2790).
--define(wxUpdateUIEvent_CanUpdate, 2791).
--define(wxUpdateUIEvent_Check, 2792).
--define(wxUpdateUIEvent_Enable, 2793).
--define(wxUpdateUIEvent_Show, 2794).
--define(wxUpdateUIEvent_GetChecked, 2795).
--define(wxUpdateUIEvent_GetEnabled, 2796).
--define(wxUpdateUIEvent_GetShown, 2797).
--define(wxUpdateUIEvent_GetSetChecked, 2798).
--define(wxUpdateUIEvent_GetSetEnabled, 2799).
--define(wxUpdateUIEvent_GetSetShown, 2800).
--define(wxUpdateUIEvent_GetSetText, 2801).
--define(wxUpdateUIEvent_GetText, 2802).
--define(wxUpdateUIEvent_GetMode, 2803).
--define(wxUpdateUIEvent_GetUpdateInterval, 2804).
--define(wxUpdateUIEvent_ResetUpdateTime, 2805).
--define(wxUpdateUIEvent_SetMode, 2806).
--define(wxUpdateUIEvent_SetText, 2807).
--define(wxUpdateUIEvent_SetUpdateInterval, 2808).
--define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2809).
--define(wxPaletteChangedEvent_SetChangedWindow, 2810).
--define(wxPaletteChangedEvent_GetChangedWindow, 2811).
--define(wxQueryNewPaletteEvent_SetPaletteRealized, 2812).
--define(wxQueryNewPaletteEvent_GetPaletteRealized, 2813).
--define(wxNavigationKeyEvent_GetDirection, 2814).
--define(wxNavigationKeyEvent_SetDirection, 2815).
--define(wxNavigationKeyEvent_IsWindowChange, 2816).
--define(wxNavigationKeyEvent_SetWindowChange, 2817).
--define(wxNavigationKeyEvent_IsFromTab, 2818).
--define(wxNavigationKeyEvent_SetFromTab, 2819).
--define(wxNavigationKeyEvent_GetCurrentFocus, 2820).
--define(wxNavigationKeyEvent_SetCurrentFocus, 2821).
--define(wxHelpEvent_GetOrigin, 2822).
--define(wxHelpEvent_GetPosition, 2823).
--define(wxHelpEvent_SetOrigin, 2824).
--define(wxHelpEvent_SetPosition, 2825).
--define(wxContextMenuEvent_GetPosition, 2826).
--define(wxContextMenuEvent_SetPosition, 2827).
--define(wxIdleEvent_CanSend, 2828).
--define(wxIdleEvent_GetMode, 2829).
--define(wxIdleEvent_RequestMore, 2830).
--define(wxIdleEvent_MoreRequested, 2831).
--define(wxIdleEvent_SetMode, 2832).
--define(wxGridEvent_AltDown, 2833).
--define(wxGridEvent_ControlDown, 2834).
--define(wxGridEvent_GetCol, 2835).
--define(wxGridEvent_GetPosition, 2836).
--define(wxGridEvent_GetRow, 2837).
--define(wxGridEvent_MetaDown, 2838).
--define(wxGridEvent_Selecting, 2839).
--define(wxGridEvent_ShiftDown, 2840).
--define(wxNotifyEvent_Allow, 2841).
--define(wxNotifyEvent_IsAllowed, 2842).
--define(wxNotifyEvent_Veto, 2843).
--define(wxSashEvent_GetEdge, 2844).
--define(wxSashEvent_GetDragRect, 2845).
--define(wxSashEvent_GetDragStatus, 2846).
--define(wxListEvent_GetCacheFrom, 2847).
--define(wxListEvent_GetCacheTo, 2848).
--define(wxListEvent_GetKeyCode, 2849).
--define(wxListEvent_GetIndex, 2850).
--define(wxListEvent_GetColumn, 2851).
--define(wxListEvent_GetPoint, 2852).
--define(wxListEvent_GetLabel, 2853).
--define(wxListEvent_GetText, 2854).
--define(wxListEvent_GetImage, 2855).
--define(wxListEvent_GetData, 2856).
--define(wxListEvent_GetMask, 2857).
--define(wxListEvent_GetItem, 2858).
--define(wxListEvent_IsEditCancelled, 2859).
--define(wxDateEvent_GetDate, 2860).
--define(wxCalendarEvent_GetWeekDay, 2861).
--define(wxFileDirPickerEvent_GetPath, 2862).
--define(wxColourPickerEvent_GetColour, 2863).
--define(wxFontPickerEvent_GetFont, 2864).
--define(wxStyledTextEvent_GetPosition, 2865).
--define(wxStyledTextEvent_GetKey, 2866).
--define(wxStyledTextEvent_GetModifiers, 2867).
--define(wxStyledTextEvent_GetModificationType, 2868).
--define(wxStyledTextEvent_GetText, 2869).
--define(wxStyledTextEvent_GetLength, 2870).
--define(wxStyledTextEvent_GetLinesAdded, 2871).
--define(wxStyledTextEvent_GetLine, 2872).
--define(wxStyledTextEvent_GetFoldLevelNow, 2873).
--define(wxStyledTextEvent_GetFoldLevelPrev, 2874).
--define(wxStyledTextEvent_GetMargin, 2875).
--define(wxStyledTextEvent_GetMessage, 2876).
--define(wxStyledTextEvent_GetWParam, 2877).
--define(wxStyledTextEvent_GetLParam, 2878).
--define(wxStyledTextEvent_GetListType, 2879).
--define(wxStyledTextEvent_GetX, 2880).
--define(wxStyledTextEvent_GetY, 2881).
--define(wxStyledTextEvent_GetDragText, 2882).
--define(wxStyledTextEvent_GetDragAllowMove, 2883).
--define(wxStyledTextEvent_GetDragResult, 2884).
--define(wxStyledTextEvent_GetShift, 2885).
--define(wxStyledTextEvent_GetControl, 2886).
--define(wxStyledTextEvent_GetAlt, 2887).
--define(utils_wxGetKeyState, 2888).
--define(utils_wxGetMousePosition, 2889).
--define(utils_wxGetMouseState, 2890).
--define(utils_wxSetDetectableAutoRepeat, 2891).
--define(utils_wxBell, 2892).
--define(utils_wxFindMenuItemId, 2893).
--define(utils_wxGenericFindWindowAtPoint, 2894).
--define(utils_wxFindWindowAtPoint, 2895).
--define(utils_wxBeginBusyCursor, 2896).
--define(utils_wxEndBusyCursor, 2897).
--define(utils_wxIsBusy, 2898).
--define(utils_wxShutdown, 2899).
--define(utils_wxShell, 2900).
--define(utils_wxLaunchDefaultBrowser, 2901).
--define(utils_wxGetEmailAddress, 2902).
--define(utils_wxGetUserId, 2903).
--define(utils_wxGetHomeDir, 2904).
--define(utils_wxNewId, 2905).
--define(utils_wxRegisterId, 2906).
--define(utils_wxGetCurrentId, 2907).
--define(utils_wxGetOsDescription, 2908).
--define(utils_wxIsPlatformLittleEndian, 2909).
--define(utils_wxIsPlatform64Bit, 2910).
--define(wxPrintout_new, 2911).
--define(wxPrintout_destruct, 2912).
--define(wxPrintout_GetDC, 2913).
--define(wxPrintout_GetPageSizeMM, 2914).
--define(wxPrintout_GetPageSizePixels, 2915).
--define(wxPrintout_GetPaperRectPixels, 2916).
--define(wxPrintout_GetPPIPrinter, 2917).
--define(wxPrintout_GetPPIScreen, 2918).
--define(wxPrintout_GetTitle, 2919).
--define(wxPrintout_IsPreview, 2920).
--define(wxPrintout_FitThisSizeToPaper, 2921).
--define(wxPrintout_FitThisSizeToPage, 2922).
--define(wxPrintout_FitThisSizeToPageMargins, 2923).
--define(wxPrintout_MapScreenSizeToPaper, 2924).
--define(wxPrintout_MapScreenSizeToPage, 2925).
--define(wxPrintout_MapScreenSizeToPageMargins, 2926).
--define(wxPrintout_MapScreenSizeToDevice, 2927).
--define(wxPrintout_GetLogicalPaperRect, 2928).
--define(wxPrintout_GetLogicalPageRect, 2929).
--define(wxPrintout_GetLogicalPageMarginsRect, 2930).
--define(wxPrintout_SetLogicalOrigin, 2931).
--define(wxPrintout_OffsetLogicalOrigin, 2932).
--define(wxStyledTextCtrl_new_2, 2933).
--define(wxStyledTextCtrl_new_0, 2934).
--define(wxStyledTextCtrl_destruct, 2935).
--define(wxStyledTextCtrl_Create, 2936).
--define(wxStyledTextCtrl_AddText, 2937).
--define(wxStyledTextCtrl_AddStyledText, 2938).
--define(wxStyledTextCtrl_InsertText, 2939).
--define(wxStyledTextCtrl_ClearAll, 2940).
--define(wxStyledTextCtrl_ClearDocumentStyle, 2941).
--define(wxStyledTextCtrl_GetLength, 2942).
--define(wxStyledTextCtrl_GetCharAt, 2943).
--define(wxStyledTextCtrl_GetCurrentPos, 2944).
--define(wxStyledTextCtrl_GetAnchor, 2945).
--define(wxStyledTextCtrl_GetStyleAt, 2946).
--define(wxStyledTextCtrl_Redo, 2947).
--define(wxStyledTextCtrl_SetUndoCollection, 2948).
--define(wxStyledTextCtrl_SelectAll, 2949).
--define(wxStyledTextCtrl_SetSavePoint, 2950).
--define(wxStyledTextCtrl_GetStyledText, 2951).
--define(wxStyledTextCtrl_CanRedo, 2952).
--define(wxStyledTextCtrl_MarkerLineFromHandle, 2953).
--define(wxStyledTextCtrl_MarkerDeleteHandle, 2954).
--define(wxStyledTextCtrl_GetUndoCollection, 2955).
--define(wxStyledTextCtrl_GetViewWhiteSpace, 2956).
--define(wxStyledTextCtrl_SetViewWhiteSpace, 2957).
--define(wxStyledTextCtrl_PositionFromPoint, 2958).
--define(wxStyledTextCtrl_PositionFromPointClose, 2959).
--define(wxStyledTextCtrl_GotoLine, 2960).
--define(wxStyledTextCtrl_GotoPos, 2961).
--define(wxStyledTextCtrl_SetAnchor, 2962).
--define(wxStyledTextCtrl_GetCurLine, 2963).
--define(wxStyledTextCtrl_GetEndStyled, 2964).
--define(wxStyledTextCtrl_ConvertEOLs, 2965).
--define(wxStyledTextCtrl_GetEOLMode, 2966).
--define(wxStyledTextCtrl_SetEOLMode, 2967).
--define(wxStyledTextCtrl_StartStyling, 2968).
--define(wxStyledTextCtrl_SetStyling, 2969).
--define(wxStyledTextCtrl_GetBufferedDraw, 2970).
--define(wxStyledTextCtrl_SetBufferedDraw, 2971).
--define(wxStyledTextCtrl_SetTabWidth, 2972).
--define(wxStyledTextCtrl_GetTabWidth, 2973).
--define(wxStyledTextCtrl_SetCodePage, 2974).
--define(wxStyledTextCtrl_MarkerDefine, 2975).
--define(wxStyledTextCtrl_MarkerSetForeground, 2976).
--define(wxStyledTextCtrl_MarkerSetBackground, 2977).
--define(wxStyledTextCtrl_MarkerAdd, 2978).
--define(wxStyledTextCtrl_MarkerDelete, 2979).
--define(wxStyledTextCtrl_MarkerDeleteAll, 2980).
--define(wxStyledTextCtrl_MarkerGet, 2981).
--define(wxStyledTextCtrl_MarkerNext, 2982).
--define(wxStyledTextCtrl_MarkerPrevious, 2983).
--define(wxStyledTextCtrl_MarkerDefineBitmap, 2984).
--define(wxStyledTextCtrl_MarkerAddSet, 2985).
--define(wxStyledTextCtrl_MarkerSetAlpha, 2986).
--define(wxStyledTextCtrl_SetMarginType, 2987).
--define(wxStyledTextCtrl_GetMarginType, 2988).
--define(wxStyledTextCtrl_SetMarginWidth, 2989).
--define(wxStyledTextCtrl_GetMarginWidth, 2990).
--define(wxStyledTextCtrl_SetMarginMask, 2991).
--define(wxStyledTextCtrl_GetMarginMask, 2992).
--define(wxStyledTextCtrl_SetMarginSensitive, 2993).
--define(wxStyledTextCtrl_GetMarginSensitive, 2994).
--define(wxStyledTextCtrl_StyleClearAll, 2995).
--define(wxStyledTextCtrl_StyleSetForeground, 2996).
--define(wxStyledTextCtrl_StyleSetBackground, 2997).
--define(wxStyledTextCtrl_StyleSetBold, 2998).
--define(wxStyledTextCtrl_StyleSetItalic, 2999).
--define(wxStyledTextCtrl_StyleSetSize, 3000).
--define(wxStyledTextCtrl_StyleSetFaceName, 3001).
--define(wxStyledTextCtrl_StyleSetEOLFilled, 3002).
--define(wxStyledTextCtrl_StyleResetDefault, 3003).
--define(wxStyledTextCtrl_StyleSetUnderline, 3004).
--define(wxStyledTextCtrl_StyleSetCase, 3005).
--define(wxStyledTextCtrl_StyleSetHotSpot, 3006).
--define(wxStyledTextCtrl_SetSelForeground, 3007).
--define(wxStyledTextCtrl_SetSelBackground, 3008).
--define(wxStyledTextCtrl_GetSelAlpha, 3009).
--define(wxStyledTextCtrl_SetSelAlpha, 3010).
--define(wxStyledTextCtrl_SetCaretForeground, 3011).
--define(wxStyledTextCtrl_CmdKeyAssign, 3012).
--define(wxStyledTextCtrl_CmdKeyClear, 3013).
--define(wxStyledTextCtrl_CmdKeyClearAll, 3014).
--define(wxStyledTextCtrl_SetStyleBytes, 3015).
--define(wxStyledTextCtrl_StyleSetVisible, 3016).
--define(wxStyledTextCtrl_GetCaretPeriod, 3017).
--define(wxStyledTextCtrl_SetCaretPeriod, 3018).
--define(wxStyledTextCtrl_SetWordChars, 3019).
--define(wxStyledTextCtrl_BeginUndoAction, 3020).
--define(wxStyledTextCtrl_EndUndoAction, 3021).
--define(wxStyledTextCtrl_IndicatorSetStyle, 3022).
--define(wxStyledTextCtrl_IndicatorGetStyle, 3023).
--define(wxStyledTextCtrl_IndicatorSetForeground, 3024).
--define(wxStyledTextCtrl_IndicatorGetForeground, 3025).
--define(wxStyledTextCtrl_SetWhitespaceForeground, 3026).
--define(wxStyledTextCtrl_SetWhitespaceBackground, 3027).
--define(wxStyledTextCtrl_GetStyleBits, 3028).
--define(wxStyledTextCtrl_SetLineState, 3029).
--define(wxStyledTextCtrl_GetLineState, 3030).
--define(wxStyledTextCtrl_GetMaxLineState, 3031).
--define(wxStyledTextCtrl_GetCaretLineVisible, 3032).
--define(wxStyledTextCtrl_SetCaretLineVisible, 3033).
--define(wxStyledTextCtrl_GetCaretLineBackground, 3034).
--define(wxStyledTextCtrl_SetCaretLineBackground, 3035).
--define(wxStyledTextCtrl_AutoCompShow, 3036).
--define(wxStyledTextCtrl_AutoCompCancel, 3037).
--define(wxStyledTextCtrl_AutoCompActive, 3038).
--define(wxStyledTextCtrl_AutoCompPosStart, 3039).
--define(wxStyledTextCtrl_AutoCompComplete, 3040).
--define(wxStyledTextCtrl_AutoCompStops, 3041).
--define(wxStyledTextCtrl_AutoCompSetSeparator, 3042).
--define(wxStyledTextCtrl_AutoCompGetSeparator, 3043).
--define(wxStyledTextCtrl_AutoCompSelect, 3044).
--define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3045).
--define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3046).
--define(wxStyledTextCtrl_AutoCompSetFillUps, 3047).
--define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3048).
--define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3049).
--define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3050).
--define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3051).
--define(wxStyledTextCtrl_UserListShow, 3052).
--define(wxStyledTextCtrl_AutoCompSetAutoHide, 3053).
--define(wxStyledTextCtrl_AutoCompGetAutoHide, 3054).
--define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3055).
--define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3056).
--define(wxStyledTextCtrl_RegisterImage, 3057).
--define(wxStyledTextCtrl_ClearRegisteredImages, 3058).
--define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3059).
--define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3060).
--define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3061).
--define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3062).
--define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3063).
--define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3064).
--define(wxStyledTextCtrl_SetIndent, 3065).
--define(wxStyledTextCtrl_GetIndent, 3066).
--define(wxStyledTextCtrl_SetUseTabs, 3067).
--define(wxStyledTextCtrl_GetUseTabs, 3068).
--define(wxStyledTextCtrl_SetLineIndentation, 3069).
--define(wxStyledTextCtrl_GetLineIndentation, 3070).
--define(wxStyledTextCtrl_GetLineIndentPosition, 3071).
--define(wxStyledTextCtrl_GetColumn, 3072).
--define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3073).
--define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3074).
--define(wxStyledTextCtrl_SetIndentationGuides, 3075).
--define(wxStyledTextCtrl_GetIndentationGuides, 3076).
--define(wxStyledTextCtrl_SetHighlightGuide, 3077).
--define(wxStyledTextCtrl_GetHighlightGuide, 3078).
--define(wxStyledTextCtrl_GetLineEndPosition, 3079).
--define(wxStyledTextCtrl_GetCodePage, 3080).
--define(wxStyledTextCtrl_GetCaretForeground, 3081).
--define(wxStyledTextCtrl_GetReadOnly, 3082).
--define(wxStyledTextCtrl_SetCurrentPos, 3083).
--define(wxStyledTextCtrl_SetSelectionStart, 3084).
--define(wxStyledTextCtrl_GetSelectionStart, 3085).
--define(wxStyledTextCtrl_SetSelectionEnd, 3086).
--define(wxStyledTextCtrl_GetSelectionEnd, 3087).
--define(wxStyledTextCtrl_SetPrintMagnification, 3088).
--define(wxStyledTextCtrl_GetPrintMagnification, 3089).
--define(wxStyledTextCtrl_SetPrintColourMode, 3090).
--define(wxStyledTextCtrl_GetPrintColourMode, 3091).
--define(wxStyledTextCtrl_FindText, 3092).
--define(wxStyledTextCtrl_FormatRange, 3093).
--define(wxStyledTextCtrl_GetFirstVisibleLine, 3094).
--define(wxStyledTextCtrl_GetLine, 3095).
--define(wxStyledTextCtrl_GetLineCount, 3096).
--define(wxStyledTextCtrl_SetMarginLeft, 3097).
--define(wxStyledTextCtrl_GetMarginLeft, 3098).
--define(wxStyledTextCtrl_SetMarginRight, 3099).
--define(wxStyledTextCtrl_GetMarginRight, 3100).
--define(wxStyledTextCtrl_GetModify, 3101).
--define(wxStyledTextCtrl_SetSelection, 3102).
--define(wxStyledTextCtrl_GetSelectedText, 3103).
--define(wxStyledTextCtrl_GetTextRange, 3104).
--define(wxStyledTextCtrl_HideSelection, 3105).
--define(wxStyledTextCtrl_LineFromPosition, 3106).
--define(wxStyledTextCtrl_PositionFromLine, 3107).
--define(wxStyledTextCtrl_LineScroll, 3108).
--define(wxStyledTextCtrl_EnsureCaretVisible, 3109).
--define(wxStyledTextCtrl_ReplaceSelection, 3110).
--define(wxStyledTextCtrl_SetReadOnly, 3111).
--define(wxStyledTextCtrl_CanPaste, 3112).
--define(wxStyledTextCtrl_CanUndo, 3113).
--define(wxStyledTextCtrl_EmptyUndoBuffer, 3114).
--define(wxStyledTextCtrl_Undo, 3115).
--define(wxStyledTextCtrl_Cut, 3116).
--define(wxStyledTextCtrl_Copy, 3117).
--define(wxStyledTextCtrl_Paste, 3118).
--define(wxStyledTextCtrl_Clear, 3119).
--define(wxStyledTextCtrl_SetText, 3120).
--define(wxStyledTextCtrl_GetText, 3121).
--define(wxStyledTextCtrl_GetTextLength, 3122).
--define(wxStyledTextCtrl_GetOvertype, 3123).
--define(wxStyledTextCtrl_SetCaretWidth, 3124).
--define(wxStyledTextCtrl_GetCaretWidth, 3125).
--define(wxStyledTextCtrl_SetTargetStart, 3126).
--define(wxStyledTextCtrl_GetTargetStart, 3127).
--define(wxStyledTextCtrl_SetTargetEnd, 3128).
--define(wxStyledTextCtrl_GetTargetEnd, 3129).
--define(wxStyledTextCtrl_ReplaceTarget, 3130).
--define(wxStyledTextCtrl_SearchInTarget, 3131).
--define(wxStyledTextCtrl_SetSearchFlags, 3132).
--define(wxStyledTextCtrl_GetSearchFlags, 3133).
--define(wxStyledTextCtrl_CallTipShow, 3134).
--define(wxStyledTextCtrl_CallTipCancel, 3135).
--define(wxStyledTextCtrl_CallTipActive, 3136).
--define(wxStyledTextCtrl_CallTipPosAtStart, 3137).
--define(wxStyledTextCtrl_CallTipSetHighlight, 3138).
--define(wxStyledTextCtrl_CallTipSetBackground, 3139).
--define(wxStyledTextCtrl_CallTipSetForeground, 3140).
--define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3141).
--define(wxStyledTextCtrl_CallTipUseStyle, 3142).
--define(wxStyledTextCtrl_VisibleFromDocLine, 3143).
--define(wxStyledTextCtrl_DocLineFromVisible, 3144).
--define(wxStyledTextCtrl_WrapCount, 3145).
--define(wxStyledTextCtrl_SetFoldLevel, 3146).
--define(wxStyledTextCtrl_GetFoldLevel, 3147).
--define(wxStyledTextCtrl_GetLastChild, 3148).
--define(wxStyledTextCtrl_GetFoldParent, 3149).
--define(wxStyledTextCtrl_ShowLines, 3150).
--define(wxStyledTextCtrl_HideLines, 3151).
--define(wxStyledTextCtrl_GetLineVisible, 3152).
--define(wxStyledTextCtrl_SetFoldExpanded, 3153).
--define(wxStyledTextCtrl_GetFoldExpanded, 3154).
--define(wxStyledTextCtrl_ToggleFold, 3155).
--define(wxStyledTextCtrl_EnsureVisible, 3156).
--define(wxStyledTextCtrl_SetFoldFlags, 3157).
--define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3158).
--define(wxStyledTextCtrl_SetTabIndents, 3159).
--define(wxStyledTextCtrl_GetTabIndents, 3160).
--define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3161).
--define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3162).
--define(wxStyledTextCtrl_SetMouseDwellTime, 3163).
--define(wxStyledTextCtrl_GetMouseDwellTime, 3164).
--define(wxStyledTextCtrl_WordStartPosition, 3165).
--define(wxStyledTextCtrl_WordEndPosition, 3166).
--define(wxStyledTextCtrl_SetWrapMode, 3167).
--define(wxStyledTextCtrl_GetWrapMode, 3168).
--define(wxStyledTextCtrl_SetWrapVisualFlags, 3169).
--define(wxStyledTextCtrl_GetWrapVisualFlags, 3170).
--define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3171).
--define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3172).
--define(wxStyledTextCtrl_SetWrapStartIndent, 3173).
--define(wxStyledTextCtrl_GetWrapStartIndent, 3174).
--define(wxStyledTextCtrl_SetLayoutCache, 3175).
--define(wxStyledTextCtrl_GetLayoutCache, 3176).
--define(wxStyledTextCtrl_SetScrollWidth, 3177).
--define(wxStyledTextCtrl_GetScrollWidth, 3178).
--define(wxStyledTextCtrl_TextWidth, 3179).
--define(wxStyledTextCtrl_GetEndAtLastLine, 3180).
--define(wxStyledTextCtrl_TextHeight, 3181).
--define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3182).
--define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3183).
--define(wxStyledTextCtrl_AppendText, 3184).
--define(wxStyledTextCtrl_GetTwoPhaseDraw, 3185).
--define(wxStyledTextCtrl_SetTwoPhaseDraw, 3186).
--define(wxStyledTextCtrl_TargetFromSelection, 3187).
--define(wxStyledTextCtrl_LinesJoin, 3188).
--define(wxStyledTextCtrl_LinesSplit, 3189).
--define(wxStyledTextCtrl_SetFoldMarginColour, 3190).
--define(wxStyledTextCtrl_SetFoldMarginHiColour, 3191).
--define(wxStyledTextCtrl_LineDown, 3192).
--define(wxStyledTextCtrl_LineDownExtend, 3193).
--define(wxStyledTextCtrl_LineUp, 3194).
--define(wxStyledTextCtrl_LineUpExtend, 3195).
--define(wxStyledTextCtrl_CharLeft, 3196).
--define(wxStyledTextCtrl_CharLeftExtend, 3197).
--define(wxStyledTextCtrl_CharRight, 3198).
--define(wxStyledTextCtrl_CharRightExtend, 3199).
--define(wxStyledTextCtrl_WordLeft, 3200).
--define(wxStyledTextCtrl_WordLeftExtend, 3201).
--define(wxStyledTextCtrl_WordRight, 3202).
--define(wxStyledTextCtrl_WordRightExtend, 3203).
--define(wxStyledTextCtrl_Home, 3204).
--define(wxStyledTextCtrl_HomeExtend, 3205).
--define(wxStyledTextCtrl_LineEnd, 3206).
--define(wxStyledTextCtrl_LineEndExtend, 3207).
--define(wxStyledTextCtrl_DocumentStart, 3208).
--define(wxStyledTextCtrl_DocumentStartExtend, 3209).
--define(wxStyledTextCtrl_DocumentEnd, 3210).
--define(wxStyledTextCtrl_DocumentEndExtend, 3211).
--define(wxStyledTextCtrl_PageUp, 3212).
--define(wxStyledTextCtrl_PageUpExtend, 3213).
--define(wxStyledTextCtrl_PageDown, 3214).
--define(wxStyledTextCtrl_PageDownExtend, 3215).
--define(wxStyledTextCtrl_EditToggleOvertype, 3216).
--define(wxStyledTextCtrl_Cancel, 3217).
--define(wxStyledTextCtrl_DeleteBack, 3218).
--define(wxStyledTextCtrl_Tab, 3219).
--define(wxStyledTextCtrl_BackTab, 3220).
--define(wxStyledTextCtrl_NewLine, 3221).
--define(wxStyledTextCtrl_FormFeed, 3222).
--define(wxStyledTextCtrl_VCHome, 3223).
--define(wxStyledTextCtrl_VCHomeExtend, 3224).
--define(wxStyledTextCtrl_ZoomIn, 3225).
--define(wxStyledTextCtrl_ZoomOut, 3226).
--define(wxStyledTextCtrl_DelWordLeft, 3227).
--define(wxStyledTextCtrl_DelWordRight, 3228).
--define(wxStyledTextCtrl_LineCut, 3229).
--define(wxStyledTextCtrl_LineDelete, 3230).
--define(wxStyledTextCtrl_LineTranspose, 3231).
--define(wxStyledTextCtrl_LineDuplicate, 3232).
--define(wxStyledTextCtrl_LowerCase, 3233).
--define(wxStyledTextCtrl_UpperCase, 3234).
--define(wxStyledTextCtrl_LineScrollDown, 3235).
--define(wxStyledTextCtrl_LineScrollUp, 3236).
--define(wxStyledTextCtrl_DeleteBackNotLine, 3237).
--define(wxStyledTextCtrl_HomeDisplay, 3238).
--define(wxStyledTextCtrl_HomeDisplayExtend, 3239).
--define(wxStyledTextCtrl_LineEndDisplay, 3240).
--define(wxStyledTextCtrl_LineEndDisplayExtend, 3241).
--define(wxStyledTextCtrl_HomeWrapExtend, 3242).
--define(wxStyledTextCtrl_LineEndWrap, 3243).
--define(wxStyledTextCtrl_LineEndWrapExtend, 3244).
--define(wxStyledTextCtrl_VCHomeWrap, 3245).
--define(wxStyledTextCtrl_VCHomeWrapExtend, 3246).
--define(wxStyledTextCtrl_LineCopy, 3247).
--define(wxStyledTextCtrl_MoveCaretInsideView, 3248).
--define(wxStyledTextCtrl_LineLength, 3249).
--define(wxStyledTextCtrl_BraceHighlight, 3250).
--define(wxStyledTextCtrl_BraceBadLight, 3251).
--define(wxStyledTextCtrl_BraceMatch, 3252).
--define(wxStyledTextCtrl_GetViewEOL, 3253).
--define(wxStyledTextCtrl_SetViewEOL, 3254).
--define(wxStyledTextCtrl_SetModEventMask, 3255).
--define(wxStyledTextCtrl_GetEdgeColumn, 3256).
--define(wxStyledTextCtrl_SetEdgeColumn, 3257).
--define(wxStyledTextCtrl_GetEdgeMode, 3258).
--define(wxStyledTextCtrl_GetEdgeColour, 3259).
--define(wxStyledTextCtrl_SetEdgeColour, 3260).
--define(wxStyledTextCtrl_SearchAnchor, 3261).
--define(wxStyledTextCtrl_SearchNext, 3262).
--define(wxStyledTextCtrl_SearchPrev, 3263).
--define(wxStyledTextCtrl_LinesOnScreen, 3264).
--define(wxStyledTextCtrl_UsePopUp, 3265).
--define(wxStyledTextCtrl_SelectionIsRectangle, 3266).
--define(wxStyledTextCtrl_SetZoom, 3267).
--define(wxStyledTextCtrl_GetZoom, 3268).
--define(wxStyledTextCtrl_GetModEventMask, 3269).
--define(wxStyledTextCtrl_SetSTCFocus, 3270).
--define(wxStyledTextCtrl_GetSTCFocus, 3271).
--define(wxStyledTextCtrl_SetStatus, 3272).
--define(wxStyledTextCtrl_GetStatus, 3273).
--define(wxStyledTextCtrl_SetMouseDownCaptures, 3274).
--define(wxStyledTextCtrl_GetMouseDownCaptures, 3275).
--define(wxStyledTextCtrl_SetSTCCursor, 3276).
--define(wxStyledTextCtrl_GetSTCCursor, 3277).
--define(wxStyledTextCtrl_SetControlCharSymbol, 3278).
--define(wxStyledTextCtrl_GetControlCharSymbol, 3279).
--define(wxStyledTextCtrl_WordPartLeft, 3280).
--define(wxStyledTextCtrl_WordPartLeftExtend, 3281).
--define(wxStyledTextCtrl_WordPartRight, 3282).
--define(wxStyledTextCtrl_WordPartRightExtend, 3283).
--define(wxStyledTextCtrl_SetVisiblePolicy, 3284).
--define(wxStyledTextCtrl_DelLineLeft, 3285).
--define(wxStyledTextCtrl_DelLineRight, 3286).
--define(wxStyledTextCtrl_GetXOffset, 3287).
--define(wxStyledTextCtrl_ChooseCaretX, 3288).
--define(wxStyledTextCtrl_SetXCaretPolicy, 3289).
--define(wxStyledTextCtrl_SetYCaretPolicy, 3290).
--define(wxStyledTextCtrl_GetPrintWrapMode, 3291).
--define(wxStyledTextCtrl_SetHotspotActiveForeground, 3292).
--define(wxStyledTextCtrl_SetHotspotActiveBackground, 3293).
--define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3294).
--define(wxStyledTextCtrl_SetHotspotSingleLine, 3295).
--define(wxStyledTextCtrl_ParaDownExtend, 3296).
--define(wxStyledTextCtrl_ParaUp, 3297).
--define(wxStyledTextCtrl_ParaUpExtend, 3298).
--define(wxStyledTextCtrl_PositionBefore, 3299).
--define(wxStyledTextCtrl_PositionAfter, 3300).
--define(wxStyledTextCtrl_CopyRange, 3301).
--define(wxStyledTextCtrl_CopyText, 3302).
--define(wxStyledTextCtrl_SetSelectionMode, 3303).
--define(wxStyledTextCtrl_GetSelectionMode, 3304).
--define(wxStyledTextCtrl_LineDownRectExtend, 3305).
--define(wxStyledTextCtrl_LineUpRectExtend, 3306).
--define(wxStyledTextCtrl_CharLeftRectExtend, 3307).
--define(wxStyledTextCtrl_CharRightRectExtend, 3308).
--define(wxStyledTextCtrl_HomeRectExtend, 3309).
--define(wxStyledTextCtrl_VCHomeRectExtend, 3310).
--define(wxStyledTextCtrl_LineEndRectExtend, 3311).
--define(wxStyledTextCtrl_PageUpRectExtend, 3312).
--define(wxStyledTextCtrl_PageDownRectExtend, 3313).
--define(wxStyledTextCtrl_StutteredPageUp, 3314).
--define(wxStyledTextCtrl_StutteredPageUpExtend, 3315).
--define(wxStyledTextCtrl_StutteredPageDown, 3316).
--define(wxStyledTextCtrl_StutteredPageDownExtend, 3317).
--define(wxStyledTextCtrl_WordLeftEnd, 3318).
--define(wxStyledTextCtrl_WordLeftEndExtend, 3319).
--define(wxStyledTextCtrl_WordRightEnd, 3320).
--define(wxStyledTextCtrl_WordRightEndExtend, 3321).
--define(wxStyledTextCtrl_SetWhitespaceChars, 3322).
--define(wxStyledTextCtrl_SetCharsDefault, 3323).
--define(wxStyledTextCtrl_AutoCompGetCurrent, 3324).
--define(wxStyledTextCtrl_Allocate, 3325).
--define(wxStyledTextCtrl_FindColumn, 3326).
--define(wxStyledTextCtrl_GetCaretSticky, 3327).
--define(wxStyledTextCtrl_SetCaretSticky, 3328).
--define(wxStyledTextCtrl_ToggleCaretSticky, 3329).
--define(wxStyledTextCtrl_SetPasteConvertEndings, 3330).
--define(wxStyledTextCtrl_GetPasteConvertEndings, 3331).
--define(wxStyledTextCtrl_SelectionDuplicate, 3332).
--define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3333).
--define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3334).
--define(wxStyledTextCtrl_StartRecord, 3335).
--define(wxStyledTextCtrl_StopRecord, 3336).
--define(wxStyledTextCtrl_SetLexer, 3337).
--define(wxStyledTextCtrl_GetLexer, 3338).
--define(wxStyledTextCtrl_Colourise, 3339).
--define(wxStyledTextCtrl_SetProperty, 3340).
--define(wxStyledTextCtrl_SetKeyWords, 3341).
--define(wxStyledTextCtrl_SetLexerLanguage, 3342).
--define(wxStyledTextCtrl_GetProperty, 3343).
--define(wxStyledTextCtrl_GetStyleBitsNeeded, 3344).
--define(wxStyledTextCtrl_GetCurrentLine, 3345).
--define(wxStyledTextCtrl_StyleSetSpec, 3346).
--define(wxStyledTextCtrl_StyleSetFont, 3347).
--define(wxStyledTextCtrl_StyleSetFontAttr, 3348).
--define(wxStyledTextCtrl_StyleSetCharacterSet, 3349).
--define(wxStyledTextCtrl_StyleSetFontEncoding, 3350).
--define(wxStyledTextCtrl_CmdKeyExecute, 3351).
--define(wxStyledTextCtrl_SetMargins, 3352).
--define(wxStyledTextCtrl_GetSelection, 3353).
--define(wxStyledTextCtrl_PointFromPosition, 3354).
--define(wxStyledTextCtrl_ScrollToLine, 3355).
--define(wxStyledTextCtrl_ScrollToColumn, 3356).
--define(wxStyledTextCtrl_SendMsg, 3357).
--define(wxStyledTextCtrl_SetVScrollBar, 3358).
--define(wxStyledTextCtrl_SetHScrollBar, 3359).
--define(wxStyledTextCtrl_GetLastKeydownProcessed, 3360).
--define(wxStyledTextCtrl_SetLastKeydownProcessed, 3361).
--define(wxStyledTextCtrl_SaveFile, 3362).
--define(wxStyledTextCtrl_LoadFile, 3363).
--define(wxStyledTextCtrl_DoDragOver, 3364).
--define(wxStyledTextCtrl_DoDropText, 3365).
--define(wxStyledTextCtrl_GetUseAntiAliasing, 3366).
--define(wxStyledTextCtrl_AddTextRaw, 3367).
--define(wxStyledTextCtrl_InsertTextRaw, 3368).
--define(wxStyledTextCtrl_GetCurLineRaw, 3369).
--define(wxStyledTextCtrl_GetLineRaw, 3370).
--define(wxStyledTextCtrl_GetSelectedTextRaw, 3371).
--define(wxStyledTextCtrl_GetTextRangeRaw, 3372).
--define(wxStyledTextCtrl_SetTextRaw, 3373).
--define(wxStyledTextCtrl_GetTextRaw, 3374).
--define(wxStyledTextCtrl_AppendTextRaw, 3375).
--define(wxArtProvider_GetBitmap, 3376).
--define(wxArtProvider_GetIcon, 3377).
--define(wxTreeEvent_GetKeyCode, 3378).
--define(wxTreeEvent_GetItem, 3379).
--define(wxTreeEvent_GetKeyEvent, 3380).
--define(wxTreeEvent_GetLabel, 3381).
--define(wxTreeEvent_GetOldItem, 3382).
--define(wxTreeEvent_GetPoint, 3383).
--define(wxTreeEvent_IsEditCancelled, 3384).
--define(wxTreeEvent_SetToolTip, 3385).
--define(wxNotebookEvent_GetOldSelection, 3386).
--define(wxNotebookEvent_GetSelection, 3387).
--define(wxNotebookEvent_SetOldSelection, 3388).
--define(wxNotebookEvent_SetSelection, 3389).
--define(wxFileDataObject_new, 3390).
--define(wxFileDataObject_AddFile, 3391).
--define(wxFileDataObject_GetFilenames, 3392).
--define(wxFileDataObject_destroy, 3393).
--define(wxTextDataObject_new, 3394).
--define(wxTextDataObject_GetTextLength, 3395).
--define(wxTextDataObject_GetText, 3396).
--define(wxTextDataObject_SetText, 3397).
--define(wxTextDataObject_destroy, 3398).
--define(wxBitmapDataObject_new_1_1, 3399).
--define(wxBitmapDataObject_new_1_0, 3400).
--define(wxBitmapDataObject_GetBitmap, 3401).
--define(wxBitmapDataObject_SetBitmap, 3402).
--define(wxBitmapDataObject_destroy, 3403).
--define(wxClipboard_new, 3405).
--define(wxClipboard_destruct, 3406).
--define(wxClipboard_AddData, 3407).
--define(wxClipboard_Clear, 3408).
--define(wxClipboard_Close, 3409).
--define(wxClipboard_Flush, 3410).
--define(wxClipboard_GetData, 3411).
--define(wxClipboard_IsOpened, 3412).
--define(wxClipboard_Open, 3413).
--define(wxClipboard_SetData, 3414).
--define(wxClipboard_UsePrimarySelection, 3416).
--define(wxClipboard_IsSupported, 3417).
--define(wxClipboard_Get, 3418).
--define(wxSpinEvent_GetPosition, 3419).
--define(wxSpinEvent_SetPosition, 3420).
--define(wxSplitterWindow_new_0, 3421).
--define(wxSplitterWindow_new_2, 3422).
--define(wxSplitterWindow_destruct, 3423).
--define(wxSplitterWindow_Create, 3424).
--define(wxSplitterWindow_GetMinimumPaneSize, 3425).
--define(wxSplitterWindow_GetSashGravity, 3426).
--define(wxSplitterWindow_GetSashPosition, 3427).
--define(wxSplitterWindow_GetSplitMode, 3428).
--define(wxSplitterWindow_GetWindow1, 3429).
--define(wxSplitterWindow_GetWindow2, 3430).
--define(wxSplitterWindow_Initialize, 3431).
--define(wxSplitterWindow_IsSplit, 3432).
--define(wxSplitterWindow_ReplaceWindow, 3433).
--define(wxSplitterWindow_SetSashGravity, 3434).
--define(wxSplitterWindow_SetSashPosition, 3435).
--define(wxSplitterWindow_SetSashSize, 3436).
--define(wxSplitterWindow_SetMinimumPaneSize, 3437).
--define(wxSplitterWindow_SetSplitMode, 3438).
--define(wxSplitterWindow_SplitHorizontally, 3439).
--define(wxSplitterWindow_SplitVertically, 3440).
--define(wxSplitterWindow_Unsplit, 3441).
--define(wxSplitterWindow_UpdateSize, 3442).
--define(wxSplitterEvent_GetSashPosition, 3443).
--define(wxSplitterEvent_GetX, 3444).
--define(wxSplitterEvent_GetY, 3445).
--define(wxSplitterEvent_GetWindowBeingRemoved, 3446).
--define(wxSplitterEvent_SetSashPosition, 3447).
--define(wxHtmlWindow_new_0, 3448).
--define(wxHtmlWindow_new_2, 3449).
--define(wxHtmlWindow_AppendToPage, 3450).
--define(wxHtmlWindow_GetOpenedAnchor, 3451).
--define(wxHtmlWindow_GetOpenedPage, 3452).
--define(wxHtmlWindow_GetOpenedPageTitle, 3453).
--define(wxHtmlWindow_GetRelatedFrame, 3454).
--define(wxHtmlWindow_HistoryBack, 3455).
--define(wxHtmlWindow_HistoryCanBack, 3456).
--define(wxHtmlWindow_HistoryCanForward, 3457).
--define(wxHtmlWindow_HistoryClear, 3458).
--define(wxHtmlWindow_HistoryForward, 3459).
--define(wxHtmlWindow_LoadFile, 3460).
--define(wxHtmlWindow_LoadPage, 3461).
--define(wxHtmlWindow_SelectAll, 3462).
--define(wxHtmlWindow_SelectionToText, 3463).
--define(wxHtmlWindow_SelectLine, 3464).
--define(wxHtmlWindow_SelectWord, 3465).
--define(wxHtmlWindow_SetBorders, 3466).
--define(wxHtmlWindow_SetFonts, 3467).
--define(wxHtmlWindow_SetPage, 3468).
--define(wxHtmlWindow_SetRelatedFrame, 3469).
--define(wxHtmlWindow_SetRelatedStatusBar, 3470).
--define(wxHtmlWindow_ToText, 3471).
--define(wxHtmlWindow_destroy, 3472).
--define(wxHtmlLinkEvent_GetLinkInfo, 3473).
--define(wxAuiNotebookEvent_SetSelection, 3474).
--define(wxAuiNotebookEvent_GetSelection, 3475).
--define(wxAuiNotebookEvent_SetOldSelection, 3476).
--define(wxAuiNotebookEvent_GetOldSelection, 3477).
--define(wxAuiNotebookEvent_SetDragSource, 3478).
--define(wxAuiNotebookEvent_GetDragSource, 3479).
--define(wxAuiManagerEvent_SetManager, 3480).
--define(wxAuiManagerEvent_GetManager, 3481).
--define(wxAuiManagerEvent_SetPane, 3482).
--define(wxAuiManagerEvent_GetPane, 3483).
--define(wxAuiManagerEvent_SetButton, 3484).
--define(wxAuiManagerEvent_GetButton, 3485).
--define(wxAuiManagerEvent_SetDC, 3486).
--define(wxAuiManagerEvent_GetDC, 3487).
--define(wxAuiManagerEvent_Veto, 3488).
--define(wxAuiManagerEvent_GetVeto, 3489).
--define(wxAuiManagerEvent_SetCanVeto, 3490).
--define(wxAuiManagerEvent_CanVeto, 3491).
--define(wxLogNull_new, 3492).
--define(wxLogNull_destroy, 3493).
+-define(wxTreeCtrl_GetFirstChild, 2018).
+-define(wxTreeCtrl_GetNextChild, 2019).
+-define(wxTreeCtrl_GetFirstVisibleItem, 2020).
+-define(wxTreeCtrl_GetImageList, 2021).
+-define(wxTreeCtrl_GetIndent, 2022).
+-define(wxTreeCtrl_GetItemBackgroundColour, 2023).
+-define(wxTreeCtrl_GetItemData, 2024).
+-define(wxTreeCtrl_GetItemFont, 2025).
+-define(wxTreeCtrl_GetItemImage_1, 2026).
+-define(wxTreeCtrl_GetItemImage_2, 2027).
+-define(wxTreeCtrl_GetItemText, 2028).
+-define(wxTreeCtrl_GetItemTextColour, 2029).
+-define(wxTreeCtrl_GetLastChild, 2030).
+-define(wxTreeCtrl_GetNextSibling, 2031).
+-define(wxTreeCtrl_GetNextVisible, 2032).
+-define(wxTreeCtrl_GetItemParent, 2033).
+-define(wxTreeCtrl_GetPrevSibling, 2034).
+-define(wxTreeCtrl_GetPrevVisible, 2035).
+-define(wxTreeCtrl_GetRootItem, 2036).
+-define(wxTreeCtrl_GetSelection, 2037).
+-define(wxTreeCtrl_GetSelections, 2038).
+-define(wxTreeCtrl_GetStateImageList, 2039).
+-define(wxTreeCtrl_HitTest, 2040).
+-define(wxTreeCtrl_InsertItem, 2042).
+-define(wxTreeCtrl_IsBold, 2043).
+-define(wxTreeCtrl_IsExpanded, 2044).
+-define(wxTreeCtrl_IsSelected, 2045).
+-define(wxTreeCtrl_IsVisible, 2046).
+-define(wxTreeCtrl_ItemHasChildren, 2047).
+-define(wxTreeCtrl_PrependItem, 2048).
+-define(wxTreeCtrl_ScrollTo, 2049).
+-define(wxTreeCtrl_SelectItem_1, 2050).
+-define(wxTreeCtrl_SelectItem_2, 2051).
+-define(wxTreeCtrl_SetIndent, 2052).
+-define(wxTreeCtrl_SetImageList, 2053).
+-define(wxTreeCtrl_SetItemBackgroundColour, 2054).
+-define(wxTreeCtrl_SetItemBold, 2055).
+-define(wxTreeCtrl_SetItemData, 2056).
+-define(wxTreeCtrl_SetItemDropHighlight, 2057).
+-define(wxTreeCtrl_SetItemFont, 2058).
+-define(wxTreeCtrl_SetItemHasChildren, 2059).
+-define(wxTreeCtrl_SetItemImage_2, 2060).
+-define(wxTreeCtrl_SetItemImage_3, 2061).
+-define(wxTreeCtrl_SetItemText, 2062).
+-define(wxTreeCtrl_SetItemTextColour, 2063).
+-define(wxTreeCtrl_SetStateImageList, 2064).
+-define(wxTreeCtrl_SetWindowStyle, 2065).
+-define(wxTreeCtrl_SortChildren, 2066).
+-define(wxTreeCtrl_Toggle, 2067).
+-define(wxTreeCtrl_ToggleItemSelection, 2068).
+-define(wxTreeCtrl_Unselect, 2069).
+-define(wxTreeCtrl_UnselectAll, 2070).
+-define(wxTreeCtrl_UnselectItem, 2071).
+-define(wxScrollBar_new_0, 2072).
+-define(wxScrollBar_new_3, 2073).
+-define(wxScrollBar_destruct, 2074).
+-define(wxScrollBar_Create, 2075).
+-define(wxScrollBar_GetRange, 2076).
+-define(wxScrollBar_GetPageSize, 2077).
+-define(wxScrollBar_GetThumbPosition, 2078).
+-define(wxScrollBar_GetThumbSize, 2079).
+-define(wxScrollBar_SetThumbPosition, 2080).
+-define(wxScrollBar_SetScrollbar, 2081).
+-define(wxSpinButton_new_2, 2083).
+-define(wxSpinButton_new_0, 2084).
+-define(wxSpinButton_Create, 2085).
+-define(wxSpinButton_GetMax, 2086).
+-define(wxSpinButton_GetMin, 2087).
+-define(wxSpinButton_GetValue, 2088).
+-define(wxSpinButton_SetRange, 2089).
+-define(wxSpinButton_SetValue, 2090).
+-define(wxSpinButton_destroy, 2091).
+-define(wxSpinCtrl_new_0, 2092).
+-define(wxSpinCtrl_new_2, 2093).
+-define(wxSpinCtrl_Create, 2095).
+-define(wxSpinCtrl_SetValue_1_1, 2098).
+-define(wxSpinCtrl_SetValue_1_0, 2099).
+-define(wxSpinCtrl_GetValue, 2101).
+-define(wxSpinCtrl_SetRange, 2103).
+-define(wxSpinCtrl_SetSelection, 2104).
+-define(wxSpinCtrl_GetMin, 2106).
+-define(wxSpinCtrl_GetMax, 2108).
+-define(wxSpinCtrl_destroy, 2109).
+-define(wxStaticText_new_0, 2110).
+-define(wxStaticText_new_4, 2111).
+-define(wxStaticText_Create, 2112).
+-define(wxStaticText_GetLabel, 2113).
+-define(wxStaticText_SetLabel, 2114).
+-define(wxStaticText_Wrap, 2115).
+-define(wxStaticText_destroy, 2116).
+-define(wxStaticBitmap_new_0, 2117).
+-define(wxStaticBitmap_new_4, 2118).
+-define(wxStaticBitmap_Create, 2119).
+-define(wxStaticBitmap_GetBitmap, 2120).
+-define(wxStaticBitmap_SetBitmap, 2121).
+-define(wxStaticBitmap_destroy, 2122).
+-define(wxRadioBox_new, 2123).
+-define(wxRadioBox_destruct, 2125).
+-define(wxRadioBox_Create, 2126).
+-define(wxRadioBox_Enable_2, 2127).
+-define(wxRadioBox_Enable_1, 2128).
+-define(wxRadioBox_GetSelection, 2129).
+-define(wxRadioBox_GetString, 2130).
+-define(wxRadioBox_SetSelection, 2131).
+-define(wxRadioBox_Show_2, 2132).
+-define(wxRadioBox_Show_1, 2133).
+-define(wxRadioBox_GetColumnCount, 2134).
+-define(wxRadioBox_GetItemHelpText, 2135).
+-define(wxRadioBox_GetItemToolTip, 2136).
+-define(wxRadioBox_GetItemFromPoint, 2138).
+-define(wxRadioBox_GetRowCount, 2139).
+-define(wxRadioBox_IsItemEnabled, 2140).
+-define(wxRadioBox_IsItemShown, 2141).
+-define(wxRadioBox_SetItemHelpText, 2142).
+-define(wxRadioBox_SetItemToolTip, 2143).
+-define(wxRadioButton_new_0, 2144).
+-define(wxRadioButton_new_4, 2145).
+-define(wxRadioButton_Create, 2146).
+-define(wxRadioButton_GetValue, 2147).
+-define(wxRadioButton_SetValue, 2148).
+-define(wxRadioButton_destroy, 2149).
+-define(wxSlider_new_6, 2151).
+-define(wxSlider_new_0, 2152).
+-define(wxSlider_Create, 2153).
+-define(wxSlider_GetLineSize, 2154).
+-define(wxSlider_GetMax, 2155).
+-define(wxSlider_GetMin, 2156).
+-define(wxSlider_GetPageSize, 2157).
+-define(wxSlider_GetThumbLength, 2158).
+-define(wxSlider_GetValue, 2159).
+-define(wxSlider_SetLineSize, 2160).
+-define(wxSlider_SetPageSize, 2161).
+-define(wxSlider_SetRange, 2162).
+-define(wxSlider_SetThumbLength, 2163).
+-define(wxSlider_SetValue, 2164).
+-define(wxSlider_destroy, 2165).
+-define(wxDialog_new_4, 2167).
+-define(wxDialog_new_0, 2168).
+-define(wxDialog_destruct, 2170).
+-define(wxDialog_Create, 2171).
+-define(wxDialog_CreateButtonSizer, 2172).
+-define(wxDialog_CreateStdDialogButtonSizer, 2173).
+-define(wxDialog_EndModal, 2174).
+-define(wxDialog_GetAffirmativeId, 2175).
+-define(wxDialog_GetReturnCode, 2176).
+-define(wxDialog_IsModal, 2177).
+-define(wxDialog_SetAffirmativeId, 2178).
+-define(wxDialog_SetReturnCode, 2179).
+-define(wxDialog_Show, 2180).
+-define(wxDialog_ShowModal, 2181).
+-define(wxColourDialog_new_0, 2182).
+-define(wxColourDialog_new_2, 2183).
+-define(wxColourDialog_destruct, 2184).
+-define(wxColourDialog_Create, 2185).
+-define(wxColourDialog_GetColourData, 2186).
+-define(wxColourData_new_0, 2187).
+-define(wxColourData_new_1, 2188).
+-define(wxColourData_destruct, 2189).
+-define(wxColourData_GetChooseFull, 2190).
+-define(wxColourData_GetColour, 2191).
+-define(wxColourData_GetCustomColour, 2193).
+-define(wxColourData_SetChooseFull, 2194).
+-define(wxColourData_SetColour, 2195).
+-define(wxColourData_SetCustomColour, 2196).
+-define(wxPalette_new_0, 2197).
+-define(wxPalette_new_4, 2198).
+-define(wxPalette_destruct, 2200).
+-define(wxPalette_Create, 2201).
+-define(wxPalette_GetColoursCount, 2202).
+-define(wxPalette_GetPixel, 2203).
+-define(wxPalette_GetRGB, 2204).
+-define(wxPalette_IsOk, 2205).
+-define(wxDirDialog_new, 2209).
+-define(wxDirDialog_destruct, 2210).
+-define(wxDirDialog_GetPath, 2211).
+-define(wxDirDialog_GetMessage, 2212).
+-define(wxDirDialog_SetMessage, 2213).
+-define(wxDirDialog_SetPath, 2214).
+-define(wxFileDialog_new, 2218).
+-define(wxFileDialog_destruct, 2219).
+-define(wxFileDialog_GetDirectory, 2220).
+-define(wxFileDialog_GetFilename, 2221).
+-define(wxFileDialog_GetFilenames, 2222).
+-define(wxFileDialog_GetFilterIndex, 2223).
+-define(wxFileDialog_GetMessage, 2224).
+-define(wxFileDialog_GetPath, 2225).
+-define(wxFileDialog_GetPaths, 2226).
+-define(wxFileDialog_GetWildcard, 2227).
+-define(wxFileDialog_SetDirectory, 2228).
+-define(wxFileDialog_SetFilename, 2229).
+-define(wxFileDialog_SetFilterIndex, 2230).
+-define(wxFileDialog_SetMessage, 2231).
+-define(wxFileDialog_SetPath, 2232).
+-define(wxFileDialog_SetWildcard, 2233).
+-define(wxPickerBase_SetInternalMargin, 2234).
+-define(wxPickerBase_GetInternalMargin, 2235).
+-define(wxPickerBase_SetTextCtrlProportion, 2236).
+-define(wxPickerBase_SetPickerCtrlProportion, 2237).
+-define(wxPickerBase_GetTextCtrlProportion, 2238).
+-define(wxPickerBase_GetPickerCtrlProportion, 2239).
+-define(wxPickerBase_HasTextCtrl, 2240).
+-define(wxPickerBase_GetTextCtrl, 2241).
+-define(wxPickerBase_IsTextCtrlGrowable, 2242).
+-define(wxPickerBase_SetPickerCtrlGrowable, 2243).
+-define(wxPickerBase_SetTextCtrlGrowable, 2244).
+-define(wxPickerBase_IsPickerCtrlGrowable, 2245).
+-define(wxFilePickerCtrl_new_0, 2246).
+-define(wxFilePickerCtrl_new_3, 2247).
+-define(wxFilePickerCtrl_Create, 2248).
+-define(wxFilePickerCtrl_GetPath, 2249).
+-define(wxFilePickerCtrl_SetPath, 2250).
+-define(wxFilePickerCtrl_destroy, 2251).
+-define(wxDirPickerCtrl_new_0, 2252).
+-define(wxDirPickerCtrl_new_3, 2253).
+-define(wxDirPickerCtrl_Create, 2254).
+-define(wxDirPickerCtrl_GetPath, 2255).
+-define(wxDirPickerCtrl_SetPath, 2256).
+-define(wxDirPickerCtrl_destroy, 2257).
+-define(wxColourPickerCtrl_new_0, 2258).
+-define(wxColourPickerCtrl_new_3, 2259).
+-define(wxColourPickerCtrl_Create, 2260).
+-define(wxColourPickerCtrl_GetColour, 2261).
+-define(wxColourPickerCtrl_SetColour_1_1, 2262).
+-define(wxColourPickerCtrl_SetColour_1_0, 2263).
+-define(wxColourPickerCtrl_destroy, 2264).
+-define(wxDatePickerCtrl_new_0, 2265).
+-define(wxDatePickerCtrl_new_3, 2266).
+-define(wxDatePickerCtrl_GetRange, 2267).
+-define(wxDatePickerCtrl_GetValue, 2268).
+-define(wxDatePickerCtrl_SetRange, 2269).
+-define(wxDatePickerCtrl_SetValue, 2270).
+-define(wxDatePickerCtrl_destroy, 2271).
+-define(wxFontPickerCtrl_new_0, 2272).
+-define(wxFontPickerCtrl_new_3, 2273).
+-define(wxFontPickerCtrl_Create, 2274).
+-define(wxFontPickerCtrl_GetSelectedFont, 2275).
+-define(wxFontPickerCtrl_SetSelectedFont, 2276).
+-define(wxFontPickerCtrl_GetMaxPointSize, 2277).
+-define(wxFontPickerCtrl_SetMaxPointSize, 2278).
+-define(wxFontPickerCtrl_destroy, 2279).
+-define(wxFindReplaceDialog_new_0, 2282).
+-define(wxFindReplaceDialog_new_4, 2283).
+-define(wxFindReplaceDialog_destruct, 2284).
+-define(wxFindReplaceDialog_Create, 2285).
+-define(wxFindReplaceDialog_GetData, 2286).
+-define(wxFindReplaceData_new_0, 2287).
+-define(wxFindReplaceData_new_1, 2288).
+-define(wxFindReplaceData_GetFindString, 2289).
+-define(wxFindReplaceData_GetReplaceString, 2290).
+-define(wxFindReplaceData_GetFlags, 2291).
+-define(wxFindReplaceData_SetFlags, 2292).
+-define(wxFindReplaceData_SetFindString, 2293).
+-define(wxFindReplaceData_SetReplaceString, 2294).
+-define(wxFindReplaceData_destroy, 2295).
+-define(wxMultiChoiceDialog_new_0, 2296).
+-define(wxMultiChoiceDialog_new_5, 2298).
+-define(wxMultiChoiceDialog_GetSelections, 2299).
+-define(wxMultiChoiceDialog_SetSelections, 2300).
+-define(wxMultiChoiceDialog_destroy, 2301).
+-define(wxSingleChoiceDialog_new_0, 2302).
+-define(wxSingleChoiceDialog_new_5, 2304).
+-define(wxSingleChoiceDialog_GetSelection, 2305).
+-define(wxSingleChoiceDialog_GetStringSelection, 2306).
+-define(wxSingleChoiceDialog_SetSelection, 2307).
+-define(wxSingleChoiceDialog_destroy, 2308).
+-define(wxTextEntryDialog_new, 2309).
+-define(wxTextEntryDialog_GetValue, 2310).
+-define(wxTextEntryDialog_SetValue, 2311).
+-define(wxTextEntryDialog_destroy, 2312).
+-define(wxPasswordEntryDialog_new, 2313).
+-define(wxPasswordEntryDialog_destroy, 2314).
+-define(wxFontData_new_0, 2315).
+-define(wxFontData_new_1, 2316).
+-define(wxFontData_destruct, 2317).
+-define(wxFontData_EnableEffects, 2318).
+-define(wxFontData_GetAllowSymbols, 2319).
+-define(wxFontData_GetColour, 2320).
+-define(wxFontData_GetChosenFont, 2321).
+-define(wxFontData_GetEnableEffects, 2322).
+-define(wxFontData_GetInitialFont, 2323).
+-define(wxFontData_GetShowHelp, 2324).
+-define(wxFontData_SetAllowSymbols, 2325).
+-define(wxFontData_SetChosenFont, 2326).
+-define(wxFontData_SetColour, 2327).
+-define(wxFontData_SetInitialFont, 2328).
+-define(wxFontData_SetRange, 2329).
+-define(wxFontData_SetShowHelp, 2330).
+-define(wxFontDialog_new_0, 2334).
+-define(wxFontDialog_new_2, 2336).
+-define(wxFontDialog_Create, 2338).
+-define(wxFontDialog_GetFontData, 2339).
+-define(wxFontDialog_destroy, 2341).
+-define(wxProgressDialog_new, 2342).
+-define(wxProgressDialog_destruct, 2343).
+-define(wxProgressDialog_Resume, 2344).
+-define(wxProgressDialog_Update_2, 2345).
+-define(wxProgressDialog_Update_0, 2346).
+-define(wxMessageDialog_new, 2347).
+-define(wxMessageDialog_destruct, 2348).
+-define(wxPageSetupDialog_new, 2349).
+-define(wxPageSetupDialog_destruct, 2350).
+-define(wxPageSetupDialog_GetPageSetupData, 2351).
+-define(wxPageSetupDialog_ShowModal, 2352).
+-define(wxPageSetupDialogData_new_0, 2353).
+-define(wxPageSetupDialogData_new_1_0, 2354).
+-define(wxPageSetupDialogData_new_1_1, 2355).
+-define(wxPageSetupDialogData_destruct, 2356).
+-define(wxPageSetupDialogData_EnableHelp, 2357).
+-define(wxPageSetupDialogData_EnableMargins, 2358).
+-define(wxPageSetupDialogData_EnableOrientation, 2359).
+-define(wxPageSetupDialogData_EnablePaper, 2360).
+-define(wxPageSetupDialogData_EnablePrinter, 2361).
+-define(wxPageSetupDialogData_GetDefaultMinMargins, 2362).
+-define(wxPageSetupDialogData_GetEnableMargins, 2363).
+-define(wxPageSetupDialogData_GetEnableOrientation, 2364).
+-define(wxPageSetupDialogData_GetEnablePaper, 2365).
+-define(wxPageSetupDialogData_GetEnablePrinter, 2366).
+-define(wxPageSetupDialogData_GetEnableHelp, 2367).
+-define(wxPageSetupDialogData_GetDefaultInfo, 2368).
+-define(wxPageSetupDialogData_GetMarginTopLeft, 2369).
+-define(wxPageSetupDialogData_GetMarginBottomRight, 2370).
+-define(wxPageSetupDialogData_GetMinMarginTopLeft, 2371).
+-define(wxPageSetupDialogData_GetMinMarginBottomRight, 2372).
+-define(wxPageSetupDialogData_GetPaperId, 2373).
+-define(wxPageSetupDialogData_GetPaperSize, 2374).
+-define(wxPageSetupDialogData_GetPrintData, 2376).
+-define(wxPageSetupDialogData_IsOk, 2377).
+-define(wxPageSetupDialogData_SetDefaultInfo, 2378).
+-define(wxPageSetupDialogData_SetDefaultMinMargins, 2379).
+-define(wxPageSetupDialogData_SetMarginTopLeft, 2380).
+-define(wxPageSetupDialogData_SetMarginBottomRight, 2381).
+-define(wxPageSetupDialogData_SetMinMarginTopLeft, 2382).
+-define(wxPageSetupDialogData_SetMinMarginBottomRight, 2383).
+-define(wxPageSetupDialogData_SetPaperId, 2384).
+-define(wxPageSetupDialogData_SetPaperSize_1_1, 2385).
+-define(wxPageSetupDialogData_SetPaperSize_1_0, 2386).
+-define(wxPageSetupDialogData_SetPrintData, 2387).
+-define(wxPrintDialog_new_2_0, 2388).
+-define(wxPrintDialog_new_2_1, 2389).
+-define(wxPrintDialog_destruct, 2390).
+-define(wxPrintDialog_GetPrintDialogData, 2391).
+-define(wxPrintDialog_GetPrintDC, 2392).
+-define(wxPrintDialogData_new_0, 2393).
+-define(wxPrintDialogData_new_1_1, 2394).
+-define(wxPrintDialogData_new_1_0, 2395).
+-define(wxPrintDialogData_destruct, 2396).
+-define(wxPrintDialogData_EnableHelp, 2397).
+-define(wxPrintDialogData_EnablePageNumbers, 2398).
+-define(wxPrintDialogData_EnablePrintToFile, 2399).
+-define(wxPrintDialogData_EnableSelection, 2400).
+-define(wxPrintDialogData_GetAllPages, 2401).
+-define(wxPrintDialogData_GetCollate, 2402).
+-define(wxPrintDialogData_GetFromPage, 2403).
+-define(wxPrintDialogData_GetMaxPage, 2404).
+-define(wxPrintDialogData_GetMinPage, 2405).
+-define(wxPrintDialogData_GetNoCopies, 2406).
+-define(wxPrintDialogData_GetPrintData, 2407).
+-define(wxPrintDialogData_GetPrintToFile, 2408).
+-define(wxPrintDialogData_GetSelection, 2409).
+-define(wxPrintDialogData_GetToPage, 2410).
+-define(wxPrintDialogData_IsOk, 2411).
+-define(wxPrintDialogData_SetCollate, 2412).
+-define(wxPrintDialogData_SetFromPage, 2413).
+-define(wxPrintDialogData_SetMaxPage, 2414).
+-define(wxPrintDialogData_SetMinPage, 2415).
+-define(wxPrintDialogData_SetNoCopies, 2416).
+-define(wxPrintDialogData_SetPrintData, 2417).
+-define(wxPrintDialogData_SetPrintToFile, 2418).
+-define(wxPrintDialogData_SetSelection, 2419).
+-define(wxPrintDialogData_SetToPage, 2420).
+-define(wxPrintData_new_0, 2421).
+-define(wxPrintData_new_1, 2422).
+-define(wxPrintData_destruct, 2423).
+-define(wxPrintData_GetCollate, 2424).
+-define(wxPrintData_GetBin, 2425).
+-define(wxPrintData_GetColour, 2426).
+-define(wxPrintData_GetDuplex, 2427).
+-define(wxPrintData_GetNoCopies, 2428).
+-define(wxPrintData_GetOrientation, 2429).
+-define(wxPrintData_GetPaperId, 2430).
+-define(wxPrintData_GetPrinterName, 2431).
+-define(wxPrintData_GetQuality, 2432).
+-define(wxPrintData_IsOk, 2433).
+-define(wxPrintData_SetBin, 2434).
+-define(wxPrintData_SetCollate, 2435).
+-define(wxPrintData_SetColour, 2436).
+-define(wxPrintData_SetDuplex, 2437).
+-define(wxPrintData_SetNoCopies, 2438).
+-define(wxPrintData_SetOrientation, 2439).
+-define(wxPrintData_SetPaperId, 2440).
+-define(wxPrintData_SetPrinterName, 2441).
+-define(wxPrintData_SetQuality, 2442).
+-define(wxPrintPreview_new_2, 2445).
+-define(wxPrintPreview_new_3, 2446).
+-define(wxPrintPreview_destruct, 2448).
+-define(wxPrintPreview_GetCanvas, 2449).
+-define(wxPrintPreview_GetCurrentPage, 2450).
+-define(wxPrintPreview_GetFrame, 2451).
+-define(wxPrintPreview_GetMaxPage, 2452).
+-define(wxPrintPreview_GetMinPage, 2453).
+-define(wxPrintPreview_GetPrintout, 2454).
+-define(wxPrintPreview_GetPrintoutForPrinting, 2455).
+-define(wxPrintPreview_IsOk, 2456).
+-define(wxPrintPreview_PaintPage, 2457).
+-define(wxPrintPreview_Print, 2458).
+-define(wxPrintPreview_RenderPage, 2459).
+-define(wxPrintPreview_SetCanvas, 2460).
+-define(wxPrintPreview_SetCurrentPage, 2461).
+-define(wxPrintPreview_SetFrame, 2462).
+-define(wxPrintPreview_SetPrintout, 2463).
+-define(wxPrintPreview_SetZoom, 2464).
+-define(wxPreviewFrame_new, 2465).
+-define(wxPreviewFrame_destruct, 2466).
+-define(wxPreviewFrame_CreateControlBar, 2467).
+-define(wxPreviewFrame_CreateCanvas, 2468).
+-define(wxPreviewFrame_Initialize, 2469).
+-define(wxPreviewFrame_OnCloseWindow, 2470).
+-define(wxPreviewControlBar_new, 2471).
+-define(wxPreviewControlBar_destruct, 2472).
+-define(wxPreviewControlBar_CreateButtons, 2473).
+-define(wxPreviewControlBar_GetPrintPreview, 2474).
+-define(wxPreviewControlBar_GetZoomControl, 2475).
+-define(wxPreviewControlBar_SetZoomControl, 2476).
+-define(wxPrinter_new, 2478).
+-define(wxPrinter_CreateAbortWindow, 2479).
+-define(wxPrinter_GetAbort, 2480).
+-define(wxPrinter_GetLastError, 2481).
+-define(wxPrinter_GetPrintDialogData, 2482).
+-define(wxPrinter_Print, 2483).
+-define(wxPrinter_PrintDialog, 2484).
+-define(wxPrinter_ReportError, 2485).
+-define(wxPrinter_Setup, 2486).
+-define(wxPrinter_destroy, 2487).
+-define(wxXmlResource_new_1, 2488).
+-define(wxXmlResource_new_2, 2489).
+-define(wxXmlResource_destruct, 2490).
+-define(wxXmlResource_AttachUnknownControl, 2491).
+-define(wxXmlResource_ClearHandlers, 2492).
+-define(wxXmlResource_CompareVersion, 2493).
+-define(wxXmlResource_Get, 2494).
+-define(wxXmlResource_GetFlags, 2495).
+-define(wxXmlResource_GetVersion, 2496).
+-define(wxXmlResource_GetXRCID, 2497).
+-define(wxXmlResource_InitAllHandlers, 2498).
+-define(wxXmlResource_Load, 2499).
+-define(wxXmlResource_LoadBitmap, 2500).
+-define(wxXmlResource_LoadDialog_2, 2501).
+-define(wxXmlResource_LoadDialog_3, 2502).
+-define(wxXmlResource_LoadFrame_2, 2503).
+-define(wxXmlResource_LoadFrame_3, 2504).
+-define(wxXmlResource_LoadIcon, 2505).
+-define(wxXmlResource_LoadMenu, 2506).
+-define(wxXmlResource_LoadMenuBar_2, 2507).
+-define(wxXmlResource_LoadMenuBar_1, 2508).
+-define(wxXmlResource_LoadPanel_2, 2509).
+-define(wxXmlResource_LoadPanel_3, 2510).
+-define(wxXmlResource_LoadToolBar, 2511).
+-define(wxXmlResource_Set, 2512).
+-define(wxXmlResource_SetFlags, 2513).
+-define(wxXmlResource_Unload, 2514).
+-define(wxXmlResource_xrcctrl, 2515).
+-define(wxHtmlEasyPrinting_new, 2516).
+-define(wxHtmlEasyPrinting_destruct, 2517).
+-define(wxHtmlEasyPrinting_GetPrintData, 2518).
+-define(wxHtmlEasyPrinting_GetPageSetupData, 2519).
+-define(wxHtmlEasyPrinting_PreviewFile, 2520).
+-define(wxHtmlEasyPrinting_PreviewText, 2521).
+-define(wxHtmlEasyPrinting_PrintFile, 2522).
+-define(wxHtmlEasyPrinting_PrintText, 2523).
+-define(wxHtmlEasyPrinting_PageSetup, 2524).
+-define(wxHtmlEasyPrinting_SetFonts, 2525).
+-define(wxHtmlEasyPrinting_SetHeader, 2526).
+-define(wxHtmlEasyPrinting_SetFooter, 2527).
+-define(wxGLCanvas_new_2, 2529).
+-define(wxGLCanvas_new_3_1, 2530).
+-define(wxGLCanvas_new_3_0, 2531).
+-define(wxGLCanvas_GetContext, 2532).
+-define(wxGLCanvas_SetCurrent, 2534).
+-define(wxGLCanvas_SwapBuffers, 2535).
+-define(wxGLCanvas_destroy, 2536).
+-define(wxAuiManager_new, 2537).
+-define(wxAuiManager_destruct, 2538).
+-define(wxAuiManager_AddPane_2_1, 2539).
+-define(wxAuiManager_AddPane_3, 2540).
+-define(wxAuiManager_AddPane_2_0, 2541).
+-define(wxAuiManager_DetachPane, 2542).
+-define(wxAuiManager_GetAllPanes, 2543).
+-define(wxAuiManager_GetArtProvider, 2544).
+-define(wxAuiManager_GetDockSizeConstraint, 2545).
+-define(wxAuiManager_GetFlags, 2546).
+-define(wxAuiManager_GetManagedWindow, 2547).
+-define(wxAuiManager_GetManager, 2548).
+-define(wxAuiManager_GetPane_1_1, 2549).
+-define(wxAuiManager_GetPane_1_0, 2550).
+-define(wxAuiManager_HideHint, 2551).
+-define(wxAuiManager_InsertPane, 2552).
+-define(wxAuiManager_LoadPaneInfo, 2553).
+-define(wxAuiManager_LoadPerspective, 2554).
+-define(wxAuiManager_SavePaneInfo, 2555).
+-define(wxAuiManager_SavePerspective, 2556).
+-define(wxAuiManager_SetArtProvider, 2557).
+-define(wxAuiManager_SetDockSizeConstraint, 2558).
+-define(wxAuiManager_SetFlags, 2559).
+-define(wxAuiManager_SetManagedWindow, 2560).
+-define(wxAuiManager_ShowHint, 2561).
+-define(wxAuiManager_UnInit, 2562).
+-define(wxAuiManager_Update, 2563).
+-define(wxAuiPaneInfo_new_0, 2564).
+-define(wxAuiPaneInfo_new_1, 2565).
+-define(wxAuiPaneInfo_destruct, 2566).
+-define(wxAuiPaneInfo_BestSize_1, 2567).
+-define(wxAuiPaneInfo_BestSize_2, 2568).
+-define(wxAuiPaneInfo_Bottom, 2569).
+-define(wxAuiPaneInfo_BottomDockable, 2570).
+-define(wxAuiPaneInfo_Caption, 2571).
+-define(wxAuiPaneInfo_CaptionVisible, 2572).
+-define(wxAuiPaneInfo_Centre, 2573).
+-define(wxAuiPaneInfo_CentrePane, 2574).
+-define(wxAuiPaneInfo_CloseButton, 2575).
+-define(wxAuiPaneInfo_DefaultPane, 2576).
+-define(wxAuiPaneInfo_DestroyOnClose, 2577).
+-define(wxAuiPaneInfo_Direction, 2578).
+-define(wxAuiPaneInfo_Dock, 2579).
+-define(wxAuiPaneInfo_Dockable, 2580).
+-define(wxAuiPaneInfo_Fixed, 2581).
+-define(wxAuiPaneInfo_Float, 2582).
+-define(wxAuiPaneInfo_Floatable, 2583).
+-define(wxAuiPaneInfo_FloatingPosition_1, 2584).
+-define(wxAuiPaneInfo_FloatingPosition_2, 2585).
+-define(wxAuiPaneInfo_FloatingSize_1, 2586).
+-define(wxAuiPaneInfo_FloatingSize_2, 2587).
+-define(wxAuiPaneInfo_Gripper, 2588).
+-define(wxAuiPaneInfo_GripperTop, 2589).
+-define(wxAuiPaneInfo_HasBorder, 2590).
+-define(wxAuiPaneInfo_HasCaption, 2591).
+-define(wxAuiPaneInfo_HasCloseButton, 2592).
+-define(wxAuiPaneInfo_HasFlag, 2593).
+-define(wxAuiPaneInfo_HasGripper, 2594).
+-define(wxAuiPaneInfo_HasGripperTop, 2595).
+-define(wxAuiPaneInfo_HasMaximizeButton, 2596).
+-define(wxAuiPaneInfo_HasMinimizeButton, 2597).
+-define(wxAuiPaneInfo_HasPinButton, 2598).
+-define(wxAuiPaneInfo_Hide, 2599).
+-define(wxAuiPaneInfo_IsBottomDockable, 2600).
+-define(wxAuiPaneInfo_IsDocked, 2601).
+-define(wxAuiPaneInfo_IsFixed, 2602).
+-define(wxAuiPaneInfo_IsFloatable, 2603).
+-define(wxAuiPaneInfo_IsFloating, 2604).
+-define(wxAuiPaneInfo_IsLeftDockable, 2605).
+-define(wxAuiPaneInfo_IsMovable, 2606).
+-define(wxAuiPaneInfo_IsOk, 2607).
+-define(wxAuiPaneInfo_IsResizable, 2608).
+-define(wxAuiPaneInfo_IsRightDockable, 2609).
+-define(wxAuiPaneInfo_IsShown, 2610).
+-define(wxAuiPaneInfo_IsToolbar, 2611).
+-define(wxAuiPaneInfo_IsTopDockable, 2612).
+-define(wxAuiPaneInfo_Layer, 2613).
+-define(wxAuiPaneInfo_Left, 2614).
+-define(wxAuiPaneInfo_LeftDockable, 2615).
+-define(wxAuiPaneInfo_MaxSize_1, 2616).
+-define(wxAuiPaneInfo_MaxSize_2, 2617).
+-define(wxAuiPaneInfo_MaximizeButton, 2618).
+-define(wxAuiPaneInfo_MinSize_1, 2619).
+-define(wxAuiPaneInfo_MinSize_2, 2620).
+-define(wxAuiPaneInfo_MinimizeButton, 2621).
+-define(wxAuiPaneInfo_Movable, 2622).
+-define(wxAuiPaneInfo_Name, 2623).
+-define(wxAuiPaneInfo_PaneBorder, 2624).
+-define(wxAuiPaneInfo_PinButton, 2625).
+-define(wxAuiPaneInfo_Position, 2626).
+-define(wxAuiPaneInfo_Resizable, 2627).
+-define(wxAuiPaneInfo_Right, 2628).
+-define(wxAuiPaneInfo_RightDockable, 2629).
+-define(wxAuiPaneInfo_Row, 2630).
+-define(wxAuiPaneInfo_SafeSet, 2631).
+-define(wxAuiPaneInfo_SetFlag, 2632).
+-define(wxAuiPaneInfo_Show, 2633).
+-define(wxAuiPaneInfo_ToolbarPane, 2634).
+-define(wxAuiPaneInfo_Top, 2635).
+-define(wxAuiPaneInfo_TopDockable, 2636).
+-define(wxAuiPaneInfo_Window, 2637).
+-define(wxAuiNotebook_new_0, 2638).
+-define(wxAuiNotebook_new_2, 2639).
+-define(wxAuiNotebook_AddPage, 2640).
+-define(wxAuiNotebook_Create, 2641).
+-define(wxAuiNotebook_DeletePage, 2642).
+-define(wxAuiNotebook_GetArtProvider, 2643).
+-define(wxAuiNotebook_GetPage, 2644).
+-define(wxAuiNotebook_GetPageBitmap, 2645).
+-define(wxAuiNotebook_GetPageCount, 2646).
+-define(wxAuiNotebook_GetPageIndex, 2647).
+-define(wxAuiNotebook_GetPageText, 2648).
+-define(wxAuiNotebook_GetSelection, 2649).
+-define(wxAuiNotebook_InsertPage, 2650).
+-define(wxAuiNotebook_RemovePage, 2651).
+-define(wxAuiNotebook_SetArtProvider, 2652).
+-define(wxAuiNotebook_SetFont, 2653).
+-define(wxAuiNotebook_SetPageBitmap, 2654).
+-define(wxAuiNotebook_SetPageText, 2655).
+-define(wxAuiNotebook_SetSelection, 2656).
+-define(wxAuiNotebook_SetTabCtrlHeight, 2657).
+-define(wxAuiNotebook_SetUniformBitmapSize, 2658).
+-define(wxAuiNotebook_destroy, 2659).
+-define(wxMDIParentFrame_new_0, 2660).
+-define(wxMDIParentFrame_new_4, 2661).
+-define(wxMDIParentFrame_destruct, 2662).
+-define(wxMDIParentFrame_ActivateNext, 2663).
+-define(wxMDIParentFrame_ActivatePrevious, 2664).
+-define(wxMDIParentFrame_ArrangeIcons, 2665).
+-define(wxMDIParentFrame_Cascade, 2666).
+-define(wxMDIParentFrame_Create, 2667).
+-define(wxMDIParentFrame_GetActiveChild, 2668).
+-define(wxMDIParentFrame_GetClientWindow, 2669).
+-define(wxMDIParentFrame_Tile, 2670).
+-define(wxMDIChildFrame_new_0, 2671).
+-define(wxMDIChildFrame_new_4, 2672).
+-define(wxMDIChildFrame_destruct, 2673).
+-define(wxMDIChildFrame_Activate, 2674).
+-define(wxMDIChildFrame_Create, 2675).
+-define(wxMDIChildFrame_Maximize, 2676).
+-define(wxMDIChildFrame_Restore, 2677).
+-define(wxMDIClientWindow_new_0, 2678).
+-define(wxMDIClientWindow_new_2, 2679).
+-define(wxMDIClientWindow_destruct, 2680).
+-define(wxMDIClientWindow_CreateClient, 2681).
+-define(wxLayoutAlgorithm_new, 2682).
+-define(wxLayoutAlgorithm_LayoutFrame, 2683).
+-define(wxLayoutAlgorithm_LayoutMDIFrame, 2684).
+-define(wxLayoutAlgorithm_LayoutWindow, 2685).
+-define(wxLayoutAlgorithm_destroy, 2686).
+-define(wxEvent_GetId, 2687).
+-define(wxEvent_GetSkipped, 2688).
+-define(wxEvent_GetTimestamp, 2689).
+-define(wxEvent_IsCommandEvent, 2690).
+-define(wxEvent_ResumePropagation, 2691).
+-define(wxEvent_ShouldPropagate, 2692).
+-define(wxEvent_Skip, 2693).
+-define(wxEvent_StopPropagation, 2694).
+-define(wxCommandEvent_getClientData, 2695).
+-define(wxCommandEvent_GetExtraLong, 2696).
+-define(wxCommandEvent_GetInt, 2697).
+-define(wxCommandEvent_GetSelection, 2698).
+-define(wxCommandEvent_GetString, 2699).
+-define(wxCommandEvent_IsChecked, 2700).
+-define(wxCommandEvent_IsSelection, 2701).
+-define(wxCommandEvent_SetInt, 2702).
+-define(wxCommandEvent_SetString, 2703).
+-define(wxScrollEvent_GetOrientation, 2704).
+-define(wxScrollEvent_GetPosition, 2705).
+-define(wxScrollWinEvent_GetOrientation, 2706).
+-define(wxScrollWinEvent_GetPosition, 2707).
+-define(wxMouseEvent_AltDown, 2708).
+-define(wxMouseEvent_Button, 2709).
+-define(wxMouseEvent_ButtonDClick, 2710).
+-define(wxMouseEvent_ButtonDown, 2711).
+-define(wxMouseEvent_ButtonUp, 2712).
+-define(wxMouseEvent_CmdDown, 2713).
+-define(wxMouseEvent_ControlDown, 2714).
+-define(wxMouseEvent_Dragging, 2715).
+-define(wxMouseEvent_Entering, 2716).
+-define(wxMouseEvent_GetButton, 2717).
+-define(wxMouseEvent_GetPosition, 2720).
+-define(wxMouseEvent_GetLogicalPosition, 2721).
+-define(wxMouseEvent_GetLinesPerAction, 2722).
+-define(wxMouseEvent_GetWheelRotation, 2723).
+-define(wxMouseEvent_GetWheelDelta, 2724).
+-define(wxMouseEvent_GetX, 2725).
+-define(wxMouseEvent_GetY, 2726).
+-define(wxMouseEvent_IsButton, 2727).
+-define(wxMouseEvent_IsPageScroll, 2728).
+-define(wxMouseEvent_Leaving, 2729).
+-define(wxMouseEvent_LeftDClick, 2730).
+-define(wxMouseEvent_LeftDown, 2731).
+-define(wxMouseEvent_LeftIsDown, 2732).
+-define(wxMouseEvent_LeftUp, 2733).
+-define(wxMouseEvent_MetaDown, 2734).
+-define(wxMouseEvent_MiddleDClick, 2735).
+-define(wxMouseEvent_MiddleDown, 2736).
+-define(wxMouseEvent_MiddleIsDown, 2737).
+-define(wxMouseEvent_MiddleUp, 2738).
+-define(wxMouseEvent_Moving, 2739).
+-define(wxMouseEvent_RightDClick, 2740).
+-define(wxMouseEvent_RightDown, 2741).
+-define(wxMouseEvent_RightIsDown, 2742).
+-define(wxMouseEvent_RightUp, 2743).
+-define(wxMouseEvent_ShiftDown, 2744).
+-define(wxSetCursorEvent_GetCursor, 2745).
+-define(wxSetCursorEvent_GetX, 2746).
+-define(wxSetCursorEvent_GetY, 2747).
+-define(wxSetCursorEvent_HasCursor, 2748).
+-define(wxSetCursorEvent_SetCursor, 2749).
+-define(wxKeyEvent_AltDown, 2750).
+-define(wxKeyEvent_CmdDown, 2751).
+-define(wxKeyEvent_ControlDown, 2752).
+-define(wxKeyEvent_GetKeyCode, 2753).
+-define(wxKeyEvent_GetModifiers, 2754).
+-define(wxKeyEvent_GetPosition, 2757).
+-define(wxKeyEvent_GetRawKeyCode, 2758).
+-define(wxKeyEvent_GetRawKeyFlags, 2759).
+-define(wxKeyEvent_GetUnicodeKey, 2760).
+-define(wxKeyEvent_GetX, 2761).
+-define(wxKeyEvent_GetY, 2762).
+-define(wxKeyEvent_HasModifiers, 2763).
+-define(wxKeyEvent_MetaDown, 2764).
+-define(wxKeyEvent_ShiftDown, 2765).
+-define(wxSizeEvent_GetSize, 2766).
+-define(wxMoveEvent_GetPosition, 2767).
+-define(wxEraseEvent_GetDC, 2768).
+-define(wxFocusEvent_GetWindow, 2769).
+-define(wxChildFocusEvent_GetWindow, 2770).
+-define(wxMenuEvent_GetMenu, 2771).
+-define(wxMenuEvent_GetMenuId, 2772).
+-define(wxMenuEvent_IsPopup, 2773).
+-define(wxCloseEvent_CanVeto, 2774).
+-define(wxCloseEvent_GetLoggingOff, 2775).
+-define(wxCloseEvent_SetCanVeto, 2776).
+-define(wxCloseEvent_SetLoggingOff, 2777).
+-define(wxCloseEvent_Veto, 2778).
+-define(wxShowEvent_SetShow, 2779).
+-define(wxShowEvent_GetShow, 2780).
+-define(wxIconizeEvent_Iconized, 2781).
+-define(wxJoystickEvent_ButtonDown, 2782).
+-define(wxJoystickEvent_ButtonIsDown, 2783).
+-define(wxJoystickEvent_ButtonUp, 2784).
+-define(wxJoystickEvent_GetButtonChange, 2785).
+-define(wxJoystickEvent_GetButtonState, 2786).
+-define(wxJoystickEvent_GetJoystick, 2787).
+-define(wxJoystickEvent_GetPosition, 2788).
+-define(wxJoystickEvent_GetZPosition, 2789).
+-define(wxJoystickEvent_IsButton, 2790).
+-define(wxJoystickEvent_IsMove, 2791).
+-define(wxJoystickEvent_IsZMove, 2792).
+-define(wxUpdateUIEvent_CanUpdate, 2793).
+-define(wxUpdateUIEvent_Check, 2794).
+-define(wxUpdateUIEvent_Enable, 2795).
+-define(wxUpdateUIEvent_Show, 2796).
+-define(wxUpdateUIEvent_GetChecked, 2797).
+-define(wxUpdateUIEvent_GetEnabled, 2798).
+-define(wxUpdateUIEvent_GetShown, 2799).
+-define(wxUpdateUIEvent_GetSetChecked, 2800).
+-define(wxUpdateUIEvent_GetSetEnabled, 2801).
+-define(wxUpdateUIEvent_GetSetShown, 2802).
+-define(wxUpdateUIEvent_GetSetText, 2803).
+-define(wxUpdateUIEvent_GetText, 2804).
+-define(wxUpdateUIEvent_GetMode, 2805).
+-define(wxUpdateUIEvent_GetUpdateInterval, 2806).
+-define(wxUpdateUIEvent_ResetUpdateTime, 2807).
+-define(wxUpdateUIEvent_SetMode, 2808).
+-define(wxUpdateUIEvent_SetText, 2809).
+-define(wxUpdateUIEvent_SetUpdateInterval, 2810).
+-define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2811).
+-define(wxPaletteChangedEvent_SetChangedWindow, 2812).
+-define(wxPaletteChangedEvent_GetChangedWindow, 2813).
+-define(wxQueryNewPaletteEvent_SetPaletteRealized, 2814).
+-define(wxQueryNewPaletteEvent_GetPaletteRealized, 2815).
+-define(wxNavigationKeyEvent_GetDirection, 2816).
+-define(wxNavigationKeyEvent_SetDirection, 2817).
+-define(wxNavigationKeyEvent_IsWindowChange, 2818).
+-define(wxNavigationKeyEvent_SetWindowChange, 2819).
+-define(wxNavigationKeyEvent_IsFromTab, 2820).
+-define(wxNavigationKeyEvent_SetFromTab, 2821).
+-define(wxNavigationKeyEvent_GetCurrentFocus, 2822).
+-define(wxNavigationKeyEvent_SetCurrentFocus, 2823).
+-define(wxHelpEvent_GetOrigin, 2824).
+-define(wxHelpEvent_GetPosition, 2825).
+-define(wxHelpEvent_SetOrigin, 2826).
+-define(wxHelpEvent_SetPosition, 2827).
+-define(wxContextMenuEvent_GetPosition, 2828).
+-define(wxContextMenuEvent_SetPosition, 2829).
+-define(wxIdleEvent_CanSend, 2830).
+-define(wxIdleEvent_GetMode, 2831).
+-define(wxIdleEvent_RequestMore, 2832).
+-define(wxIdleEvent_MoreRequested, 2833).
+-define(wxIdleEvent_SetMode, 2834).
+-define(wxGridEvent_AltDown, 2835).
+-define(wxGridEvent_ControlDown, 2836).
+-define(wxGridEvent_GetCol, 2837).
+-define(wxGridEvent_GetPosition, 2838).
+-define(wxGridEvent_GetRow, 2839).
+-define(wxGridEvent_MetaDown, 2840).
+-define(wxGridEvent_Selecting, 2841).
+-define(wxGridEvent_ShiftDown, 2842).
+-define(wxNotifyEvent_Allow, 2843).
+-define(wxNotifyEvent_IsAllowed, 2844).
+-define(wxNotifyEvent_Veto, 2845).
+-define(wxSashEvent_GetEdge, 2846).
+-define(wxSashEvent_GetDragRect, 2847).
+-define(wxSashEvent_GetDragStatus, 2848).
+-define(wxListEvent_GetCacheFrom, 2849).
+-define(wxListEvent_GetCacheTo, 2850).
+-define(wxListEvent_GetKeyCode, 2851).
+-define(wxListEvent_GetIndex, 2852).
+-define(wxListEvent_GetColumn, 2853).
+-define(wxListEvent_GetPoint, 2854).
+-define(wxListEvent_GetLabel, 2855).
+-define(wxListEvent_GetText, 2856).
+-define(wxListEvent_GetImage, 2857).
+-define(wxListEvent_GetData, 2858).
+-define(wxListEvent_GetMask, 2859).
+-define(wxListEvent_GetItem, 2860).
+-define(wxListEvent_IsEditCancelled, 2861).
+-define(wxDateEvent_GetDate, 2862).
+-define(wxCalendarEvent_GetWeekDay, 2863).
+-define(wxFileDirPickerEvent_GetPath, 2864).
+-define(wxColourPickerEvent_GetColour, 2865).
+-define(wxFontPickerEvent_GetFont, 2866).
+-define(wxStyledTextEvent_GetPosition, 2867).
+-define(wxStyledTextEvent_GetKey, 2868).
+-define(wxStyledTextEvent_GetModifiers, 2869).
+-define(wxStyledTextEvent_GetModificationType, 2870).
+-define(wxStyledTextEvent_GetText, 2871).
+-define(wxStyledTextEvent_GetLength, 2872).
+-define(wxStyledTextEvent_GetLinesAdded, 2873).
+-define(wxStyledTextEvent_GetLine, 2874).
+-define(wxStyledTextEvent_GetFoldLevelNow, 2875).
+-define(wxStyledTextEvent_GetFoldLevelPrev, 2876).
+-define(wxStyledTextEvent_GetMargin, 2877).
+-define(wxStyledTextEvent_GetMessage, 2878).
+-define(wxStyledTextEvent_GetWParam, 2879).
+-define(wxStyledTextEvent_GetLParam, 2880).
+-define(wxStyledTextEvent_GetListType, 2881).
+-define(wxStyledTextEvent_GetX, 2882).
+-define(wxStyledTextEvent_GetY, 2883).
+-define(wxStyledTextEvent_GetDragText, 2884).
+-define(wxStyledTextEvent_GetDragAllowMove, 2885).
+-define(wxStyledTextEvent_GetDragResult, 2886).
+-define(wxStyledTextEvent_GetShift, 2887).
+-define(wxStyledTextEvent_GetControl, 2888).
+-define(wxStyledTextEvent_GetAlt, 2889).
+-define(utils_wxGetKeyState, 2890).
+-define(utils_wxGetMousePosition, 2891).
+-define(utils_wxGetMouseState, 2892).
+-define(utils_wxSetDetectableAutoRepeat, 2893).
+-define(utils_wxBell, 2894).
+-define(utils_wxFindMenuItemId, 2895).
+-define(utils_wxGenericFindWindowAtPoint, 2896).
+-define(utils_wxFindWindowAtPoint, 2897).
+-define(utils_wxBeginBusyCursor, 2898).
+-define(utils_wxEndBusyCursor, 2899).
+-define(utils_wxIsBusy, 2900).
+-define(utils_wxShutdown, 2901).
+-define(utils_wxShell, 2902).
+-define(utils_wxLaunchDefaultBrowser, 2903).
+-define(utils_wxGetEmailAddress, 2904).
+-define(utils_wxGetUserId, 2905).
+-define(utils_wxGetHomeDir, 2906).
+-define(utils_wxNewId, 2907).
+-define(utils_wxRegisterId, 2908).
+-define(utils_wxGetCurrentId, 2909).
+-define(utils_wxGetOsDescription, 2910).
+-define(utils_wxIsPlatformLittleEndian, 2911).
+-define(utils_wxIsPlatform64Bit, 2912).
+-define(wxPrintout_new, 2913).
+-define(wxPrintout_destruct, 2914).
+-define(wxPrintout_GetDC, 2915).
+-define(wxPrintout_GetPageSizeMM, 2916).
+-define(wxPrintout_GetPageSizePixels, 2917).
+-define(wxPrintout_GetPaperRectPixels, 2918).
+-define(wxPrintout_GetPPIPrinter, 2919).
+-define(wxPrintout_GetPPIScreen, 2920).
+-define(wxPrintout_GetTitle, 2921).
+-define(wxPrintout_IsPreview, 2922).
+-define(wxPrintout_FitThisSizeToPaper, 2923).
+-define(wxPrintout_FitThisSizeToPage, 2924).
+-define(wxPrintout_FitThisSizeToPageMargins, 2925).
+-define(wxPrintout_MapScreenSizeToPaper, 2926).
+-define(wxPrintout_MapScreenSizeToPage, 2927).
+-define(wxPrintout_MapScreenSizeToPageMargins, 2928).
+-define(wxPrintout_MapScreenSizeToDevice, 2929).
+-define(wxPrintout_GetLogicalPaperRect, 2930).
+-define(wxPrintout_GetLogicalPageRect, 2931).
+-define(wxPrintout_GetLogicalPageMarginsRect, 2932).
+-define(wxPrintout_SetLogicalOrigin, 2933).
+-define(wxPrintout_OffsetLogicalOrigin, 2934).
+-define(wxStyledTextCtrl_new_2, 2935).
+-define(wxStyledTextCtrl_new_0, 2936).
+-define(wxStyledTextCtrl_destruct, 2937).
+-define(wxStyledTextCtrl_Create, 2938).
+-define(wxStyledTextCtrl_AddText, 2939).
+-define(wxStyledTextCtrl_AddStyledText, 2940).
+-define(wxStyledTextCtrl_InsertText, 2941).
+-define(wxStyledTextCtrl_ClearAll, 2942).
+-define(wxStyledTextCtrl_ClearDocumentStyle, 2943).
+-define(wxStyledTextCtrl_GetLength, 2944).
+-define(wxStyledTextCtrl_GetCharAt, 2945).
+-define(wxStyledTextCtrl_GetCurrentPos, 2946).
+-define(wxStyledTextCtrl_GetAnchor, 2947).
+-define(wxStyledTextCtrl_GetStyleAt, 2948).
+-define(wxStyledTextCtrl_Redo, 2949).
+-define(wxStyledTextCtrl_SetUndoCollection, 2950).
+-define(wxStyledTextCtrl_SelectAll, 2951).
+-define(wxStyledTextCtrl_SetSavePoint, 2952).
+-define(wxStyledTextCtrl_GetStyledText, 2953).
+-define(wxStyledTextCtrl_CanRedo, 2954).
+-define(wxStyledTextCtrl_MarkerLineFromHandle, 2955).
+-define(wxStyledTextCtrl_MarkerDeleteHandle, 2956).
+-define(wxStyledTextCtrl_GetUndoCollection, 2957).
+-define(wxStyledTextCtrl_GetViewWhiteSpace, 2958).
+-define(wxStyledTextCtrl_SetViewWhiteSpace, 2959).
+-define(wxStyledTextCtrl_PositionFromPoint, 2960).
+-define(wxStyledTextCtrl_PositionFromPointClose, 2961).
+-define(wxStyledTextCtrl_GotoLine, 2962).
+-define(wxStyledTextCtrl_GotoPos, 2963).
+-define(wxStyledTextCtrl_SetAnchor, 2964).
+-define(wxStyledTextCtrl_GetCurLine, 2965).
+-define(wxStyledTextCtrl_GetEndStyled, 2966).
+-define(wxStyledTextCtrl_ConvertEOLs, 2967).
+-define(wxStyledTextCtrl_GetEOLMode, 2968).
+-define(wxStyledTextCtrl_SetEOLMode, 2969).
+-define(wxStyledTextCtrl_StartStyling, 2970).
+-define(wxStyledTextCtrl_SetStyling, 2971).
+-define(wxStyledTextCtrl_GetBufferedDraw, 2972).
+-define(wxStyledTextCtrl_SetBufferedDraw, 2973).
+-define(wxStyledTextCtrl_SetTabWidth, 2974).
+-define(wxStyledTextCtrl_GetTabWidth, 2975).
+-define(wxStyledTextCtrl_SetCodePage, 2976).
+-define(wxStyledTextCtrl_MarkerDefine, 2977).
+-define(wxStyledTextCtrl_MarkerSetForeground, 2978).
+-define(wxStyledTextCtrl_MarkerSetBackground, 2979).
+-define(wxStyledTextCtrl_MarkerAdd, 2980).
+-define(wxStyledTextCtrl_MarkerDelete, 2981).
+-define(wxStyledTextCtrl_MarkerDeleteAll, 2982).
+-define(wxStyledTextCtrl_MarkerGet, 2983).
+-define(wxStyledTextCtrl_MarkerNext, 2984).
+-define(wxStyledTextCtrl_MarkerPrevious, 2985).
+-define(wxStyledTextCtrl_MarkerDefineBitmap, 2986).
+-define(wxStyledTextCtrl_MarkerAddSet, 2987).
+-define(wxStyledTextCtrl_MarkerSetAlpha, 2988).
+-define(wxStyledTextCtrl_SetMarginType, 2989).
+-define(wxStyledTextCtrl_GetMarginType, 2990).
+-define(wxStyledTextCtrl_SetMarginWidth, 2991).
+-define(wxStyledTextCtrl_GetMarginWidth, 2992).
+-define(wxStyledTextCtrl_SetMarginMask, 2993).
+-define(wxStyledTextCtrl_GetMarginMask, 2994).
+-define(wxStyledTextCtrl_SetMarginSensitive, 2995).
+-define(wxStyledTextCtrl_GetMarginSensitive, 2996).
+-define(wxStyledTextCtrl_StyleClearAll, 2997).
+-define(wxStyledTextCtrl_StyleSetForeground, 2998).
+-define(wxStyledTextCtrl_StyleSetBackground, 2999).
+-define(wxStyledTextCtrl_StyleSetBold, 3000).
+-define(wxStyledTextCtrl_StyleSetItalic, 3001).
+-define(wxStyledTextCtrl_StyleSetSize, 3002).
+-define(wxStyledTextCtrl_StyleSetFaceName, 3003).
+-define(wxStyledTextCtrl_StyleSetEOLFilled, 3004).
+-define(wxStyledTextCtrl_StyleResetDefault, 3005).
+-define(wxStyledTextCtrl_StyleSetUnderline, 3006).
+-define(wxStyledTextCtrl_StyleSetCase, 3007).
+-define(wxStyledTextCtrl_StyleSetHotSpot, 3008).
+-define(wxStyledTextCtrl_SetSelForeground, 3009).
+-define(wxStyledTextCtrl_SetSelBackground, 3010).
+-define(wxStyledTextCtrl_GetSelAlpha, 3011).
+-define(wxStyledTextCtrl_SetSelAlpha, 3012).
+-define(wxStyledTextCtrl_SetCaretForeground, 3013).
+-define(wxStyledTextCtrl_CmdKeyAssign, 3014).
+-define(wxStyledTextCtrl_CmdKeyClear, 3015).
+-define(wxStyledTextCtrl_CmdKeyClearAll, 3016).
+-define(wxStyledTextCtrl_SetStyleBytes, 3017).
+-define(wxStyledTextCtrl_StyleSetVisible, 3018).
+-define(wxStyledTextCtrl_GetCaretPeriod, 3019).
+-define(wxStyledTextCtrl_SetCaretPeriod, 3020).
+-define(wxStyledTextCtrl_SetWordChars, 3021).
+-define(wxStyledTextCtrl_BeginUndoAction, 3022).
+-define(wxStyledTextCtrl_EndUndoAction, 3023).
+-define(wxStyledTextCtrl_IndicatorSetStyle, 3024).
+-define(wxStyledTextCtrl_IndicatorGetStyle, 3025).
+-define(wxStyledTextCtrl_IndicatorSetForeground, 3026).
+-define(wxStyledTextCtrl_IndicatorGetForeground, 3027).
+-define(wxStyledTextCtrl_SetWhitespaceForeground, 3028).
+-define(wxStyledTextCtrl_SetWhitespaceBackground, 3029).
+-define(wxStyledTextCtrl_GetStyleBits, 3030).
+-define(wxStyledTextCtrl_SetLineState, 3031).
+-define(wxStyledTextCtrl_GetLineState, 3032).
+-define(wxStyledTextCtrl_GetMaxLineState, 3033).
+-define(wxStyledTextCtrl_GetCaretLineVisible, 3034).
+-define(wxStyledTextCtrl_SetCaretLineVisible, 3035).
+-define(wxStyledTextCtrl_GetCaretLineBackground, 3036).
+-define(wxStyledTextCtrl_SetCaretLineBackground, 3037).
+-define(wxStyledTextCtrl_AutoCompShow, 3038).
+-define(wxStyledTextCtrl_AutoCompCancel, 3039).
+-define(wxStyledTextCtrl_AutoCompActive, 3040).
+-define(wxStyledTextCtrl_AutoCompPosStart, 3041).
+-define(wxStyledTextCtrl_AutoCompComplete, 3042).
+-define(wxStyledTextCtrl_AutoCompStops, 3043).
+-define(wxStyledTextCtrl_AutoCompSetSeparator, 3044).
+-define(wxStyledTextCtrl_AutoCompGetSeparator, 3045).
+-define(wxStyledTextCtrl_AutoCompSelect, 3046).
+-define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3047).
+-define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3048).
+-define(wxStyledTextCtrl_AutoCompSetFillUps, 3049).
+-define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3050).
+-define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3051).
+-define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3052).
+-define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3053).
+-define(wxStyledTextCtrl_UserListShow, 3054).
+-define(wxStyledTextCtrl_AutoCompSetAutoHide, 3055).
+-define(wxStyledTextCtrl_AutoCompGetAutoHide, 3056).
+-define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3057).
+-define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3058).
+-define(wxStyledTextCtrl_RegisterImage, 3059).
+-define(wxStyledTextCtrl_ClearRegisteredImages, 3060).
+-define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3061).
+-define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3062).
+-define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3063).
+-define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3064).
+-define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3065).
+-define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3066).
+-define(wxStyledTextCtrl_SetIndent, 3067).
+-define(wxStyledTextCtrl_GetIndent, 3068).
+-define(wxStyledTextCtrl_SetUseTabs, 3069).
+-define(wxStyledTextCtrl_GetUseTabs, 3070).
+-define(wxStyledTextCtrl_SetLineIndentation, 3071).
+-define(wxStyledTextCtrl_GetLineIndentation, 3072).
+-define(wxStyledTextCtrl_GetLineIndentPosition, 3073).
+-define(wxStyledTextCtrl_GetColumn, 3074).
+-define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3075).
+-define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3076).
+-define(wxStyledTextCtrl_SetIndentationGuides, 3077).
+-define(wxStyledTextCtrl_GetIndentationGuides, 3078).
+-define(wxStyledTextCtrl_SetHighlightGuide, 3079).
+-define(wxStyledTextCtrl_GetHighlightGuide, 3080).
+-define(wxStyledTextCtrl_GetLineEndPosition, 3081).
+-define(wxStyledTextCtrl_GetCodePage, 3082).
+-define(wxStyledTextCtrl_GetCaretForeground, 3083).
+-define(wxStyledTextCtrl_GetReadOnly, 3084).
+-define(wxStyledTextCtrl_SetCurrentPos, 3085).
+-define(wxStyledTextCtrl_SetSelectionStart, 3086).
+-define(wxStyledTextCtrl_GetSelectionStart, 3087).
+-define(wxStyledTextCtrl_SetSelectionEnd, 3088).
+-define(wxStyledTextCtrl_GetSelectionEnd, 3089).
+-define(wxStyledTextCtrl_SetPrintMagnification, 3090).
+-define(wxStyledTextCtrl_GetPrintMagnification, 3091).
+-define(wxStyledTextCtrl_SetPrintColourMode, 3092).
+-define(wxStyledTextCtrl_GetPrintColourMode, 3093).
+-define(wxStyledTextCtrl_FindText, 3094).
+-define(wxStyledTextCtrl_FormatRange, 3095).
+-define(wxStyledTextCtrl_GetFirstVisibleLine, 3096).
+-define(wxStyledTextCtrl_GetLine, 3097).
+-define(wxStyledTextCtrl_GetLineCount, 3098).
+-define(wxStyledTextCtrl_SetMarginLeft, 3099).
+-define(wxStyledTextCtrl_GetMarginLeft, 3100).
+-define(wxStyledTextCtrl_SetMarginRight, 3101).
+-define(wxStyledTextCtrl_GetMarginRight, 3102).
+-define(wxStyledTextCtrl_GetModify, 3103).
+-define(wxStyledTextCtrl_SetSelection, 3104).
+-define(wxStyledTextCtrl_GetSelectedText, 3105).
+-define(wxStyledTextCtrl_GetTextRange, 3106).
+-define(wxStyledTextCtrl_HideSelection, 3107).
+-define(wxStyledTextCtrl_LineFromPosition, 3108).
+-define(wxStyledTextCtrl_PositionFromLine, 3109).
+-define(wxStyledTextCtrl_LineScroll, 3110).
+-define(wxStyledTextCtrl_EnsureCaretVisible, 3111).
+-define(wxStyledTextCtrl_ReplaceSelection, 3112).
+-define(wxStyledTextCtrl_SetReadOnly, 3113).
+-define(wxStyledTextCtrl_CanPaste, 3114).
+-define(wxStyledTextCtrl_CanUndo, 3115).
+-define(wxStyledTextCtrl_EmptyUndoBuffer, 3116).
+-define(wxStyledTextCtrl_Undo, 3117).
+-define(wxStyledTextCtrl_Cut, 3118).
+-define(wxStyledTextCtrl_Copy, 3119).
+-define(wxStyledTextCtrl_Paste, 3120).
+-define(wxStyledTextCtrl_Clear, 3121).
+-define(wxStyledTextCtrl_SetText, 3122).
+-define(wxStyledTextCtrl_GetText, 3123).
+-define(wxStyledTextCtrl_GetTextLength, 3124).
+-define(wxStyledTextCtrl_GetOvertype, 3125).
+-define(wxStyledTextCtrl_SetCaretWidth, 3126).
+-define(wxStyledTextCtrl_GetCaretWidth, 3127).
+-define(wxStyledTextCtrl_SetTargetStart, 3128).
+-define(wxStyledTextCtrl_GetTargetStart, 3129).
+-define(wxStyledTextCtrl_SetTargetEnd, 3130).
+-define(wxStyledTextCtrl_GetTargetEnd, 3131).
+-define(wxStyledTextCtrl_ReplaceTarget, 3132).
+-define(wxStyledTextCtrl_SearchInTarget, 3133).
+-define(wxStyledTextCtrl_SetSearchFlags, 3134).
+-define(wxStyledTextCtrl_GetSearchFlags, 3135).
+-define(wxStyledTextCtrl_CallTipShow, 3136).
+-define(wxStyledTextCtrl_CallTipCancel, 3137).
+-define(wxStyledTextCtrl_CallTipActive, 3138).
+-define(wxStyledTextCtrl_CallTipPosAtStart, 3139).
+-define(wxStyledTextCtrl_CallTipSetHighlight, 3140).
+-define(wxStyledTextCtrl_CallTipSetBackground, 3141).
+-define(wxStyledTextCtrl_CallTipSetForeground, 3142).
+-define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3143).
+-define(wxStyledTextCtrl_CallTipUseStyle, 3144).
+-define(wxStyledTextCtrl_VisibleFromDocLine, 3145).
+-define(wxStyledTextCtrl_DocLineFromVisible, 3146).
+-define(wxStyledTextCtrl_WrapCount, 3147).
+-define(wxStyledTextCtrl_SetFoldLevel, 3148).
+-define(wxStyledTextCtrl_GetFoldLevel, 3149).
+-define(wxStyledTextCtrl_GetLastChild, 3150).
+-define(wxStyledTextCtrl_GetFoldParent, 3151).
+-define(wxStyledTextCtrl_ShowLines, 3152).
+-define(wxStyledTextCtrl_HideLines, 3153).
+-define(wxStyledTextCtrl_GetLineVisible, 3154).
+-define(wxStyledTextCtrl_SetFoldExpanded, 3155).
+-define(wxStyledTextCtrl_GetFoldExpanded, 3156).
+-define(wxStyledTextCtrl_ToggleFold, 3157).
+-define(wxStyledTextCtrl_EnsureVisible, 3158).
+-define(wxStyledTextCtrl_SetFoldFlags, 3159).
+-define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3160).
+-define(wxStyledTextCtrl_SetTabIndents, 3161).
+-define(wxStyledTextCtrl_GetTabIndents, 3162).
+-define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3163).
+-define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3164).
+-define(wxStyledTextCtrl_SetMouseDwellTime, 3165).
+-define(wxStyledTextCtrl_GetMouseDwellTime, 3166).
+-define(wxStyledTextCtrl_WordStartPosition, 3167).
+-define(wxStyledTextCtrl_WordEndPosition, 3168).
+-define(wxStyledTextCtrl_SetWrapMode, 3169).
+-define(wxStyledTextCtrl_GetWrapMode, 3170).
+-define(wxStyledTextCtrl_SetWrapVisualFlags, 3171).
+-define(wxStyledTextCtrl_GetWrapVisualFlags, 3172).
+-define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3173).
+-define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3174).
+-define(wxStyledTextCtrl_SetWrapStartIndent, 3175).
+-define(wxStyledTextCtrl_GetWrapStartIndent, 3176).
+-define(wxStyledTextCtrl_SetLayoutCache, 3177).
+-define(wxStyledTextCtrl_GetLayoutCache, 3178).
+-define(wxStyledTextCtrl_SetScrollWidth, 3179).
+-define(wxStyledTextCtrl_GetScrollWidth, 3180).
+-define(wxStyledTextCtrl_TextWidth, 3181).
+-define(wxStyledTextCtrl_GetEndAtLastLine, 3182).
+-define(wxStyledTextCtrl_TextHeight, 3183).
+-define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3184).
+-define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3185).
+-define(wxStyledTextCtrl_AppendText, 3186).
+-define(wxStyledTextCtrl_GetTwoPhaseDraw, 3187).
+-define(wxStyledTextCtrl_SetTwoPhaseDraw, 3188).
+-define(wxStyledTextCtrl_TargetFromSelection, 3189).
+-define(wxStyledTextCtrl_LinesJoin, 3190).
+-define(wxStyledTextCtrl_LinesSplit, 3191).
+-define(wxStyledTextCtrl_SetFoldMarginColour, 3192).
+-define(wxStyledTextCtrl_SetFoldMarginHiColour, 3193).
+-define(wxStyledTextCtrl_LineDown, 3194).
+-define(wxStyledTextCtrl_LineDownExtend, 3195).
+-define(wxStyledTextCtrl_LineUp, 3196).
+-define(wxStyledTextCtrl_LineUpExtend, 3197).
+-define(wxStyledTextCtrl_CharLeft, 3198).
+-define(wxStyledTextCtrl_CharLeftExtend, 3199).
+-define(wxStyledTextCtrl_CharRight, 3200).
+-define(wxStyledTextCtrl_CharRightExtend, 3201).
+-define(wxStyledTextCtrl_WordLeft, 3202).
+-define(wxStyledTextCtrl_WordLeftExtend, 3203).
+-define(wxStyledTextCtrl_WordRight, 3204).
+-define(wxStyledTextCtrl_WordRightExtend, 3205).
+-define(wxStyledTextCtrl_Home, 3206).
+-define(wxStyledTextCtrl_HomeExtend, 3207).
+-define(wxStyledTextCtrl_LineEnd, 3208).
+-define(wxStyledTextCtrl_LineEndExtend, 3209).
+-define(wxStyledTextCtrl_DocumentStart, 3210).
+-define(wxStyledTextCtrl_DocumentStartExtend, 3211).
+-define(wxStyledTextCtrl_DocumentEnd, 3212).
+-define(wxStyledTextCtrl_DocumentEndExtend, 3213).
+-define(wxStyledTextCtrl_PageUp, 3214).
+-define(wxStyledTextCtrl_PageUpExtend, 3215).
+-define(wxStyledTextCtrl_PageDown, 3216).
+-define(wxStyledTextCtrl_PageDownExtend, 3217).
+-define(wxStyledTextCtrl_EditToggleOvertype, 3218).
+-define(wxStyledTextCtrl_Cancel, 3219).
+-define(wxStyledTextCtrl_DeleteBack, 3220).
+-define(wxStyledTextCtrl_Tab, 3221).
+-define(wxStyledTextCtrl_BackTab, 3222).
+-define(wxStyledTextCtrl_NewLine, 3223).
+-define(wxStyledTextCtrl_FormFeed, 3224).
+-define(wxStyledTextCtrl_VCHome, 3225).
+-define(wxStyledTextCtrl_VCHomeExtend, 3226).
+-define(wxStyledTextCtrl_ZoomIn, 3227).
+-define(wxStyledTextCtrl_ZoomOut, 3228).
+-define(wxStyledTextCtrl_DelWordLeft, 3229).
+-define(wxStyledTextCtrl_DelWordRight, 3230).
+-define(wxStyledTextCtrl_LineCut, 3231).
+-define(wxStyledTextCtrl_LineDelete, 3232).
+-define(wxStyledTextCtrl_LineTranspose, 3233).
+-define(wxStyledTextCtrl_LineDuplicate, 3234).
+-define(wxStyledTextCtrl_LowerCase, 3235).
+-define(wxStyledTextCtrl_UpperCase, 3236).
+-define(wxStyledTextCtrl_LineScrollDown, 3237).
+-define(wxStyledTextCtrl_LineScrollUp, 3238).
+-define(wxStyledTextCtrl_DeleteBackNotLine, 3239).
+-define(wxStyledTextCtrl_HomeDisplay, 3240).
+-define(wxStyledTextCtrl_HomeDisplayExtend, 3241).
+-define(wxStyledTextCtrl_LineEndDisplay, 3242).
+-define(wxStyledTextCtrl_LineEndDisplayExtend, 3243).
+-define(wxStyledTextCtrl_HomeWrapExtend, 3244).
+-define(wxStyledTextCtrl_LineEndWrap, 3245).
+-define(wxStyledTextCtrl_LineEndWrapExtend, 3246).
+-define(wxStyledTextCtrl_VCHomeWrap, 3247).
+-define(wxStyledTextCtrl_VCHomeWrapExtend, 3248).
+-define(wxStyledTextCtrl_LineCopy, 3249).
+-define(wxStyledTextCtrl_MoveCaretInsideView, 3250).
+-define(wxStyledTextCtrl_LineLength, 3251).
+-define(wxStyledTextCtrl_BraceHighlight, 3252).
+-define(wxStyledTextCtrl_BraceBadLight, 3253).
+-define(wxStyledTextCtrl_BraceMatch, 3254).
+-define(wxStyledTextCtrl_GetViewEOL, 3255).
+-define(wxStyledTextCtrl_SetViewEOL, 3256).
+-define(wxStyledTextCtrl_SetModEventMask, 3257).
+-define(wxStyledTextCtrl_GetEdgeColumn, 3258).
+-define(wxStyledTextCtrl_SetEdgeColumn, 3259).
+-define(wxStyledTextCtrl_GetEdgeMode, 3260).
+-define(wxStyledTextCtrl_GetEdgeColour, 3261).
+-define(wxStyledTextCtrl_SetEdgeColour, 3262).
+-define(wxStyledTextCtrl_SearchAnchor, 3263).
+-define(wxStyledTextCtrl_SearchNext, 3264).
+-define(wxStyledTextCtrl_SearchPrev, 3265).
+-define(wxStyledTextCtrl_LinesOnScreen, 3266).
+-define(wxStyledTextCtrl_UsePopUp, 3267).
+-define(wxStyledTextCtrl_SelectionIsRectangle, 3268).
+-define(wxStyledTextCtrl_SetZoom, 3269).
+-define(wxStyledTextCtrl_GetZoom, 3270).
+-define(wxStyledTextCtrl_GetModEventMask, 3271).
+-define(wxStyledTextCtrl_SetSTCFocus, 3272).
+-define(wxStyledTextCtrl_GetSTCFocus, 3273).
+-define(wxStyledTextCtrl_SetStatus, 3274).
+-define(wxStyledTextCtrl_GetStatus, 3275).
+-define(wxStyledTextCtrl_SetMouseDownCaptures, 3276).
+-define(wxStyledTextCtrl_GetMouseDownCaptures, 3277).
+-define(wxStyledTextCtrl_SetSTCCursor, 3278).
+-define(wxStyledTextCtrl_GetSTCCursor, 3279).
+-define(wxStyledTextCtrl_SetControlCharSymbol, 3280).
+-define(wxStyledTextCtrl_GetControlCharSymbol, 3281).
+-define(wxStyledTextCtrl_WordPartLeft, 3282).
+-define(wxStyledTextCtrl_WordPartLeftExtend, 3283).
+-define(wxStyledTextCtrl_WordPartRight, 3284).
+-define(wxStyledTextCtrl_WordPartRightExtend, 3285).
+-define(wxStyledTextCtrl_SetVisiblePolicy, 3286).
+-define(wxStyledTextCtrl_DelLineLeft, 3287).
+-define(wxStyledTextCtrl_DelLineRight, 3288).
+-define(wxStyledTextCtrl_GetXOffset, 3289).
+-define(wxStyledTextCtrl_ChooseCaretX, 3290).
+-define(wxStyledTextCtrl_SetXCaretPolicy, 3291).
+-define(wxStyledTextCtrl_SetYCaretPolicy, 3292).
+-define(wxStyledTextCtrl_GetPrintWrapMode, 3293).
+-define(wxStyledTextCtrl_SetHotspotActiveForeground, 3294).
+-define(wxStyledTextCtrl_SetHotspotActiveBackground, 3295).
+-define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3296).
+-define(wxStyledTextCtrl_SetHotspotSingleLine, 3297).
+-define(wxStyledTextCtrl_ParaDownExtend, 3298).
+-define(wxStyledTextCtrl_ParaUp, 3299).
+-define(wxStyledTextCtrl_ParaUpExtend, 3300).
+-define(wxStyledTextCtrl_PositionBefore, 3301).
+-define(wxStyledTextCtrl_PositionAfter, 3302).
+-define(wxStyledTextCtrl_CopyRange, 3303).
+-define(wxStyledTextCtrl_CopyText, 3304).
+-define(wxStyledTextCtrl_SetSelectionMode, 3305).
+-define(wxStyledTextCtrl_GetSelectionMode, 3306).
+-define(wxStyledTextCtrl_LineDownRectExtend, 3307).
+-define(wxStyledTextCtrl_LineUpRectExtend, 3308).
+-define(wxStyledTextCtrl_CharLeftRectExtend, 3309).
+-define(wxStyledTextCtrl_CharRightRectExtend, 3310).
+-define(wxStyledTextCtrl_HomeRectExtend, 3311).
+-define(wxStyledTextCtrl_VCHomeRectExtend, 3312).
+-define(wxStyledTextCtrl_LineEndRectExtend, 3313).
+-define(wxStyledTextCtrl_PageUpRectExtend, 3314).
+-define(wxStyledTextCtrl_PageDownRectExtend, 3315).
+-define(wxStyledTextCtrl_StutteredPageUp, 3316).
+-define(wxStyledTextCtrl_StutteredPageUpExtend, 3317).
+-define(wxStyledTextCtrl_StutteredPageDown, 3318).
+-define(wxStyledTextCtrl_StutteredPageDownExtend, 3319).
+-define(wxStyledTextCtrl_WordLeftEnd, 3320).
+-define(wxStyledTextCtrl_WordLeftEndExtend, 3321).
+-define(wxStyledTextCtrl_WordRightEnd, 3322).
+-define(wxStyledTextCtrl_WordRightEndExtend, 3323).
+-define(wxStyledTextCtrl_SetWhitespaceChars, 3324).
+-define(wxStyledTextCtrl_SetCharsDefault, 3325).
+-define(wxStyledTextCtrl_AutoCompGetCurrent, 3326).
+-define(wxStyledTextCtrl_Allocate, 3327).
+-define(wxStyledTextCtrl_FindColumn, 3328).
+-define(wxStyledTextCtrl_GetCaretSticky, 3329).
+-define(wxStyledTextCtrl_SetCaretSticky, 3330).
+-define(wxStyledTextCtrl_ToggleCaretSticky, 3331).
+-define(wxStyledTextCtrl_SetPasteConvertEndings, 3332).
+-define(wxStyledTextCtrl_GetPasteConvertEndings, 3333).
+-define(wxStyledTextCtrl_SelectionDuplicate, 3334).
+-define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3335).
+-define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3336).
+-define(wxStyledTextCtrl_StartRecord, 3337).
+-define(wxStyledTextCtrl_StopRecord, 3338).
+-define(wxStyledTextCtrl_SetLexer, 3339).
+-define(wxStyledTextCtrl_GetLexer, 3340).
+-define(wxStyledTextCtrl_Colourise, 3341).
+-define(wxStyledTextCtrl_SetProperty, 3342).
+-define(wxStyledTextCtrl_SetKeyWords, 3343).
+-define(wxStyledTextCtrl_SetLexerLanguage, 3344).
+-define(wxStyledTextCtrl_GetProperty, 3345).
+-define(wxStyledTextCtrl_GetStyleBitsNeeded, 3346).
+-define(wxStyledTextCtrl_GetCurrentLine, 3347).
+-define(wxStyledTextCtrl_StyleSetSpec, 3348).
+-define(wxStyledTextCtrl_StyleSetFont, 3349).
+-define(wxStyledTextCtrl_StyleSetFontAttr, 3350).
+-define(wxStyledTextCtrl_StyleSetCharacterSet, 3351).
+-define(wxStyledTextCtrl_StyleSetFontEncoding, 3352).
+-define(wxStyledTextCtrl_CmdKeyExecute, 3353).
+-define(wxStyledTextCtrl_SetMargins, 3354).
+-define(wxStyledTextCtrl_GetSelection, 3355).
+-define(wxStyledTextCtrl_PointFromPosition, 3356).
+-define(wxStyledTextCtrl_ScrollToLine, 3357).
+-define(wxStyledTextCtrl_ScrollToColumn, 3358).
+-define(wxStyledTextCtrl_SendMsg, 3359).
+-define(wxStyledTextCtrl_SetVScrollBar, 3360).
+-define(wxStyledTextCtrl_SetHScrollBar, 3361).
+-define(wxStyledTextCtrl_GetLastKeydownProcessed, 3362).
+-define(wxStyledTextCtrl_SetLastKeydownProcessed, 3363).
+-define(wxStyledTextCtrl_SaveFile, 3364).
+-define(wxStyledTextCtrl_LoadFile, 3365).
+-define(wxStyledTextCtrl_DoDragOver, 3366).
+-define(wxStyledTextCtrl_DoDropText, 3367).
+-define(wxStyledTextCtrl_GetUseAntiAliasing, 3368).
+-define(wxStyledTextCtrl_AddTextRaw, 3369).
+-define(wxStyledTextCtrl_InsertTextRaw, 3370).
+-define(wxStyledTextCtrl_GetCurLineRaw, 3371).
+-define(wxStyledTextCtrl_GetLineRaw, 3372).
+-define(wxStyledTextCtrl_GetSelectedTextRaw, 3373).
+-define(wxStyledTextCtrl_GetTextRangeRaw, 3374).
+-define(wxStyledTextCtrl_SetTextRaw, 3375).
+-define(wxStyledTextCtrl_GetTextRaw, 3376).
+-define(wxStyledTextCtrl_AppendTextRaw, 3377).
+-define(wxArtProvider_GetBitmap, 3378).
+-define(wxArtProvider_GetIcon, 3379).
+-define(wxTreeEvent_GetKeyCode, 3380).
+-define(wxTreeEvent_GetItem, 3381).
+-define(wxTreeEvent_GetKeyEvent, 3382).
+-define(wxTreeEvent_GetLabel, 3383).
+-define(wxTreeEvent_GetOldItem, 3384).
+-define(wxTreeEvent_GetPoint, 3385).
+-define(wxTreeEvent_IsEditCancelled, 3386).
+-define(wxTreeEvent_SetToolTip, 3387).
+-define(wxNotebookEvent_GetOldSelection, 3388).
+-define(wxNotebookEvent_GetSelection, 3389).
+-define(wxNotebookEvent_SetOldSelection, 3390).
+-define(wxNotebookEvent_SetSelection, 3391).
+-define(wxFileDataObject_new, 3392).
+-define(wxFileDataObject_AddFile, 3393).
+-define(wxFileDataObject_GetFilenames, 3394).
+-define(wxFileDataObject_destroy, 3395).
+-define(wxTextDataObject_new, 3396).
+-define(wxTextDataObject_GetTextLength, 3397).
+-define(wxTextDataObject_GetText, 3398).
+-define(wxTextDataObject_SetText, 3399).
+-define(wxTextDataObject_destroy, 3400).
+-define(wxBitmapDataObject_new_1_1, 3401).
+-define(wxBitmapDataObject_new_1_0, 3402).
+-define(wxBitmapDataObject_GetBitmap, 3403).
+-define(wxBitmapDataObject_SetBitmap, 3404).
+-define(wxBitmapDataObject_destroy, 3405).
+-define(wxClipboard_new, 3407).
+-define(wxClipboard_destruct, 3408).
+-define(wxClipboard_AddData, 3409).
+-define(wxClipboard_Clear, 3410).
+-define(wxClipboard_Close, 3411).
+-define(wxClipboard_Flush, 3412).
+-define(wxClipboard_GetData, 3413).
+-define(wxClipboard_IsOpened, 3414).
+-define(wxClipboard_Open, 3415).
+-define(wxClipboard_SetData, 3416).
+-define(wxClipboard_UsePrimarySelection, 3418).
+-define(wxClipboard_IsSupported, 3419).
+-define(wxClipboard_Get, 3420).
+-define(wxSpinEvent_GetPosition, 3421).
+-define(wxSpinEvent_SetPosition, 3422).
+-define(wxSplitterWindow_new_0, 3423).
+-define(wxSplitterWindow_new_2, 3424).
+-define(wxSplitterWindow_destruct, 3425).
+-define(wxSplitterWindow_Create, 3426).
+-define(wxSplitterWindow_GetMinimumPaneSize, 3427).
+-define(wxSplitterWindow_GetSashGravity, 3428).
+-define(wxSplitterWindow_GetSashPosition, 3429).
+-define(wxSplitterWindow_GetSplitMode, 3430).
+-define(wxSplitterWindow_GetWindow1, 3431).
+-define(wxSplitterWindow_GetWindow2, 3432).
+-define(wxSplitterWindow_Initialize, 3433).
+-define(wxSplitterWindow_IsSplit, 3434).
+-define(wxSplitterWindow_ReplaceWindow, 3435).
+-define(wxSplitterWindow_SetSashGravity, 3436).
+-define(wxSplitterWindow_SetSashPosition, 3437).
+-define(wxSplitterWindow_SetSashSize, 3438).
+-define(wxSplitterWindow_SetMinimumPaneSize, 3439).
+-define(wxSplitterWindow_SetSplitMode, 3440).
+-define(wxSplitterWindow_SplitHorizontally, 3441).
+-define(wxSplitterWindow_SplitVertically, 3442).
+-define(wxSplitterWindow_Unsplit, 3443).
+-define(wxSplitterWindow_UpdateSize, 3444).
+-define(wxSplitterEvent_GetSashPosition, 3445).
+-define(wxSplitterEvent_GetX, 3446).
+-define(wxSplitterEvent_GetY, 3447).
+-define(wxSplitterEvent_GetWindowBeingRemoved, 3448).
+-define(wxSplitterEvent_SetSashPosition, 3449).
+-define(wxHtmlWindow_new_0, 3450).
+-define(wxHtmlWindow_new_2, 3451).
+-define(wxHtmlWindow_AppendToPage, 3452).
+-define(wxHtmlWindow_GetOpenedAnchor, 3453).
+-define(wxHtmlWindow_GetOpenedPage, 3454).
+-define(wxHtmlWindow_GetOpenedPageTitle, 3455).
+-define(wxHtmlWindow_GetRelatedFrame, 3456).
+-define(wxHtmlWindow_HistoryBack, 3457).
+-define(wxHtmlWindow_HistoryCanBack, 3458).
+-define(wxHtmlWindow_HistoryCanForward, 3459).
+-define(wxHtmlWindow_HistoryClear, 3460).
+-define(wxHtmlWindow_HistoryForward, 3461).
+-define(wxHtmlWindow_LoadFile, 3462).
+-define(wxHtmlWindow_LoadPage, 3463).
+-define(wxHtmlWindow_SelectAll, 3464).
+-define(wxHtmlWindow_SelectionToText, 3465).
+-define(wxHtmlWindow_SelectLine, 3466).
+-define(wxHtmlWindow_SelectWord, 3467).
+-define(wxHtmlWindow_SetBorders, 3468).
+-define(wxHtmlWindow_SetFonts, 3469).
+-define(wxHtmlWindow_SetPage, 3470).
+-define(wxHtmlWindow_SetRelatedFrame, 3471).
+-define(wxHtmlWindow_SetRelatedStatusBar, 3472).
+-define(wxHtmlWindow_ToText, 3473).
+-define(wxHtmlWindow_destroy, 3474).
+-define(wxHtmlLinkEvent_GetLinkInfo, 3475).
+-define(wxAuiNotebookEvent_SetSelection, 3476).
+-define(wxAuiNotebookEvent_GetSelection, 3477).
+-define(wxAuiNotebookEvent_SetOldSelection, 3478).
+-define(wxAuiNotebookEvent_GetOldSelection, 3479).
+-define(wxAuiNotebookEvent_SetDragSource, 3480).
+-define(wxAuiNotebookEvent_GetDragSource, 3481).
+-define(wxAuiManagerEvent_SetManager, 3482).
+-define(wxAuiManagerEvent_GetManager, 3483).
+-define(wxAuiManagerEvent_SetPane, 3484).
+-define(wxAuiManagerEvent_GetPane, 3485).
+-define(wxAuiManagerEvent_SetButton, 3486).
+-define(wxAuiManagerEvent_GetButton, 3487).
+-define(wxAuiManagerEvent_SetDC, 3488).
+-define(wxAuiManagerEvent_GetDC, 3489).
+-define(wxAuiManagerEvent_Veto, 3490).
+-define(wxAuiManagerEvent_GetVeto, 3491).
+-define(wxAuiManagerEvent_SetCanVeto, 3492).
+-define(wxAuiManagerEvent_CanVeto, 3493).
+-define(wxLogNull_new, 3494).
+-define(wxLogNull_destroy, 3495).
diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl
index cedbd1ef19..ddb491be6c 100644
--- a/lib/wx/test/wx_class_SUITE.erl
+++ b/lib/wx/test/wx_class_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%%-------------------------------------------------------------------
%%% File : wx_class_SUITE.erl
@@ -113,12 +113,14 @@ treeCtrl(Config) ->
Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
Panel = wxPanel:new(Frame, []),
Tree = ?mt(wxTreeCtrl,wxTreeCtrl:new(Panel, [{style , ?wxTR_HAS_BUTTONS}])),
- Root = ?mt(wxTreeItemId, wxTreeCtrl:addRoot(Tree, "Root", [])),
- Item1 = ?mt(wxTreeItemId, wxTreeCtrl:appendItem(Tree, Root, "Item1", [])),
- ?m(ok, wxTreeCtrl:setItemData(Tree, Item1, {data, item1})),
- Item2 = ?mt(wxTreeItemId, wxTreeCtrl:appendItem(Tree, Root, "Item2", [])),
- ?m(ok, wxTreeCtrl:setItemData(Tree, Item2, {data, item2})),
- Item3 = ?mt(wxTreeItemId, wxTreeCtrl:appendItem(Tree, Root, "Item3", [])),
+ Root = wxTreeCtrl:addRoot(Tree, "Root", []),
+ ?m(true, is_integer(Root)),
+ Item1 = wxTreeCtrl:appendItem(Tree, Root, "Item1", []),
+ ?m(true, is_integer(Item1)),
+ ?m(ok, wxTreeCtrl:setItemData(Tree, Item1, {data, item1})),
+ Item2 = wxTreeCtrl:appendItem(Tree, Root, "Item2", []),
+ ?m(ok, wxTreeCtrl:setItemData(Tree, Item2, {data, item2})),
+ Item3 = wxTreeCtrl:appendItem(Tree, Root, "Item3", []),
?m(ok, wxTreeCtrl:setItemData(Tree, Item3, {data, item3})),
Sizer = wxBoxSizer:new(?wxVERTICAL),
@@ -373,7 +375,7 @@ radioBox(Config) ->
io:format("TrSortRadioBox ~p ~n", [TrSortRadioBox]),
%% If I uncomment any of these lines, it will crash
- ?m(_, catch wxControlWithItems:setClientData(TrSortRadioBox, 0, timestamp)),
+ io:format("~p~n", [catch wxControlWithItems:setClientData(TrSortRadioBox, 0, timestamp)]),
%?m(_, wxListBox:append(TrSortRadioBox, "Session Id", session_id)),
%?m(_, wxListBox:insert(TrSortRadioBox, "Session Id", 0, session_id)),
diff --git a/lib/wx/test/wx_xtra_SUITE.erl b/lib/wx/test/wx_xtra_SUITE.erl
index 2ce1d18039..d5888bbf94 100644
--- a/lib/wx/test/wx_xtra_SUITE.erl
+++ b/lib/wx/test/wx_xtra_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%%-------------------------------------------------------------------
%%% File : wx_basic_SUITE.erl
@@ -51,7 +51,8 @@ all(suite) ->
[
destroy_app,
multiple_add_in_sizer,
- app_dies
+ app_dies,
+ menu_item_debug
].
%% The test cases
@@ -68,10 +69,11 @@ destroy_app_test(N) when N > 0 ->
Wx = ?mr(wx_ref, wx:new()),
Frame = wxFrame:new(Wx, 1, "Destroy"),
?m(ok, wxFrame:destroy(Frame)),
- wx:destroy(),
receive
Msg -> Msg
- after 150 -> destroy_app_test(N-1)
+ after 150 ->
+ wx:destroy(),
+ destroy_app_test(N-1)
end;
destroy_app_test(_) ->
receive
@@ -174,3 +176,57 @@ multiple_add_in_sizer(Config) ->
wxWindow:show(Frame),
wx_test_lib:wx_destroy(Frame, Config).
+menu_item_debug(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+menu_item_debug(Config) ->
+ %% Debugging a menu entry problem
+ %% Run it with: lists:map(fun(_) -> [{0,{ok,_,_}}] = wxt:t() end, lists:seq(1,50)), ok.
+ Wx = wx:new(),
+ wx:debug(trace),
+ Frame = wxFrame:new(Wx, -1, "Button Fix"),
+ wxFrame:connect(Frame, close_window),
+
+ wxPanel:new(Frame),
+ create_menus(Frame),
+ wxWindow:show(Frame),
+ wx_test_lib:wx_destroy(Frame,Config).
+
+
+create_menus(Frame) ->
+ MenuBar = ?mt(wxMenuBar, wxMenuBar:new()),
+ File = ?mt(wxMenu, wxMenu:new([])),
+ Help = ?mt(wxMenu, wxMenu:new([])),
+
+ ?mt(wxMenuItem, wxMenu:append(Help, ?wxID_ABOUT, "&About", [])),
+ ?mt(wxMenuItem, wxMenu:append(Help, ?wxID_HELP, "&Help", [])),
+ ?mt(wxMenuItem, wxMenu:append(File, ?wxID_EXIT, "Exit", [])),
+ T1 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T1, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(100, 120)],
+ T2 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T2, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(200, 220)],
+ T3 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T3, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(300, 320)],
+ T4 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T4, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(400, 420)],
+ T5 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T5, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(500, 520)],
+ T6 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T6, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(600, 620)],
+
+ ?m(ok,wxFrame:connect(Frame, command_menu_selected)),
+ ?m(true, wxMenuBar:append(MenuBar, File, "&File")),
+ ?m(true, wxMenuBar:append(MenuBar, Help, "&Help")),
+ ?m(true, wxMenuBar:append(MenuBar, T1, "T1")),
+ ?m(true, wxMenuBar:append(MenuBar, T2, "T2")),
+ ?m(true, wxMenuBar:append(MenuBar, T3, "T3")),
+ ?m(true, wxMenuBar:append(MenuBar, T4, "T4")),
+ ?m(true, wxMenuBar:append(MenuBar, T5, "T5")),
+ ?m(true, wxMenuBar:append(MenuBar, T6, "T6")),
+
+
+ ?m(ok, wxFrame:setMenuBar(Frame,MenuBar)).
diff --git a/lib/wx/test/wxt.erl b/lib/wx/test/wxt.erl
index a346a6bdb8..1f5b1cc3b1 100644
--- a/lib/wx/test/wxt.erl
+++ b/lib/wx/test/wxt.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%%-------------------------------------------------------------------
%%% File : wxt.erl
@@ -58,16 +58,16 @@ user(Mod,Tc) when is_atom(Tc) ->
%% Resolves the name of test suites and test cases
%% according to the alias definitions. Single atoms
%% are assumed to be the name of a test suite.
-resolve(Suite0) when atom(Suite0) ->
+resolve(Suite0) when is_atom(Suite0) ->
case alias(Suite0) of
- Suite when atom(Suite) ->
+ Suite when is_atom(Suite) ->
{Suite, all};
{Suite, Case} ->
{Suite, Case}
end;
-resolve({Suite0, Case}) when atom(Suite0), atom(Case) ->
+resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) ->
case alias(Suite0) of
- Suite when atom(Suite) ->
+ Suite when is_atom(Suite) ->
{Suite, Case};
{Suite, Case2} ->
{Suite, Case2}
diff --git a/lib/xmerl/doc/src/Makefile b/lib/xmerl/doc/src/Makefile
index e26e77eb96..100a2feb0a 100644
--- a/lib/xmerl/doc/src/Makefile
+++ b/lib/xmerl/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
@@ -126,7 +126,7 @@ pdf: $(TOP_PDF_FILE)
html: gifs $(HTML_REF_MAN_FILE)
$(XMERL_XML_FILES):
- docb_gen $(XMERL_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(XMERL_DIR)/$(@:%.xml=%.erl)
man: $(MAN3_FILES) $(MAN6_FILES)
diff --git a/make/otp.mk.in b/make/otp.mk.in
index bcf9bd85a4..9f0486a609 100644
--- a/make/otp.mk.in
+++ b/make/otp.mk.in
@@ -3,20 +3,20 @@
# Make include file for otp
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
# Author: Lars Thorsen
@@ -53,6 +53,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_DATA = @INSTALL_DATA@
CC = @CC@
+GCC = @GCC@
HCC = @HCC@
CC32 = @CC32@
CFLAGS32 = @CFLAGS32@
@@ -235,33 +236,44 @@ DOCGEN=$(ERL_TOP)/lib/erl_docgen
$(MAN1DIR)/%.1:: %.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
$(MAN2DIR)/%.2:: %.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
$(MAN3DIR)/%.3:: %.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+# left for compatability
$(MAN4DIR)/%.4:: %.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+$(MAN4DIR)/%.5:: %.xml
+ date=`date +"%B %e %Y"`; \
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+
+# left for compatability
$(MAN6DIR)/%.6:: %_app.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+
+$(MAN6DIR)/%.7:: %_app.xml
+ date=`date +"%B %e %Y"`; \
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
$(MAN9DIR)/%.9:: %.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
.xmlsrc.xml:
- $(DOCGEN)/priv/bin/codeline_preprocessing.escript $< $@
+ escript $(DOCGEN)/priv/bin/codeline_preprocessing.escript $< $@
.fo.pdf:
$(FOP) -fo $< -pdf $@
+
diff --git a/otp_build b/otp_build
index cddb477db5..3fd1d18634 100755
--- a/otp_build
+++ b/otp_build
@@ -1,20 +1,20 @@
#! /bin/sh
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -26,7 +26,7 @@ clearmake=false
# Global configuration variables
#
-# NOTE: lazy_configure depends on '.' allways being last directory
+# NOTE: lazy_configure depends on '.' always being last directory
if [ -z "$ONLY_ERTS" ]; then
AUTOCONF_SUBDIRS="lib lib/*"
fi
@@ -42,7 +42,6 @@ usage ()
echo " configure [<configure parameters>] - does the actual configuration"
echo " smp [-a] - build a small Erlang system, smp flavor"
echo " hybrid [-a] - build a small Erlang system, hybrid flavor"
- echo " nofrag [-a] - build a small Erlang system, nofrag flavor"
echo " boot [-a] - bootstraps and build system (after configure)"
echo " release <target_dir> - creates a small release to <target_dir>"
echo " release [-a] <target_dir> - creates full release to <target_dir>"
@@ -68,23 +67,39 @@ usage ()
echo "Before trying to cross compile, set environment via the following option"
echo "Please note that the path to the configuration file should be absolute."
echo " env_cross <absolute path to cross conf file> - echo environment settings for cross compilation, use with eval"
- echo ""
- echo "The following options concern the primary bootstrap."
- echo "{prepare,update,commit,cancel}_primary is for actually updating"
- echo "the checked in derivates of the main code base, they are not for"
- echo "managing a downloaded spource-tree."
- echo " prepare_primary - prepares for building primary bootstrap (only in Clearcase)"
- echo " update_primary - creates the primary bootstrap, the one shipped"
- echo " commit_primary - commits a primary bootstrap (only in Clearcase)"
- echo " cancel_primary - uncheckout a primary bootstrap (only in Clearcase)"
- echo ""
- echo "The following options concern preloaded code."
- echo "They are, like the primary bootstrap, mainly the concern of the"
- echo "main developers."
- echo " prepare_preloaded - prepares for building preloaded code (only in Clearcase)"
- echo " update_preloaded - creates the preloaded beam code, the one shipped"
- echo " commit_preloaded - commits the preloaded code (only in Clearcase)"
- echo " cancel_preloaded - uncheckout preloaded code (only in Clearcase)"
+ case $version_controller in
+ none)
+ ;;
+ clearcase)
+ echo ""
+ echo "Handle the primary bootstrap in Clearcase:"
+ echo " prepare_primary - prepare for building a primary bootstrap"
+ echo " update_primary - create the primary bootstrap"
+ echo " commit_primary - commit a primary bootstrap"
+ echo " cancel_primary - uncheckout a primary bootstrap"
+ ;;
+ git)
+ echo ""
+ echo "update_primary - build and commit a new primary bootstrap"
+ ;;
+ esac
+
+ case $version_controller in
+ none)
+ ;;
+ clearcase)
+ echo ""
+ echo "Handle the preloaded modules in Clearcase:"
+ echo " prepare_preloaded - prepares for building preloaded code"
+ echo " update_preloaded - creates the preloaded code"
+ echo " commit_preloaded - commits the preloaded code"
+ echo " cancel_preloaded - uncheckout preloaded code"
+ ;;
+ git)
+ echo ""
+ echo "update_preloaded - build and commit the preloaded modules"
+ ;;
+ esac
}
export_cross_env ()
@@ -189,7 +204,23 @@ target_contains ()
return $?
}
+determine_version_controller ()
+{
+ version_controller=none
+
+ # The current directory is now $ERL_TOP. Check for
+ # either this directory being controlled by git or
+ # for the "otp_build" file being a Clearcase controlled
+ # object.
+ if git rev-parse --git-dir 2>/dev/null >/dev/null; then
+ version_controller=git
+ else
+ if test -d "otp_build@@/"; then
+ version_controller=clearcase
+ fi
+ fi
+}
# Execution of the different options
@@ -813,6 +844,23 @@ do_primary ()
fi
}
+do_primary_git ()
+{
+ setup_make
+ if [ "x$OVERRIDE_TARGET" != "x" -a "x$OVERRIDE_TARGET" != "xwin32" ]; then
+ do_primary_cross
+ else
+ $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET primary_bootstrap || exit 1;
+ fi
+ git add -A bootstrap/lib/kernel \
+ bootstrap/lib/stdlib \
+ bootstrap/lib/compiler \
+ bootstrap/lib/orber/include \
+ bootstrap/bin
+ git commit -m 'Update primary bootstrap'
+}
+
+
do_prepare ()
{
CT=`lookup_prog_in_path cleartool`
@@ -915,10 +963,6 @@ do_prepare_prel ()
do_update_prel ()
{
CT=`lookup_prog_in_path cleartool`
- if [ X"$CLEARCASE_ROOT" = X"" -o X"$CT" = X"" ]; then
- echo "To prepare for update of preloaded code, you have to run in a Clearcase view" >&2
- return
- fi
if [ X"$ERL_TOP" = X"" ]; then
echo "ERL_TOP is not set." >&2
@@ -934,6 +978,16 @@ do_update_prel ()
echo '*****************************************************'
}
+do_update_prel_git ()
+{
+ setup_make
+ (cd $ERL_TOP/erts/preloaded/src && $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET clean)
+ $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET preloaded || exit 1
+ (cd $ERL_TOP/erts/preloaded/src && $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET copy)
+ git add -A $ERL_TOP/erts/preloaded/ebin/*.beam
+ git commit -m 'Update preloaded modules'
+}
+
do_commit_prel ()
{
CT=`lookup_prog_in_path cleartool`
@@ -1144,6 +1198,8 @@ check_erltop
cd $ERL_TOP
+determine_version_controller
+
# Unset ERL_FLAGS and ERL_<Release>_FLAGS to prevent, for instance,
# a value of "-hybrid" to run the hybrid emulator during bootstrap.
sys_vsn=`awk '/SYSTEM_VSN = / {print $3}' < erts/vsn.mk`
@@ -1252,7 +1308,7 @@ case "$1" in
do_lazy_configure_target_clean;;
opt)
do_boot;;
- plain|smp|hybrid|nofrag)
+ plain|smp|hybrid)
if [ $minus_a_flag = false ]; then
TYPE=opt
fi;
@@ -1264,7 +1320,11 @@ case "$1" in
prepare_primary)
do_prepare;;
update_primary)
- do_primary;;
+ case $version_controller in
+ git) do_primary_git ;;
+ clearcase) do_primary ;;
+ none) do_primary ;;
+ esac ;;
commit_primary)
do_commit;;
cancel_primary)
@@ -1272,7 +1332,11 @@ case "$1" in
prepare_preloaded)
do_prepare_prel;;
update_preloaded)
- do_update_prel;;
+ case $version_controller in
+ git) do_update_prel_git ;;
+ clearcase) do_update_prel ;;
+ none) do_update_prel ;;
+ esac ;;
commit_preloaded)
do_commit_prel;;
cancel_preloaded)
diff --git a/system/AD.html b/system/AD.html
deleted file mode 100644
index 695f3b40aa..0000000000
--- a/system/AD.html
+++ /dev/null
@@ -1,307 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>AMENDMENT DIRECTIVE, OTP</TITLE>
-</HEAD>
-<BODY BGCOLOR="#FFFFFF">
-<CENTER>
-<A HREF="http://otp.ericsson.se"><IMG BORDER=0 ALT="[OTP]" SRC="http://otp.ericsson.se/pics/banner/min_head.gif"></A>
-<H1>AMENDMENT DIRECTIVE, OTP</H1>
-<FONT SIZE="+1">
-1/177 82 - APN 181 01I<BR>
-UAB/F Kenneth Lundin, Lars Thors�n, Morgan Eriksson<BR>
-961023<BR>
-</FONT>
-</CENTER>
-<BLOCKQUOTE>
-<H2>Table of Contents</H2>
-1 <A HREF="#1">Introduction</A><BR>
-1.1 <A HREF="#1.1">Purpose</A><BR>
-1.2 <A HREF="#1.2">Revision History</A><BR>
-2 <A HREF="#2">Product Identities</A><BR>
-3 <A HREF="#3">Document Survey</A><BR>
-4 <A HREF="#4">Implemented Change requests</A><BR>
-5 <A HREF="#5">Implemented Trouble Reports</A><BR>
-6 <A HREF="#6">Installation Instructions</A><BR>
-6.1 <A HREF="#6.1">Separate (optional) Installation of XNTP (Network Time Protocol)</A><BR>
-7 <A HREF="#7">Some useful notes</A><BR>
-8 <A HREF="#8">Known problems in this release</A><BR>
-9 <A HREF="#9">References</A><BR>
-
-<A NAME="1"><!-- Empty --></A><H2>1 Introduction</H2>
-<P><A NAME="1.1"><!-- Empty --></A><H3>1.1 Purpose</H3>
-<P>This update release, OTP P1H, contains a fix for the erl_call problems in OTP P1G.<A NAME="1.2"><!-- Empty --></A><H3>1.2 Revision History</H3>
-<P>Rev.A:Kenneth Lundin 1996-05-31<BR>
-
-Rev.B:Lars Thors�n 1996-06-04<BR>
-
-Rev.C:Kenneth Lundin 1996-06-14<BR>
-
-Rev.D:Kenneth Lundin 1996-08-28<BR>
-
-Rev.E:Lars Thors�n 1996-09-12<BR>
-
-Rev.F:Kenneth Lundin 1996-09-13<BR>
-
-Rev.G:Morgan Ericsson 1996-10-08<BR>
-
-Rev.H:Kenneth Lundin 1996-10-14<BR>
-
-Rev.I:Morgan Eriksson 1996-10-23<BR>
-<P>The exact changes between revisions of this document can be generated from our ClearCase repository upon request , or a simple unix "diff" can be used.<A NAME="2"><!-- Empty --></A><H2>2 Product Identities</H2>
-<P><P><TABLE BORDER=1>
-<TR>
-<TD><B>Product Name</B></TD>
-<TD><B>Product Number</B></TD>
-<TD><B>R-state</B></TD>
-</TR>
-<TR>
-<TD>OTP</TD>
-<TD>APN 181 01</TD>
-<TD>P1H</TD>
-</TR>
-<TR>
-<TD>ERTS (sunos4)</TD>
-<TD>CXC 138 10/1</TD>
-<TD>P1G</TD>
-</TR>
-<TR>
-<TD>ERTS (sunos5)</TD>
-<TD>CXC 138 10/2</TD>
-<TD>P1G</TD>
-</TR>
-<TR>
-<TD>SASL (BOS) (sunos4)</TD>
-<TD>CXC 138 11/1</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>SASL (BOS) (sunos5)</TD>
-<TD>CXC 138 11/2</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>MNESIA</TD>
-<TD>CXC 138 12/1</TD>
-<TD>P1E</TD>
-</TR>
-<TR>
-<TD>SNMPEA</TD>
-<TD>CXC 138 13/1</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>ERLDEV (Compiler & Debugger)</TD>
-<TD>CXC 138 15/1</TD>
-<TD>P1C</TD>
-</TR>
-<TR>
-<TD>DEVTOOLS (sunos4)</TD>
-<TD>CXC 138 16/1</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>DEVTOOLS (sunos5)</TD>
-<TD>CXC 138 16/2</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>XLATETOOLS (sunos4)</TD>
-<TD>CXC 138 17/1</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>XLATETOOLS (sunos5)</TD>
-<TD>CXC 138 17/2</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>CPO Solaris (XNTP)</TD>
-<TD>CXC 138 46/1</TD>
-<TD>P1A</TD>
-</TR>
-</TABLE>
-<A NAME="3"><!-- Empty --></A><H2>3 Document Survey</H2>
-<P><P><TABLE BORDER=1>
-<TR>
-<TD><B>Document name</B></TD>
-<TD><B>Document number</B></TD>
-<TD>Rev</TD>
-</TR>
-<TR>
-<TD>Systems Overview</TD>
-<TD>1551-APN 181 01</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools Introduction</TD>
-<TD>EPK-95:030/1</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools User's Guide</TD>
-<TD>EPK-95:030/2</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools</TD>
-<TD>EPK-95:030/3</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Distributed Erlang User's Guide</TD>
-<TD>EPK-95:030/4</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools Examples</TD>
-<TD>EPK-95:030/5</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>User's Guide to the Erlang Interface Library</TD>
-<TD>3/1553-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Interface Library Examples</TD>
-<TD>1/198 17-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Programmer's Guide to the Erlang Interface Library</TD>
-<TD>2/198 17-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>OTP Erlang User's guide</TD>
-<TD>1553-CNA 121 17</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>The Mnesia Query Language Mnemosyne</TD>
-<TD>1553-CNA 121 18</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>SNMPEA User's Guide</TD>
-<TD>1553-CNA 121 19</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>SNMPEA Reference Guide</TD>
-<TD>1551-CNA 121 19</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>User's Guide to the Interface Generator</TD>
-<TD>1553-CNA 121 38</TD>
-<TD>A</TD>
-</TR>
-</TABLE>
-<P>A complete browseable document survey is available at the OTP WWW-server http://otp.ericsson.se and can also be found in the release at $OTP_ROOT/doc/all.html when the
-release file is un-tar:ed at $OTP_ROOT.<A NAME="4"><!-- Empty --></A><H2>4 Implemented Change requests</H2>
-<P>-<A NAME="5"><!-- Empty --></A><H2>5 Implemented Trouble Reports</H2>
-<P><P><TABLE BORDER=1>
-<TR>
-<TD><B>Block</B></TD>
-<TD><B>TR id</B></TD>
-<TD><B>Slogan</B></TD>
-</TR>
-<TR>
-<TD>ERTS</TD>
-<TD>-</TD>
-<TD>erl_call crashes (Segmentation fault) has now been fixed</TD>
-</TR>
-</TABLE>
-<A NAME="6"><!-- Empty --></A><H2>6 Installation Instructions</H2>
-<P>The release is delivered as a compressed tar-file <B>otp_APN18101_P1H.&#60;target&#62;.tar.Z</B>, where &#60;target&#62; is substituted with <B>sunos4</B> or <B>sunos5</B>.<P>Then the following steps shall be performed at installation time:<UL>
-<LI>Create a new directory $OTP_INSTALL_DIR where OTP can be installed.
-<PRE>mkdir $OTP_INSTALL_DIR
-cd $OTP_INSTALL_DIR
-uncompress $XXX/otp_APN18101_P1H.&lt;target&gt;.tar.Z
-tar xvfp $XXX/otp_APN18101_P1H.&lt;target&gt;.tar</PRE>
-
-<LI>Run the OTP installscript and answer the questions.
-<PRE>./Install $OTP_INSTALL_DIR</PRE>
-<BR>The Install command will ask a number of questions during the installation.
-<B>OBS!</B> When installing on a system where DNS is not used you
-should answer <B>NO</B> on the question "WILL YOU USE DNS?"
-
-<LI>Prepare the OTP man pages.
-<PRE>mkdir man/cat1 man/cat3
-./format_man_pages</PRE>
-
-<LI>Update the erl_interface library with ranlib (sunos4 only).
-<PRE>cd $OTP_INSTALL_DIR/usr/lib
-ranlib liberl_interface.a</PRE>
-
-</UL>
-<P>Add $OTP_INSTALL_DIR/bin to the path variable and $OTP_INSTALL_DIR/man to the MANPATH variable.<P>Where <B>$XXX</B> denotes the path at which otp_APN18101_P1H.&#60;target&#62;.tar resides.
-<A NAME="6.1"><!-- Empty --></A><H3>6.1 Separate (optional) Installation of XNTP (Network Time Protocol)</H3>
-<P>XNTP (Network Time Protocol) <B>for use in an embedded system running Sunos5</B> is
-delivered in this release. The XNTP resides in the tar-file xntp_CXC_13846_P1A.sunos5.tar.Z and can be fetched with Netscape from the same place as the other OTP deliverables.<UL>
-<LI>Create a new directory $XNTP_DIR where the XNTP distribution can be loaded.
-<PRE>mkdir $XNTP_DIR
-cd $XNTP_DIR
-uncompress $XXX/xntp_CXC_13846_P1A.sunos5.tar.Z
-tar xvf $XXX/xntp_CXC_13846_P1A.sunos5.tar.Z</PRE>
-
-<LI>Read the README-file which is included, below follows information which
-is partly the same as can be found at the end of the README file.
-
-<LI>Note, the xntp3.5a.export subdirectory is not needed for installation.
-
-<BR>Create a suitable configuration file based on the samples in the
-'config' directory, and copy it to /etc/ntp.conf.
-
-<LI>Create a directory for the binaries and copy them there:<BR>
-
-<PRE>mkdir -p /opt/xntp/bin
-cp bin/* /opt/xntp/bin</PRE>
-<BR>Note!, if you prefer another installation directory for the binaries, you have to edit one line in the "Run Commands" script xntp (located in the init directory):
-<PRE>BINDIR=&lt;your new bindir&gt;</PRE>
-
-<LI>Install the "Run Commands" script:<BR>
-
-<PRE>cp init/xntp /etc/init.d/xntp&lt;br&gt;
-ln /etc/init.d/xntp /etc/rc0.d/K57xntp
-ln /etc/init.d/xntp /etc/rc1.d/K57xntp
-ln /etc/init.d/xntp /etc/rc2.d/S78xntp</PRE>
-
-<LI>Modify the /etc/system file (you probably want to save the original):<BR>
-
-<PRE>cat init/system &gt;&gt; /etc/system</PRE>
-
-</UL>
-<P>Where <B>$XXX</B> denotes the path at which xntp_CXC13846_P1A.sunos5.tar.Z resides.<A NAME="7"><!-- Empty --></A><H2>7 Some useful notes</H2>
-<P>To make it possible to browse Framemaker documents through Netscape the files
-.mime.types and .mailcap should be modified (see below). The modifications
-can be made as systems defaults if they are placed in e.g /usr/local/lib/netscape (see Netscape Handbook for details) or as personal defaults if placed in the
-users $HOME directory.<P>.mime.types<P><PRE>application/x-maker fm</PRE>
-<P>
-.mailcap<P><PRE>application/x-maker; fmclient -f %s</PRE>
-<A NAME="8"><!-- Empty --></A><H2>8 Known problems in this release</H2>
-<P><UL>
-<LI>In the manual-page for module code, the returned value of the function
-which is described to be String but in reality it is an Atom (for compatibility
-reasons). In the next release the return type will however be String as it says
-in the manual-page.
-
-<LI>On SunOS4.x platforms, the format_man_pages script (executed as a part of installation) will cause following error messages for missing manual sections:
-<BR>
-<PRE>opendir:man{2,4,5,6,7,8,l,n}: No such file or directory</PRE>
-<BR>These messages should be ignored.
-
-</UL>
-<A NAME="9"><!-- Empty --></A><H2>9 References</H2>
-<P><I>Nothing to reference</I>
-</BLOCKQUOTE>
-<CENTER>
-<HR>
-<P><FONT SIZE=-1>
-Copyright &copy; 1996 <A HREF="http://otp.ericsson.se">Open Telecom Platform</A><BR>
-<!--#include virtual="/ssi/otp_footer.html"-->
-</FONT>
-</CENTER>
-</BODY>
-</HTML>
diff --git a/system/AD.sgml b/system/AD.sgml
deleted file mode 100644
index e7fc9755ed..0000000000
--- a/system/AD.sgml
+++ /dev/null
@@ -1,367 +0,0 @@
-<!doctype report PUBLIC "-//Stork//DTD report//EN">
-
-<report>
- <header>
- <title>AMENDMENT DIRECTIVE, OTP</title>
- <prepared>ETX/B/SFP Kenneth Lundin, Lars Thors&#233;n, Morgan Eriksson</prepared>
- <responsible></responsible>
- <docno>1/177 82 - APN 181 01</docno>
- <approved>ETX/B/SF Torbj&ouml;rn Johnson</approved>
- <checked></checked>
- <date>961023</date>
- <rev>I</rev>
- <file>tr1c.sgml</file>
- </header>
-
-<section>
-<title>Introduction</title>
-<p>
-<section><title>Purpose</title>
-<p>
-This update release, OTP P1H, contains a fix for the erl_call problems in OTP P1G.
-</section>
-
-<section><title>Revision History</title>
-<p>
-Rev.A:Kenneth Lundin 1996-05-31<br>
-Rev.B:Lars Thors&#233;n 1996-06-04<br>
-Rev.C:Kenneth Lundin 1996-06-14<br>
-Rev.D:Kenneth Lundin 1996-08-28<br>
-Rev.E:Lars Thors&#233;n 1996-09-12<br>
-Rev.F:Kenneth Lundin 1996-09-13<br>
-Rev.G:Morgan Ericsson 1996-10-08<br>
-Rev.H:Kenneth Lundin 1996-10-14<br>
-Rev.I:Morgan Eriksson 1996-10-23<br>
-<p>
-The exact changes between revisions of this document can be generated from our ClearCase repository upon request , or a simple unix "diff" can be used.
-</section>
-</section>
-<section><title>Product Identities</title>
-<p>
-<table>
-<row>
-<cell><b>Product Name</b></cell>
-<cell><b>Product Number</b></cell>
-<cell><b>R-state</b></cell>
-</row>
-<row>
-<cell>OTP</cell>
-<cell>APN 181 01</cell>
-<cell>P1H</cell>
-</row>
-<row>
-<cell>ERTS (sunos4)</cell>
-<cell>CXC 138 10/1</cell>
-<cell>P1G</cell>
-</row>
-<row>
-<cell>ERTS (sunos5)</cell>
-<cell>CXC 138 10/2</cell>
-<cell>P1G</cell>
-</row>
-<row>
-<cell>SASL (BOS) (sunos4)</cell>
-<cell>CXC 138 11/1</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>SASL (BOS) (sunos5)</cell>
-<cell>CXC 138 11/2</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>MNESIA</cell>
-<cell>CXC 138 12/1</cell>
-<cell>P1E</cell>
-</row>
-<row>
-<cell>SNMPEA</cell>
-<cell>CXC 138 13/1</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>ERLDEV (Compiler & Debugger)</cell>
-<cell>CXC 138 15/1</cell>
-<cell>P1C</cell>
-</row>
-<row>
-<cell>DEVTOOLS (sunos4)</cell>
-<cell>CXC 138 16/1</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>DEVTOOLS (sunos5)</cell>
-<cell>CXC 138 16/2</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>XLATETOOLS (sunos4)</cell>
-<cell>CXC 138 17/1</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>XLATETOOLS (sunos5)</cell>
-<cell>CXC 138 17/2</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>CPO Solaris (XNTP)</cell>
-<cell>CXC 138 46/1</cell>
-<cell>P1A</cell>
-</row>
-</table>
-</section>
-<section><title>Document Survey</title>
-<p>
-<table>
-<row>
-<cell><b>Document name</b></cell>
-<cell><b>Document number</b></cell>
-<cell>Rev</cell>
-</row>
-<row>
-<cell>Systems Overview</cell>
-<cell>1551-APN 181 01</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Erlang Tools Introduction</cell>
-<cell>EPK-95:030/1</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Erlang Tools User's Guide</cell>
-<cell>EPK-95:030/2</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Erlang Tools</cell>
-<cell>EPK-95:030/3</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Distributed Erlang User's Guide</cell>
-<cell>EPK-95:030/4</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Erlang Tools Examples</cell>
-<cell>EPK-95:030/5</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>User's Guide to the Erlang Interface Library</cell>
-<cell>3/1553-CNA 121 16</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Erlang Interface Library Examples</cell>
-<cell>1/198 17-CNA 121 16</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Programmer's Guide to the Erlang Interface Library</cell>
-<cell>2/198 17-CNA 121 16</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>OTP Erlang User's guide</cell>
-<cell>1553-CNA 121 17</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>The Mnesia Query Language Mnemosyne</cell>
-<cell>1553-CNA 121 18</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>SNMPEA User's Guide</cell>
-<cell>1553-CNA 121 19</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>SNMPEA Reference Guide</cell>
-<cell>1551-CNA 121 19</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>User's Guide to the Interface Generator</cell>
-<cell>1553-CNA 121 38</cell>
-<cell>A</cell>
-</row>
-
-</table>
-
-<p>
-A complete browseable document survey is available at the OTP WWW-server http://otp.ericsson.se and can also be found in the release at $OTP_ROOT/doc/all.html when the
-release file is un-tar:ed at $OTP_ROOT.
-</section>
-<section><title>Implemented Change requests</title>
-<p>
--
-</section>
-<section><title>Implemented Trouble Reports</title>
-<p>
-<table>
-<row>
-<cell><b>Block</b></cell>
-<cell><b>TR id</b></cell>
-<cell><b>Slogan</b></cell>
-</row>
-<row>
-<cell>ERTS</cell>
-<cell>-</cell>
-<cell>
-erl_call crashes (Segmentation fault) has now been fixed
-</cell>
-</row>
-</table>
-</section>
-<section><title>Installation Instructions</title>
-<p>
-The release is delivered as a compressed tar-file <b>otp_APN18101_P1H.&lt;target&gt;.tar.Z</b>, where &lt;target&gt; is substituted with <b>sunos4</b> or <b>sunos5</b>.
-<p>
-Then the following steps shall be performed at installation time:
-</p>
-<list>
-<item><p>Create a new directory $OTP_INSTALL_DIR where OTP can be installed.
-<code>
-mkdir $OTP_INSTALL_DIR
-cd $OTP_INSTALL_DIR
-uncompress $XXX/otp_APN18101_P1H.<target>.tar.Z
-tar xvfp $XXX/otp_APN18101_P1H.<target>.tar
-</code>
-</item>
-<item><p>Run the OTP installscript and answer the questions.
-<code>
-./Install $OTP_INSTALL_DIR
-</code>
-<p>
-The Install command will ask a number of questions during the installation.
-<b>OBS!</b> When installing on a system where DNS is not used you
-should answer <b>NO</b> on the question "WILL YOU USE DNS?"
-</item>
-<item><p>Prepare the OTP man pages.
-<code>
-mkdir man/cat1 man/cat3
-./format_man_pages
-</code>
-<item><p>Update the erl_interface library with ranlib (sunos4 only).
-<code>
-cd $OTP_INSTALL_DIR/usr/lib
-ranlib liberl_interface.a
-</code>
-</item>
-</list>
-<p>
-Add $OTP_INSTALL_DIR/bin to the path variable and $OTP_INSTALL_DIR/man to the MANPATH variable.
-<p>
-Where <b>$XXX</b> denotes the path at which otp_APN18101_P1H.&lt;target&gt;.tar resides.
-
-<section><title>Separate (optional) Installation of XNTP (Network Time Protocol)</title>
-<p>
-XNTP (Network Time Protocol) <b>for use in an embedded system running Sunos5</b> is
-delivered in this release. The XNTP resides in the tar-file xntp_CXC_13846_P1A.sunos5.tar.Z and can be fetched with Netscape from the same place as the other OTP deliverables.
-<list>
-<item><p>Create a new directory $XNTP_DIR where the XNTP distribution can be loaded.
-<code>
-mkdir $XNTP_DIR
-cd $XNTP_DIR
-uncompress $XXX/xntp_CXC_13846_P1A.sunos5.tar.Z
-tar xvf $XXX/xntp_CXC_13846_P1A.sunos5.tar.Z
-</code>
-</item>
-<item><p>Read the README-file which is included, below follows information which
-is partly the same as can be found at the end of the README file.</item>
-<item><p>Note, the xntp3.5a.export subdirectory is not needed for installation.
-
-<p>Create a suitable configuration file based on the samples in the
-'config' directory, and copy it to /etc/ntp.conf.</item>
-
-<item><p>Create a directory for the binaries and copy them there:<br>
-<code>
-mkdir -p /opt/xntp/bin
-cp bin/* /opt/xntp/bin
-</code>
-<p>Note!, if you prefer another installation directory for the binaries, you have to edit one line in the "Run Commands" script xntp (located in the init directory):
-<code>
-BINDIR=<your new bindir>;
-</code>
-</item>
-
-<item><p>Install the "Run Commands" script:<br>
-<code>
-cp init/xntp /etc/init.d/xntp<br>
-ln /etc/init.d/xntp /etc/rc0.d/K57xntp
-ln /etc/init.d/xntp /etc/rc1.d/K57xntp
-ln /etc/init.d/xntp /etc/rc2.d/S78xntp
-</code>
-</item>
-
-<item><p>Modify the /etc/system file (you probably want to save the original):<br>
-<code>
-cat init/system >> /etc/system
-</code>
-</item>
-
-</list>
-<p>
-Where <b>$XXX</b> denotes the path at which xntp_CXC13846_P1A.sunos5.tar.Z resides.
-</section>
-</section>
-
-<section><title>Some useful notes</title>
-<p>
-To make it possible to browse Framemaker documents through Netscape the files
-.mime.types and .mailcap should be modified (see below). The modifications
-can be made as systems defaults if they are placed in e.g /usr/local/lib/netscape (see Netscape Handbook for details) or as personal defaults if placed in the
-users $HOME directory.
-<p>
-.mime.types
-<p>
-<pre>
-application/x-maker fm
-</pre>
-<p>
-
-.mailcap
-<p>
-<pre>
-application/x-maker; fmclient -f %s
-</pre>
-</section>
-<section><title>Known problems in this release</title>
-<p>
-<list>
-<item><p>In the manual-page for module code, the returned value of the function
-which is described to be String but in reality it is an Atom (for compatibility
-reasons). In the next release the return type will however be String as it says
-in the manual-page.</item>
-<item><p>On SunOS4.x platforms, the format_man_pages script (executed as a part of installation) will cause following error messages for missing manual sections:
-<p><code>opendir:man{2,4,5,6,7,8,l,n}: No such file or directory</code>
-<p>These messages should be ignored.
-</item>
-
-</list>
-</section>
-<section><title>References</title>
-<p>
-<i>Nothing to reference</i>
-
-</section>
-</report>
-
-
-
-
-
-
-
-
-
diff --git a/system/ADbeam.html b/system/ADbeam.html
deleted file mode 100644
index abb80c9f0a..0000000000
--- a/system/ADbeam.html
+++ /dev/null
@@ -1,261 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>AMENDMENT DIRECTIVE, OTP-BEAM
- </TITLE>
-</HEAD>
-<BODY BGCOLOR="#FFFFFF">
-<TABLE WIDTH=100%>
-<TR>
-<TD ROWSPAN=2 WIDTH=50%><IMG ALT="Ericsson" SRC="http://otp.ericsson.se/pics/logo/elogo.gif"></TD>
-<TD VALIGN=TOP WIDTH=50%><BR><BR></TD>
-</TR>
-<TR>
-<TD VALIGN=TOP WIDTH=50%><B>OTP Report</B></TD>
-</TR>
-</TABLE><CENTER>
-<TABLE BORDER CELLSPACING=0 CELLPADDING=2 WIDTH=100%>
-<TR>
-<TD VALIGN=TOP WIDTH=30% COLSPAN=3>
-<FONT SIZE=1>Uppgjord - <I>Prepared</I></FONT><BR>
-<FONT SIZE=3>UAB/F Kenneth Lundin, Lars Thors�n
-</FONT>
-</TD>
-<TD VALIGN=TOP WIDTH=20% COLSPAN=2 NOWRAP>
-<FONT SIZE=1>Faktaansvarig - <I>Subject responsible</I></FONT><BR>
-<FONT SIZE=3> </FONT><BR>
-</TD>
-<TD VALIGN=TOP WIDTH=50% COLSPAN=5>
-<FONT SIZE=1>Nr - <I>No</I></FONT><BR>
-<FONT SIZE=3>3/177 82 - APN 181 01
-</FONT>
-</TD>
-</TR>
-<TR>
-<TD VALIGN=TOP WIDTH=40% COLSPAN=4 NOWRAP>
-<FONT SIZE=1>Dokansv/Godk - <I>Doc respons/Approved</I></FONT><BR>
-<FONT SIZE=3>ETX/B/DU Torbj&ouml;rn Johnsson
-</FONT>
-</TD>
-<TD VALIGN=TOP WIDTH=10%>
-<FONT SIZE=1>Kontr - <I>Checked</I></FONT><BR>
-<FONT SIZE=3> </FONT>
-</TD>
-<TD VALIGN=TOP WIDTH=20% COLSPAN=2 NOWRAP>
-<FONT SIZE=1>Datum - <I>Date</I></FONT><BR>
-<FONT SIZE=3>960828
-</FONT></TD>
-<TD VALIGN=TOP WIDTH=10%><FONT SIZE=1>Rev</FONT><BR>
-<FONT SIZE=3>D
-</FONT>
-</TD>
-<TD VALIGN=TOP WIDTH=20% COLSPAN=2>
-<FONT SIZE=1>File</FONT><BR>
-<FONT SIZE=3>tr1c.sgml
-<BR></FONT>
-</TD>
-</TR>
-</TABLE><P>
-<A HREF="http://otp.ericsson.se/">
-<STRONG>OTP</STRONG></A> /
-<STRONG>...</STRONG> /
-<A HREF="../
- ">
-<STRONG>Up</STRONG></A> /
-<P><B><FONT SIZE=8>AMENDMENT DIRECTIVE, OTP-BEAM
-</FONT></B>
-</CENTER>
-<HR>
-<H2>Introduction</H2>
-<P>
-<H3>Purpose</H3>
-<P>This is a first prototype release of the OTP-BEAM system for SunOS5.
-This version is intended to be used for various capacity measurements and the functionality is comparable to that of OTP rev P1D (APN 181 01 P1D).
-
-<H3>Revision History</H3>
-<P>Rev.A:Kenneth Lundin 1996-08-28<BR>
-
-<P>The exact changes between revisions of this document can be generated from our ClearCase repository upon request , or a simple unix "diff" can be used.
-<H2>Product Identities</H2>
-<P><CENTER><TABLE BORDER=1>
-<TR>
-<TH>Product Name</TH>
-<TH>Product Number</TH>
-<TH>R-state</TH>
-</TR>
-<TR>
-<TD>OTP</TD>
-<TD>APN 181 01</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>ERTS (sunos5-beam)</TD>
-<TD>CXC 138 10/3</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>SASL (BOS) (sunos5-beam)</TD>
-<TD>CXC 138 11/3</TD>
-<TD>P1C</TD>
-</TR>
-<TR>
-<TD>MNESIA</TD>
-<TD>CXC 138 12/1</TD>
-<TD>P1C</TD>
-</TR>
-<TR>
-<TD>SNMPEA</TD>
-<TD>CXC 138 13/1</TD>
-<TD>P1C</TD>
-</TR>
-<TR>
-<TD>ERLDEV (Compiler & Debugger)</TD>
-<TD>CXC 138 15/1</TD>
-<TD>P1B</TD>
-</TR>
-<TR>
-<TD>DEVTOOLS (sunos5-beam)</TD>
-<TD>CXC 138 16/3</TD>
-<TD>P1C</TD>
-</TR>
-<TR>
-<TD>XLATETOOLS (sunos5-beam)</TD>
-<TD>CXC 138 17/3</TD>
-<TD>P1C</TD>
-</TR>
-</TABLE></CENTER>
-
-<H2>Document Survey</H2>
-<P><CENTER><TABLE BORDER=1>
-<TR>
-<TH>Document name</TH>
-<TH>Document number</TH>
-<TH>Rev</TH>
-</TR>
-<TR>
-<TD>Systems Overview</TD>
-<TD>1551-APN 181 01</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools Introduction</TD>
-<TD>EPK-95:030/1</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools User's Guide</TD>
-<TD>EPK-95:030/2</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools</TD>
-<TD>EPK-95:030/3</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Distributed Erlang User's Guide</TD>
-<TD>EPK-95:030/4</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools Examples</TD>
-<TD>EPK-95:030/5</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>User's Guide to the Erlang Interface Library</TD>
-<TD>3/1553-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Interface Library Examples</TD>
-<TD>1/198 17-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Programmer's Guide to the Erlang Interface Library</TD>
-<TD>2/198 17-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>OTP Erlang User's guide</TD>
-<TD>1553-CNA 121 17</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Mnesia Users Guide (changed name and much improved)</TD>
-<TD>1553-CNA 121 18</TD>
-<TD>PB1</TD>
-</TR>
-<TR>
-<TD>SNMPEA User's Guide</TD>
-<TD>1553-CNA 121 19</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>SNMPEA Reference Guide</TD>
-<TD>1551-CNA 121 19</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>User's Guide to the Interface Generator</TD>
-<TD>1553-CNA 121 38</TD>
-<TD>A</TD>
-</TR>
-</TABLE></CENTER>
-
-
-<P>A complete browseable document survey is available at the OTP WWW-server http://otp.ericsson.se and can also be found in the release at $OTP_ROOT/doc/all.html when the
-release file is un-tar:ed at $OTP_ROOT.
-<H2>Implemented Change requests</H2>
-<P>Comparable in functionality with OTP 181 01 P1D (jam).
-
-<H2>Implemented Trouble Reports</H2>
-<P>This is the first version.
-
-<H2>Installation Instructions</H2>
-<P><B>OBS! The installation path selected below must not be the same as the one used for an OTP -jam system. </B>
-<P>The release is delivered as a compressed tar-file
-<B>otp_APN18101_beam_P1D.&lt;target&gt;.tar.Z</B>,
-where &lt;target&gt; is substituted with <B>sunos5</B>.
-<P>Then the following steps shall be performed at installation time:
-<UL>
-<LI>mkdir <I>&lt;installation path&gt;</I>
-<LI>cd <I>&lt;installation path&gt;</I>
-<LI>uncompress $XXX/otp_APN18101_beam_P1D.&lt;target&gt;.tar.Z
-<LI>tar xvfp $XXX/otp_APN18101_beam_P1D.&lt;target&gt;.tar
-<LI>./Install <I>&lt;installation path&gt;</I><BR>
-The Install command will ask a number of questions during the installation.<BR>
-<B>OBS!</B> When installing on a system where DNS is not used you
-should answer <B>NO</B> on the question "WILL YOU USE DNS?"
-<LI>mkdir man/cat1 man/cat3
-<LI>./format_man_pages
-<LI>cd <I>&lt;installation path&gt;</I>/usr/lib and run ranlib on liberl_interface.a (only sunos4)
-</UL>
-
-Add <I>&lt;installation path&gt;</I>/bin to the path variable and <I>&lt;installation path&gt;</I>/man to the MANPATH variable.
-<P>Where $XXX denotes the path at which otp_APN18101_beam_P1D.&lt;target&gt;.tar resides.
-<H2>Some useful notes</H2>
-<P>To make it possible to browse Framemaker documents through Netscape the files
-.mime.types and .mailcap should be modified (see below). The modifications
-can be made as systems defaults if they are placed in e.g /usr/local/lib/netscape (see Netscape Handbook for details) or as personal defaults if placed in the
-users $HOME directory.
-<P>.mime.types
-<P>
-<PRE>application/x-maker fm</PRE>
-
-<P>
-.mailcap
-<P>
-<PRE>application/x-maker; fmclient -f %s</PRE>
-
-<H2>Known problems in this release</H2>
-<P><UL>
-<LI>Some html-links may still be faulty.
-</UL>
-
-<H2>References</H2>
-<P><I>Nothing to reference</I>
-
-
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/system/ADbeam.sgml b/system/ADbeam.sgml
deleted file mode 100644
index 63995fe26e..0000000000
--- a/system/ADbeam.sgml
+++ /dev/null
@@ -1,246 +0,0 @@
-<!doctype report PUBLIC "-//Stork//DTD tr1c//EN">
-
-<report>
- <header>
- <title>AMENDMENT DIRECTIVE, OTP-BEAM
- <prepared>ETX/B/DUP Kenneth Lundin, Lars Thors&#233;n
- <responsible>
- <docno>3/177 82 - APN 181 01
- <approved>ETX/B/DU Torbj&ouml;rn Johnsson
- <checked>
- <date>960828
- <rev>D
- <file>tr1c.sgml
- <parent>../
- </header>
-
- <section>
-<h1>Introduction</h1>
-<p>
-<h2>Purpose</h2>
-<p>
-This is a first prototype release of the OTP-BEAM system for SunOS5.
-This version is intended to be used for various capacity measurements and the functionality is comparable to that of OTP rev P1D (APN 181 01 P1D).
-
-<h2>Revision History</h2>
-<p>
-Rev.A:Kenneth Lundin 1996-08-28<br>
-
-<p>
-The exact changes between revisions of this document can be generated from our ClearCase repository upon request , or a simple unix "diff" can be used.
-<h1>Product Identities</h1>
-<p>
-<table>
-<row>
-<hcell>Product Name
-<hcell>Product Number
-<hcell>R-state
-</row>
-<row>
-<cell>OTP
-<cell>APN 181 01
-<cell>P1D
-</row>
-<row>
-<cell>ERTS (sunos5-beam)
-<cell>CXC 138 10/3
-<cell>P1D
-</row>
-<row>
-<cell>SASL (BOS) (sunos5-beam)
-<cell>CXC 138 11/3
-<cell>P1C
-</row>
-<row>
-<cell>MNESIA
-<cell>CXC 138 12/1
-<cell>P1C
-</row>
-<row>
-<cell>SNMPEA
-<cell>CXC 138 13/1
-<cell>P1C
-</row>
-<row>
-<cell>ERLDEV (Compiler & Debugger)
-<cell>CXC 138 15/1
-<cell>P1B
-</row>
-<row>
-<cell>DEVTOOLS (sunos5-beam)
-<cell>CXC 138 16/3
-<cell>P1C
-</row>
-<row>
-<cell>XLATETOOLS (sunos5-beam)
-<cell>CXC 138 17/3
-<cell>P1C
-</row>
-</table>
-<h1>Document Survey</h1>
-<p>
-<table>
-<row>
-<hcell>Document name
-<hcell>Document number
-<hcell>Rev
-</row>
-<row>
-<cell>Systems Overview
-<cell>1551-APN 181 01
-<cell>A
-</row>
-<row>
-<cell>Erlang Tools Introduction
-<cell>EPK-95:030/1
-<cell>A
-</row>
-<row>
-<cell>Erlang Tools User's Guide
-<cell>EPK-95:030/2
-<cell>A
-</row>
-<row>
-<cell>Erlang Tools
-<cell>EPK-95:030/3
-<cell>A
-</row>
-<row>
-<cell>Distributed Erlang User's Guide
-<cell>EPK-95:030/4
-<cell>A
-</row>
-<row>
-<cell>Erlang Tools Examples
-<cell>EPK-95:030/5
-<cell>A
-</row>
-
-<row>
-<cell>User's Guide to the Erlang Interface Library
-<cell>3/1553-CNA 121 16
-<cell>A
-</row>
-<row>
-<cell>Erlang Interface Library Examples
-<cell>1/198 17-CNA 121 16
-<cell>A
-</row>
-<row>
-<cell>Programmer's Guide to the Erlang Interface Library
-<cell>2/198 17-CNA 121 16
-<cell>A
-</row>
-
-<row>
-<cell>OTP Erlang User's guide
-<cell>1553-CNA 121 17
-<cell>A
-</row>
-
-<row>
-<cell>Mnesia Users Guide (changed name and much improved)
-<cell>1553-CNA 121 18
-<cell>PB1
-</row>
-
-<row>
-<cell>SNMPEA User's Guide
-<cell>1553-CNA 121 19
-<cell>A
-</row>
-
-<row>
-<cell>SNMPEA Reference Guide
-<cell>1551-CNA 121 19
-<cell>A
-</row>
-
-<row>
-<cell>User's Guide to the Interface Generator
-<cell>1553-CNA 121 38
-<cell>A
-</row>
-
-</table>
-
-<p>
-A complete browseable document survey is available at the OTP WWW-server http://otp.ericsson.se and can also be found in the release at $OTP_ROOT/doc/all.html when the
-release file is un-tar:ed at $OTP_ROOT.
-<h1>Implemented Change requests</h1>
-<p>
-Comparable in functionality with OTP 181 01 P1D (jam).
-
-<h1>Implemented Trouble Reports</h1>
-<p>
-This is the first version.
-
-<h1>Installation Instructions</h1>
-<p>
-<b>OBS! The installation path selected below must not be the same as the one used for an OTP -jam system. </b>
-<p>
-The release is delivered as a compressed tar-file
-<b>otp_APN18101_beam_P1D.&lt;target&gt;.tar.Z</b>,
-where &lt;target&gt; is substituted with <b>sunos5</b>.
-<p>
-Then the following steps shall be performed at installation time:
-<list>
-<item>mkdir <i>&lt;installation path&gt;</i>
-<item>cd <i>&lt;installation path&gt;</i>
-<item>uncompress $XXX/otp_APN18101_beam_P1D.&lt;target&gt;.tar.Z
-<item>tar xvfp $XXX/otp_APN18101_beam_P1D.&lt;target&gt;.tar
-<item>./Install <i>&lt;installation path&gt;</i><br>
-The Install command will ask a number of questions during the installation.<br>
-<b>OBS!</b> When installing on a system where DNS is not used you
-should answer <b>NO</b> on the question "WILL YOU USE DNS?"
-<item>mkdir man/cat1 man/cat3
-<item>./format_man_pages
-<item>cd <i>&lt;installation path&gt;</i>/usr/lib and run ranlib on liberl_interface.a (only sunos4)
-</list>
-Add <i>&lt;installation path&gt;</i>/bin to the path variable and <i>&lt;installation path&gt;</i>/man to the MANPATH variable.
-<p>
-Where $XXX denotes the path at which otp_APN18101_beam_P1D.&lt;target&gt;.tar resides.
-<h1>Some useful notes</h1>
-<p>
-To make it possible to browse Framemaker documents through Netscape the files
-.mime.types and .mailcap should be modified (see below). The modifications
-can be made as systems defaults if they are placed in e.g /usr/local/lib/netscape (see Netscape Handbook for details) or as personal defaults if placed in the
-users $HOME directory.
-<p>
-.mime.types
-<p>
-<pre>
-application/x-maker fm
-</pre>
-<p>
-
-.mailcap
-<p>
-<pre>
-application/x-maker; fmclient -f %s
-</pre>
-<h1>Known problems in this release</h1>
-<p>
-<list>
-<item>Some html-links may still be faulty.
-</list>
-<h1>References</h1>
-<p>
-<i>Nothing to reference</i>
-
- </section>
-</report>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/system/doc/book.xml b/system/doc/book.xml
deleted file mode 100644
index d1ec093019..0000000000
--- a/system/doc/book.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE book SYSTEM "book.dtd">
-
-<book xmlns:xi="http://www.w3.org/2001/XInclude">
- <header titlestyle="normal">
- <copyright>
- <year>1997</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Erlang/OTP System Documentation</title>
- <prepared>OTP Team</prepared>
- <docno></docno>
- <date>2009-08-21</date>
- <rev>A</rev>
- <file>book.xml</file>
- </header>
- <insidecover>
- </insidecover>
- <pagetext></pagetext>
- <preamble>
- <contents level="2"></contents>
- </preamble>
- <parts lift="no">
- <xi:include href="installation_guide/part.xml"/>
- <xi:include href="system_principles/part.xml"/>
- <xi:include href="embedded/part.xml"/>
- <xi:include href="getting_started/part.xml"/>
- <xi:include href="reference_manual/part.xml"/>
- <xi:include href="getting_started/part.xml"/>
- <xi:include href="efficiency_guide/part.xml"/>
- <xi:include href="tutorial/part.xml"/>
- <xi:include href="design_principles/part.xml"/>
- <xi:include href="oam/part.xml"/>
- </parts>
- <listofterms></listofterms>
- <index></index>
-</book>
-
diff --git a/system/doc/extensions/Makefile b/system/doc/extensions/Makefile
deleted file mode 100644
index cfc506f7e8..0000000000
--- a/system/doc/extensions/Makefile
+++ /dev/null
@@ -1,142 +0,0 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
-#
-# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-# AB. All Rights Reserved.''
-#
-# $Id$
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include $(ERL_TOP)/erts/vsn.mk
-#VSN=$(SYSTEM_VSN)
-
-# ----------------------------------------------------
-# Include dependency
-# ----------------------------------------------------
-
-include make.dep
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/doc/extensions
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-XML_PART_FILES = part.xml
-XML_CHAPTER_FILES = \
- funs.xml \
- macros.xml \
- misc.xml \
- include.xml \
- records.xml \
- list_comprehensions.xml \
- bit_syntax.xml
-
-BOOK_FILES = book.xml
-
-GIF_FILES = note.gif
-
-PS_FILES =
-
-# ----------------------------------------------------
-
-HTML_FILES = \
- $(XML_PART_FILES:%.xml=%.html)
-
-HTMLDIR = .
-EXTRA_FILES = $(DEFAULT_GIF_FILES) \
- $(DEFAULT_HTML_FILES) \
- $(XML_CHAPTER_FILES:%.xml=%.html)
-
-TEX_FILES_BOOK = \
- $(BOOK_FILES:%.xml=%.tex)
-TEX_FILES_USERS_GUIDE = \
- $(XML_CHAPTER_FILES:%.xml=%.tex)
-
-TOP_PDF_FILE = extensions-$(VSN).pdf
-TOP_PS_FILE = extensions-$(VSN).ps
-
-$(TOP_PDF_FILE): book.dvi $(ERL_TOP)/erts/vsn.mk
- $(DVI2PS) $(DVIPS_FLAGS) -f $< | $(DISTILL) $(DISTILL_FLAGS) > $@
-
-$(TOP_PS_FILE): book.dvi $(ERL_TOP)/erts/vsn.mk
- $(DVI2PS) $(DVIPS_FLAGS) -f $< > $@
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-XML_FLAGS +=
-DVIPS_FLAGS +=
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-ifeq ($(DOCTYPE),pdf)
-docs: pdf
-else
-ifeq ($(DOCTYPE),ps)
-docs: ps
-else
-docs: html
-endif
-endif
-
-pdf: $(TOP_PDF_FILE)
-
-ps: $(TOP_PS_FILE)
-
-html: $(HTML_FILES) $(GIF_FILES)
-
-debug opt:
-
-clean_tex:
- -rm -f $(TEX_FILES_USERS_GUIDE) $(TEX_FILES_BOOK)
-
-clean:
- rm -f *.html $(TEX_FILES_USERS_GUIDE)
- rm -f $(TOP_PS_FILES)
- rm -f errs core *~ $(LATEX_CLEAN)
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-ifeq ($(DOCTYPE),pdf)
-release_docs_spec: pdf
- $(INSTALL_DIR) $(RELEASE_PATH)/pdf
- $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELEASE_PATH)/pdf
-else
-ifeq ($(DOCTYPE),ps)
-release_docs_spec: ps
- $(INSTALL_DIR) $(RELEASE_PATH)/ps
- $(INSTALL_DATA) $(TOP_PS_FILE) $(RELEASE_PATH)/ps
-else
-release_docs_spec: docs
- $(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \
- $(RELSYSDIR)
-endif
-endif
-
-release_spec:
-
-
-
diff --git a/system/doc/extensions/bit_syntax.xml b/system/doc/extensions/bit_syntax.xml
deleted file mode 100644
index d86f73cd9a..0000000000
--- a/system/doc/extensions/bit_syntax.xml
+++ /dev/null
@@ -1,403 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2000</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>The Bit Syntax</title>
- <prepared>Bj&ouml;rn Gustavsson</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno>1</docno>
- <approved>Bjarne D&auml;Ker</approved>
- <checked></checked>
- <date>00-06-21</date>
- <rev>PA1</rev>
- <file>bit_syntax.sgml</file>
- </header>
- <p>This section describes the "bit syntax" which was added to
- the Erlang language in release 5.0 (R7).
- Compared to the original bit syntax prototype
- by Claes Wikstr&ouml;m and Tony Rogvall (presented on the
- Erlang User's Conference 1999), this implementation differs
- primarily in the following respects,
- </p>
- <list type="ordered">
- <item>
- <p>the character pairs '&lt;&lt;' and '&gt;&gt;' are used to delimit
- a binary patterns and constructor (not '&lt;' and '&gt;' as in
- the prototype),
- </p>
- </item>
- <item>
- <p>the tail syntax ('|Variable') has been eliminated,
- </p>
- </item>
- <item>
- <p>all size expressions must be bound,
- </p>
- </item>
- <item>
- <p>a type <c>unit:U</c> has been added,
- </p>
- </item>
- <item>
- <p>lists and tuples cannot be generated
- </p>
- </item>
- <item>
- <p>there are no paddings whatsoever.
- </p>
- </item>
- </list>
-
- <section>
- <title>Introduction</title>
- <p>In Erlang a Bin is used for constructing binaries and
- matching binary patterns. A Bin is written with the
- following syntax:</p>
- <code type="none"><![CDATA[
- <<E1, E2, ... En>>
- ]]></code>
- <p>A Bin is a low-level sequence of bytes. The purpose of a
- Bin is to be able to, from a high level,
- <em>construct</em> a binary,
- </p>
- <code type="none"><![CDATA[
- Bin = <<E1, E2, ... En>>
- ]]></code>
- <p>in which case all elements must be bound, or to
- <em>match</em> a binary,
- </p>
- <code type="none"><![CDATA[
- <<E1, E2, ... En>> = Bin
- ]]></code>
- <p>where <c>Bin</c> is bound, and where the elements are bound or unbound,
- as in any match.
- </p>
- <p>Each element specifies a certain <em>segment</em> of the binary.
- A segment is is a set of contiguous bits of the binary (not
- necessarily on a byte boundary). The first element specifies
- the initial segment, the second element specifies the following
- segment etc.
- </p>
- <p>The following examples illustrate how binaries are constructed
- or matched, and how elements and tails are specified.
- </p>
-
- <section>
- <title>Examples</title>
- <p><em>Example 1: </em>A binary can be constructed from a set of
- constants or a string literal:</p>
- <code type="none"><![CDATA[
- Bin11 = <<1, 17, 42>>,
- Bin12 = <<"abc">>
- ]]></code>
- <p>yields binaries of size 3; <c>binary_to_list(Bin11)</c>
- evaluates to <c>[1, 17, 42]</c>, and
- <c>binary_to_list(Bin12)</c> evaluates to <c>[97, 98, 99]</c>.
- </p>
- <p><em>Example 2: </em>Similarly, a binary can be constructed
- from a set of bound variables:</p>
- <code type="none"><![CDATA[
- A = 1, B = 17, C = 42,
- Bin2 = <<A, B, C:16>>
- ]]></code>
- <p>yields a binary of size 4, and <c>binary_to_list(Bin2)</c>
- evaluates to <c>[1, 17, 00, 42]</c> too. Here we used a
- <em>size expression</em> for the variable <c>C</c> in order to
- specify a 16-bits segment of <c>Bin2</c>.
- </p>
- <p><em>Example 3: </em>A Bin can also be used for matching: if
- <c>D</c>, <c>E</c>, and <c>F</c> are unbound variables, and
- <c>Bin2</c> is bound as in the former example,</p>
- <code type="none"><![CDATA[
- <<D:16, E, F/binary>> = Bin2
- ]]></code>
- <p>yields <c>D = 273</c>, <c>E = 00</c>, and F binds to a binary
- of size 1: <c>binary_to_list(F) = [42]</c>.
- </p>
- <p><em>Example 4: </em>The following is a more elaborate example
- of matching, where <c>Dgram</c> is bound to the consecutive
- bytes of an IP datagram of IP protocol version 4, and where we
- want to extract the header and the data of the datagram:</p>
- <code type="none"><![CDATA[
- -define(IP_VERSION, 4).
- -define(IP_MIN_HDR_LEN, 5).
-
- DgramSize = byte_size(Dgram),
- case Dgram of
- <<?IP_VERSION:4, HLen:4, SrvcType:8, TotLen:16,
- ID:16, Flgs:3, FragOff:13,
- TTL:8, Proto:8, HdrChkSum:16,
- SrcIP:32,
- DestIP:32, RestDgram/binary>> when HLen >= 5, 4*HLen =< DgramSize ->
- OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN),
- <<Opts:OptsLen/binary,Data/binary>> = RestDgram,
- ...
- end.
- ]]></code>
- <p>Here the segment corresponding to the <c>Opts</c> variable
- has a <em>type modifier</em> specifying that <c>Opts</c> should
- bind to a binary. All other variables have the default type
- equal to unsigned integer.
- </p>
- <p>An IP datagram header is of variable length, and its length -
- measured in the number of 32-bit words - is given in the segment
- corresponding to <c>HLen</c>, the minimum value of which is
- 5. It is the segment corresponding to <c>Opts</c> that is
- variable: if <c>HLen</c> is equal to 5, <c>Opts</c> will be an
- empty binary.
- </p>
- <p>The tail variables <c>RestDgram</c> and <c>Data</c> bind to
- binaries, as all tail variables do. Both may bind to empty
- binaries.
- </p>
- <p>If the first 4-bits segment of <c>Dgram</c> is not equal to
- 4, or if <c>HLen</c> is less than 5, or if the size of
- <c>Dgram</c> is less than <c>4*HLen</c>, the match of
- <c>Dgram</c> fails.
- </p>
- </section>
- </section>
-
- <section>
- <title>A Lexical Note</title>
- <p>Note that "<c><![CDATA[B=<<1>>]]></c>" will be interpreted as
- "<c><![CDATA[B =< ;<1>>]]></c>", which is a syntax error.
- The correct way to write the expression is "<c><![CDATA[B = <<1>>]]></c>".</p>
- </section>
-
- <section>
- <title>Segments</title>
- <p>Each segment has the following general syntax:</p>
- <p><c>Value:Size/TypeSpecifierList</c></p>
- <p>Both the <c>Size</c> and the <c>TypeSpecifier</c> or both may be
- omitted; thus the following variations are allowed:
- </p>
- <p><c>Value</c></p>
- <p><c>Value:Size</c></p>
- <p><c>Value/TypeSpecifierList</c></p>
- <p>Default values will be used for missing specifications. The default
- values are described in the section "Defaults" below.
- </p>
- <p>Used in binary construction, the <c>Value</c> part is any expression.
- Used in binary matching, the <c>Value</c> part must be a literal or
- variable. You can read more about the <c>Value</c> part in the
- sections about constructing binaries and matching binaries.
- </p>
- <p>The <c>Size</c> part of the segment multiplied by the unit in the
- <c>TypeSpecifierList</c> (described below) gives the number of bits
- for the segment. In construction, <c>Size</c> is any expression that
- evaluates to an integer. In matching, <c>Size</c> must be a constant
- expression or a variable.
- </p>
- <p>The <c>TypeSpecifierList</c> is a list of type specifiers separated by
- hyphens.
- </p>
- <taglist>
- <tag>Type</tag>
- <item>The type can be <c>integer</c>, <c>float</c>, or <c>binary</c>.</item>
- <tag>Signedness</tag>
- <item>The signedness specification can be either <c>signed</c>
- or <c>unsigned</c>. Note that signedness only matters for matching.</item>
- <tag>Endianness</tag>
- <item>The endianness specification can be either <c>big</c>,
- <c>little</c>, or <c>native</c>. Native-endian means that
- the endian will be resolved at load time to be either
- big-endian or little-endian, depending on what is "native"
- for the CPU that the Erlang machine is run on.</item>
- <tag>Unit</tag>
- <item>The unit size is given as <c>unit:IntegerLiteral</c>.
- The allowed range is 1-256. It will be multiplied by the <c>Size</c>
- specifier to give the effective size of the segment.</item>
- </taglist>
- <p>Example:
- </p>
- <code type="none">
-X:4/little-signed-integer-unit:8
- </code>
- <p>This element has a total size of 4*8 = 32 bits, and it contains a
- signed integer in little-endian order.</p>
- </section>
-
- <section>
- <title>Defaults</title>
- <p>The default type for a segment is <c>integer</c>. The default type
- does <em>not</em> depend on the value, even if the value is a literal.
- For instance, the default type in '<c><![CDATA[<<3.14>>]]></c>' is <c>integer</c>,
- not <c>float</c>.
- </p>
- <p>The default <c>Size</c> depends on the type.
- For <c>integer</c> it is 8. For <c>float</c> it is 64.
- For <c>binary</c> it is all of the binary. In matching, this default
- value is only valid for the very last element. All other binary elements
- in matching must have a size specification.
- </p>
- <p>The default unit depends on the the type.
- For <c>integer</c> and <c>float</c> it is 1.
- For <c>binary</c> it is 8.
- </p>
- <p>The default signedness is <c>unsigned</c>.
- </p>
- <p>The default endianness is <c>big</c>.</p>
- </section>
-
- <section>
- <title>Constructing Binaries</title>
- <p>This section describes the rules for constructing binaries using
- the bit syntax. Unlike when constructing lists or tuples, the construction
- of a binary can fail with a <c>badarg</c> exception.
- </p>
- <p>There can be zero or more segments in a binary to be constructed.
- The expression '<c><![CDATA[<<>>]]></c>' constructs a zero length binary.
- </p>
- <p>Each segment in a binary can consist of zero or more bits.
- There are no alignment rules for individual segments, but the total
- number of bits in all segments must be evenly divisible by 8,
- or in other words, the resulting binary must consist of a whole number
- of bytes. An <c>badarg</c> exception will be thrown if the resulting
- binary is not byte-aligned. Example:
- </p>
- <code type="none"><![CDATA[
-<<X:1,Y:6>>
- ]]></code>
- <p>The total number of bits is 7, which is not evenly divisible by 8;
- thus, there will be <c>badarg</c> exception (and a compiler warning
- as well). The following example
- </p>
- <code type="none"><![CDATA[
-<<X:1,Y:6,Z:1>>
- ]]></code>
- <p>will successfully construct a binary of 8 bits, or one byte. (Provided
- that all of X, Y and Z are integers.)
- </p>
- <p>As noted earlier, segments have the following general syntax:
- </p>
- <p><c>Value:Size/TypeSpecifierList</c></p>
- <p>When constructing binaries, <c>Value</c> and <c>Size</c> can be
- any Erlang expression. However, for syntactical reasons,
- both <c>Value</c> and <c>Size</c> must be enclosed in parenthesis
- if the expression consists of anything more than a single literal
- or variable. The following gives a compiler syntax error:
- </p>
- <code type="none"><![CDATA[
-<<X+1:8>>
- ]]></code>
- <p>This expression must be rewritten to
- </p>
- <code type="none"><![CDATA[
-<<(X+1):8>>
- ]]></code>
- <p>in order to be accepted by the compiler.
- </p>
-
- <section>
- <title>Including Literal Strings</title>
- <p>As syntactic sugar, an literal string may be written instead of a
- element.</p>
- <code type="none"><![CDATA[
-<<"hello">> ]]></code>
- <p>which is syntactic sugar for</p>
- <code type="none"><![CDATA[
-<<$h,$e,$l,$l,$o>> ]]></code>
- </section>
- </section>
-
- <section>
- <title>Matching Binaries</title>
- <p>This section describes the rules for matching binaries using the
- bit syntax.
- </p>
- <p>There can be zero or more segments in a binary binary pattern.
- A binary pattern can occur in every place patterns are allowed, also
- inside other patterns. Binary patterns cannot be nested.
- </p>
- <p>The pattern '<c><![CDATA[<<>>]]></c>' matches a zero length binary.
- </p>
- <p>Each segment in a binary can consist of zero or more bits.
- </p>
- <p>A segment of type <c>binary</c> must have a size evenly divisible by 8.
- </p>
- <p>This means that the following head will never match:</p>
- <code type="none"><![CDATA[
-foo(<<X:7/binary,Y:1/binary>>) -> ]]></code>
- <p>As noted earlier, segments have the following general syntax:
- </p>
- <p><c>Value:Size/TypeSpecifierList</c></p>
- <p>When matching <c>Value</c> value must be either a variable or an integer
- or floating point literal. Expressions are not allowed.
- </p>
- <p><c>Size</c> must be an integer literal, or a previously bound variable.
- Note that the following is not allowed:</p>
- <code type="none"><![CDATA[
-foo(N, <<X:N,T/binary>>) ->
- {X,T}. ]]></code>
- <p>The two occurrences of <c>N</c> are not related. The compiler
- will complain that the <c>N</c> in the size field is unbound.
- </p>
- <p>The correct way to write this example is like this:</p>
- <code type="none"><![CDATA[
-foo(N, Bin) ->
- <<X:N,T/binary>> = Bin,
- {X,T}. ]]></code>
-
- <section>
- <title>Getting the Rest of the Binary</title>
- <p>To match out the rest of binary, specify a binary field without size:</p>
- <code type="none"><![CDATA[
-foo(<<A:8,Rest/binary>>) -> ]]></code>
- <p>As always, the size of the tail must be evenly divisible by 8.
- </p>
- </section>
- </section>
-
- <section>
- <title>Traps and Pitfalls</title>
- <p>Assume that we need a function that creates a binary out of a
- list of triples of integers. A first (inefficient) version of such
- a function could look like this:</p>
- <code type="none"><![CDATA[
-triples_to_bin(T) ->
- triples_to_bin(T, <<>>).
-
-triples_to_bin([{X,Y,Z} | T], Acc) ->
- triples_to_bin(T, <<Acc/binary, X:32, Y:32, Z:32>>); % inefficient
-triples_to_bin([], Acc) ->
- Acc. ]]></code>
- <p>The reason for the inefficiency of this function is that for
- each triple, the binary constructed so far (<c>Acc</c>) is copied.
- (Note: The original bit syntax prototype avoided the copy operation
- by using segmented binaries, which are not implemented in R7.)
- </p>
- <p>The efficient way to write this function in R7 is:</p>
- <code type="none"><![CDATA[
-triples_to_bin(T) ->
- triples_to_bin(T, []).
-
-triples_to_bin([{X,Y,Z} | T], Acc) ->
- triples_to_bin(T, [<<X:32, Y:32, Z:32>> | Acc]);
-triples_to_bin([], Acc) ->
- list_to_binary(lists:reverse(Acc)). ]]></code>
- <p>Note that <c>list_to_binary/1</c> handles deep lists of binaries
- and small integers. (This fact was previously undocumented.)
- </p>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/book.xml b/system/doc/extensions/book.xml
deleted file mode 100644
index ffdbe6cb44..0000000000
--- a/system/doc/extensions/book.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE book SYSTEM "book.dtd">
-
-<book>
- <header titlestyle="normal">
- <copyright>
- <year>1997</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Erlang Extensions Since 4.4</title>
- <prepared>OTP Team</prepared>
- <docno></docno>
- <date>1997-05-21</date>
- <rev></rev>
- <file>book.sgml</file>
- </header>
- <insidecover>
- </insidecover>
- <pagetext>Erlang Extensions Since 4.4</pagetext>
- <preamble>
- <contents level="2"></contents>
- </preamble>
- <parts lift="no">
- <include file="part"></include>
- </parts>
- <listofterms></listofterms>
- <index></index>
-</book>
-
diff --git a/system/doc/extensions/fun_test.erl b/system/doc/extensions/fun_test.erl
deleted file mode 100644
index 8472fd87f8..0000000000
--- a/system/doc/extensions/fun_test.erl
+++ /dev/null
@@ -1,17 +0,0 @@
-%1
--module(fun_test).
--export([t1/0, t2/0, t3/0, t4/0, double/1]).
--import(lists, [map/2]).
-
-t1() -> map(fun(X) -> 2 * X end, [1,2,3,4,5]).
-
-t2() -> map(fun double/1, [1,2,3,4,5]).
-
-t3() -> map({?MODULE, double}, [1,2,3,4,5]).
-
-double(X) -> X * 2.
-%1
-
-
-t4() ->
- "hello world".
diff --git a/system/doc/extensions/funparse.erl b/system/doc/extensions/funparse.erl
deleted file mode 100644
index 5e23c90df9..0000000000
--- a/system/doc/extensions/funparse.erl
+++ /dev/null
@@ -1,74 +0,0 @@
--module(funparse).
--compile(export_all).
--import(lists, [reverse/1]).
-
-%17
-%% > hof:parse([a,c]).
-%% {ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}
-%% > hof:parse([a,d]).
-%% {ok,{'and',{'or',1,{const,a}},{'or',2,{const,d}}}}
-%% > hof:parse([b,c]).
-%% {ok,{'and',{'or',2,{const,b}},{'or',1,{const,c}}}}
-%% > hof:parse([b,d]).
-%% {ok,{'and',{'or',2,{const,b}},{'or',2,{const,d}}}}
-%% > hof:parse([a,b]).
-%% fail
-%17
-
-%% Grammar = (a | b) & (c | d)
-
-%12
-parse(List) ->
- (grammar())(List).
-%12
-
-%13
-grammar() ->
- pand(
- por(pconst(a), pconst(b)),
- por(pconst(c), pconst(d))).
-%13
-
-%14
-pconst(X) ->
- fun (T) ->
- case T of
- [X|T1] -> {ok, {const, X}, T1};
- _ -> fail
- end
- end.
-%14
-
-%15
-por(P1, P2) ->
- fun (T) ->
- case P1(T) of
- {ok, R, T1} ->
- {ok, {'or',1,R}, T1};
- fail ->
- case P2(T) of
- {ok, R1, T1} ->
- {ok, {'or',2,R1}, T1};
- fail ->
- fail
- end
- end
- end.
-%15
-
-%16
-pand(P1, P2) ->
- fun (T) ->
- case P1(T) of
- {ok, R1, T1} ->
- case P2(T1) of
- {ok, R2, T2} ->
- {ok, {'and', R1, R2}};
- fail ->
- fail
- end;
- fail ->
- fail
- end
- end.
-%16
diff --git a/system/doc/extensions/funs.xml b/system/doc/extensions/funs.xml
deleted file mode 100644
index f9c003c8ee..0000000000
--- a/system/doc/extensions/funs.xml
+++ /dev/null
@@ -1,486 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Programming with Funs</title>
- <prepared>Joe Armstrong</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno>1</docno>
- <approved>Bjarne D&auml;Ker</approved>
- <checked></checked>
- <date>96-01-16</date>
- <rev>PA1</rev>
- <file>funs.sgml</file>
- </header>
- <p>This section introduces functional objects (Funs). That is a new data type introduced in Erlang 4.4. Functions which takes Funs as arguments, or which return Funs are called higher order functions.</p>
- <list type="bulleted">
- <item>Funs can be passed as arguments to other functions, just like lists or tuples</item>
- <item>functions can be written which return Funs, just like any other data object.</item>
- </list>
-
- <section>
- <title>Higher Order Functions </title>
- <p>Funs encourages us to encapsulate common patterns of design into functional forms called higher order functions. These functions not only shortens programs, but also produce clearer programs because the intended meaning of the program is explicitly rather than implicitly stated.</p>
- <p>The concepts of higher order functions and procedural abstraction are introduced with two brief examples.</p>
-
- <section>
- <title>Example 1 - map</title>
- <p>If we want to double every element in a list, we could write a function named <c>double</c>:</p>
- <code type="none">
-
-double([H|T]) -> [2*H|double(T)];
-double([]) -> [] </code>
- <p>This function obviously doubles the argument entered as input as follows:</p>
- <pre>
-
-> <input>double([1,2,3,4]).</input>
-[2,4,6,8] </pre>
- <p>We now add the function <c>add_one</c>, which adds one to every element in a list:</p>
- <code type="none">
-
-add_one([H|T]) -> [H+1|add_one(T)];
-add_one([]) -> []. </code>
- <p>These functions, <c>double</c> and <c>add_one</c>, have a very similar structure. We can exploit this fact and write a function <c>map</c> which expresses this similarity:</p>
- <codeinclude file="funs1.erl" tag="%1" type="erl"></codeinclude>
- <p>We can now express the functions <c>double</c> and <c>add_one</c> in terms of <c>map</c> as follows:</p>
- <code type="none">
-
-double(L) -> map(fun(X) -> 2*X end, L).
-add_one(L) -> map(fun(X) -> 1 + X end, L). </code>
- <p><c>map(F, List)</c> is a function which takes a function <c>F</c> and a list <c>L</c> as arguments and
- returns the new list which is obtained by applying <c>F</c> to each of the elements in <c>L</c>.</p>
- <p>The process of abstracting out the common features of a number of different programs is called procedural abstraction. Procedural abstraction can be used in order to write several different functions which have a similar structure, but differ only in some minor detail. This is done as follows:</p>
- <list type="ordered">
- <item>write one function which represents the common features of these functions</item>
- <item>parameterize the difference in terms of functions which are passed as arguments to the common function.</item>
- </list>
- </section>
-
- <section>
- <title>Example 2 - foreach</title>
- <p>This example illustrates procedural abstraction. Initially, we show the following two examples written as conventional functions:</p>
- <list type="ordered">
- <item>all elements of a list are printed onto a stream</item>
- <item>a message is broadcast to a list of processes.</item>
- </list>
- <code type="none">
-
-print_list(Stream, [H|T]) ->
- io:format(Stream, "~p~n", [H]),
- print_list(Stream, T);
-print_on_list(Stream, []) ->
- true. </code>
- <code type="none">
-
-broadcast(Msg, [Pid|Pids]) ->
- Pid ! Msg,
- broadcast(Msg, Pids);
-broadcast(_, []) ->
- true. </code>
- <p>Both these functions have a very similar structure. They both iterate over a list doing something to each element in the list. The "something" has to be carried round as an extra argument to the function which does this.</p>
- <p>The function <c>foreach</c> expresses this similarity:</p>
- <codeinclude file="funs1.erl" tag="%2" type="erl"></codeinclude>
- <p>Using <c>foreach</c>, <c>print_on_list</c> becomes:</p>
- <code type="none">
-
-foreach(fun(H) -> io:format(S, "~p~n~,[H]) end, L) </code>
- <p><c>broadcast</c> becomes:</p>
- <code type="none">
-
-foreach(fun(Pid) -> Pid ! M end, L) </code>
- <p><c>foreach</c> is evaluated for its side-effect and not its value. <c>foreach(Fun ,L)</c> calls <c>Fun(X)</c> for each element <c>X</c> in <c>L</c> and the processing occurs in the order in which the elements were defined in <c>L</c>. <c>map</c> does not define the order in which its elements are processed.</p>
- </section>
- </section>
-
- <section>
- <title>Advantages of Higher Order Functions</title>
- <p>Programming with higher order functions, such as <c>map</c> and <c>foreach</c>, has a number of advantages:</p>
- <list type="bulleted">
- <item>It is much easier to understand the program and the intention of the programmer is clearly expressed in the code. The statement <c>foreach(fun(X) -></c> clearly indicates that the intention of this program is to do something to each element in the list <c>L</c>. We also know that the function which is passed as the first argument of <c>foreach</c> takes one argument <c>X</c>, which will be successively bound to each of the elements in <c>L</c>.</item>
- <item>Functions which take Funs as arguments are much easier to re-use than other functions. </item>
- </list>
- </section>
-
- <section>
- <title>The Syntax of Funs</title>
- <p>Funs are written with the syntax:</p>
- <code type="none">
-
-F = fun (Arg1, Arg2, ... ArgN) ->
- ...
- end </code>
- <p>This creates an anonymous function of <c>N</c> arguments and binds it to the variable <c>F</c>.</p>
- <p>If we have already written a function in the same module and wish to pass this function as an argument, we can use the following syntax:</p>
- <code type="none">
-
-F = fun FunctionName/Arity </code>
- <p>With this form of function reference, the function which is referred to does not need to be exported from the module.</p>
- <p>We can also refer to a function defined in a different module with the following syntax:</p>
- <code type="none">
-
-F = {Module, FunctionName} </code>
- <p>In this case, the function must be exported from the module in question.</p>
- <p>The follow program illustrates the different ways of creating Funs:</p>
- <codeinclude file="fun_test.erl" tag="%1" type="erl"></codeinclude>
- <p>We can evaluate the fun <c>F</c> with the syntax:</p>
- <code type="none">
-
-F(Arg1, Arg2, ..., Argn) </code>
- <p>To check whether a term is a Fun, use the test <c>function/1</c>
- in a guard. Example:</p>
- <code type="none">
-f(F, Args) when function(F) ->
- apply(F, Args);
-f(N, _) when integer(N) ->
- N. </code>
- <p>Funs are a distinct type. The BIFs erlang:fun_info/1,2 can
- be used to retrieve information about a fun, and the BIF
- erlang:fun_to_list/1 returns a textual representation of a fun.
- The check_process_code/2 BIF returns true if the
- process contains funs that depend on the old version of
- a module.</p>
- <note>
- <p>In OTP R5 and earlier releases, funs were represented
- using tuples.</p>
- </note>
- </section>
-
- <section>
- <title>Variable Bindings within a Fun</title>
- <p>The scope rules for variables which occur in Funs are as follows:</p>
- <list type="bulleted">
- <item>All variables which occur in the head of a Fun are assumed to be "fresh" variables.</item>
- <item>Variables which are defined before the Fun, and which occur in function calls or guard tests within the Fun, have the values they had outside the Fun.</item>
- <item>No variables may be exported from a Fun.</item>
- </list>
- <p>The following examples illustrate these rules:</p>
- <code type="none">
-
-print_list(File, List) ->
- {ok, Stream} = file:open(File, write),
- foreach(fun(X) -> io:format(Stream,"~p~n",[X]) end, List),
- file:close(Stream). </code>
- <p>In the above example, the variable <c>X</c> which is defined in the head of the Fun is a new variable. The value of the variable <c>Stream</c> which is used within within the Fun gets its value from the
- <c>file:open</c> line.</p>
- <p>Since any variable which occurs in the head of a Fun is considered a new variable it would be equally valid to write:</p>
- <code type="none">
-
-print_list(File, List) ->
- {ok, Stream} = file:open(File, write),
- foreach(fun(File) ->
- io:format(Stream,"~p~n",[File])
- end, List),
- file:close(Stream). </code>
- <p>In this example, <c>File</c> is used as the new variable instead of <c>X</c>. This is rather silly since code in the body of the Fun cannot refer to the variable <c>File</c> which is defined outside the Fun. Compiling this example will yield the diagnostic:</p>
- <code type="none">
-
-./FileName.erl:Line: Warning: variable 'File'
- shadowed in 'lambda head' </code>
- <p>This reminds us that the variable <c>File</c> which is defined inside the Fun collides with the variable <c>File</c> which is defined outside the Fun.</p>
- <p>The rules for importing variables into a Fun has the consequence that certain pattern matching operations have to be moved into guard expressions and cannot be written in the head of the Fun. For example, we might write the following code if we intend the first clause of <c>F</c> to be evaluated when the value of its argument is <c>Y</c>:</p>
- <code type="none">
-
-f(...) ->
- Y = ...
- map(fun(X) when X == Y ->
- ;
- (_) ->
- ...
- end, ...)
- ... </code>
- <p>instead of</p>
- <code type="none">
-
-f(...) ->
- Y = ...
- map(fun(Y) ->
- ;
- (_) ->
- ...
- end, ...)
- ... </code>
- </section>
-
- <section>
- <title>Funs and the Module Lists</title>
- <p>The following examples show a dialogue with the Erlang shell. All the higher order functions discussed are exported from the module <c>lists</c>.</p>
-
- <section>
- <title>map</title>
- <codeinclude file="funs1.erl" tag="%1" type="erl"></codeinclude>
- <p><c>map</c> takes a function of one argument and a list of terms. It returns the list obtained by applying the function to every argument in the list.</p>
- <pre>
-
-1> <input>Double = fun(X) -> 2 * X end.</input>
-#Fun&lt;erl_eval>
-2><input>lists:map(Double, [1,2,3,4,5]).</input>
-[2,4,6,8,10] </pre>
- <p>When a new Fun is defined in the shell, the value of the Fun is printed as <c><![CDATA[Fun#<erl_eval>]]></c></p>
- </section>
-
- <section>
- <title>any</title>
- <codeinclude file="funs1.erl" tag="%4" type="erl"></codeinclude>
- <p><c>any</c> takes a predicate <c>P</c> of one argument and a list of terms. A predicate is a function which returns <c>true</c> or <c>false</c>. <c>any</c> is true if there is a term <c>X</c> in the list such that <c>P(X)</c> is <c>true</c>.</p>
- <p>We define a predicate <c>Big(X)</c> which is <c>true</c> if its argument is greater that 10.</p>
- <pre>
-
-3> <input>Big = fun(X) -> if X > 10 -> true; true -> false end end.</input>
-#Fun&lt;erl_eval>
-4><input>lists:any(Big, [1,2,3,4]).</input>
-false.
-5> <input>lists:any(Big, [1,2,3,12,5]).</input>
-true. </pre>
- </section>
-
- <section>
- <title>all</title>
- <codeinclude file="funs1.erl" tag="%3" type="erl"></codeinclude>
- <p><c>all</c> has the same arguments as <c>any</c>. It is true if the predicate applied to all elements in the list is true.</p>
- <pre>
-
-6><input>lists:all(Big, [1,2,3,4,12,6]).</input>
-false
-7><input>lists:all(Big, [12,13,14,15]).</input>
-true </pre>
- </section>
-
- <section>
- <title>foreach</title>
- <codeinclude file="funs1.erl" tag="%2" type="erl"></codeinclude>
- <p><c>foreach</c> takes a function of one argument and a list of terms. The function is applied to each argument in the list. <c>foreach</c> returns <c>ok</c>. It is used for its side-effect only.</p>
- <pre>
-
-8> <input>lists:foreach(fun(X) -> io:format("~w~n",[X]) end, [1,2,3,4]).</input>
-1
-2
-3
-4
-true </pre>
- </section>
-
- <section>
- <title>foldl</title>
- <codeinclude file="funs1.erl" tag="%8" type="erl"></codeinclude>
- <p><c>foldl</c> takes a function of two arguments, an accumulator and a list. The function is called with two arguments. The first argument is the successive elements in the list, the second argument is the accumulator. The function must return a new accumulator which is used the next time the function is called.</p>
- <p>If we have a list of lists <c>L = ["I","like","Erlang"]</c>, then we can sum the lengths of all the strings in <c>L</c> as follows:</p>
- <pre>
-
-9> <input>L = ["I","like","Erlang"].</input>
-["I","like","Erlang"]
-10> <input>lists:foldl(fun(X, Sum) -> length(X) + Sum end, 0, L).</input>
-11 </pre>
- <p><c>foldl</c> works like a <c>while</c> loop in an imperative language:</p>
- <code type="none">
-
- L = ["I","like","Erlang"],
- Sum = 0,
- while( L != []){
- Sum += length(head(L)),
- L = tail(L)
- end </code>
- </section>
-
- <section>
- <title>mapfoldl</title>
- <codeinclude file="funs1.erl" tag="%10" type="erl"></codeinclude>
- <p><c>mapfoldl</c> simultaneously maps and folds over a list. The following example shows how to change all letters in <c>L</c> to upper case and count them.</p>
- <p>First upcase:</p>
- <pre>
-
-11> <input>Upcase = fun(X) when $a =&lt; X, X =&lt; $z -> X + $A - $a;</input>
-<input>(X) -> X</input>
-<input>end.</input>
-#Fun&lt;erl_eval>
-12> <input>Upcase_word =</input>
-<input>fun(X) -></input>
-<input>lists:map(Upcase, X)</input>
-<input>end.</input>
-#Fun&lt;erl_eval>
-13><input>Upcase_word("Erlang").</input>
-"ERLANG"
-14><input>lists:map(Upcase_word, L).</input>
-["I","LIKE","ERLANG"] </pre>
- <p>Now we can do the fold and the map at the same time:</p>
- <pre>
-
-14> <input>lists:mapfoldl(fun(Word, Sum) -></input>
-14> <input>{Upcase_word(Word), Sum + length(Word)}</input>
-14> <input>end, 0, L).</input>
-{["I","LIKE","ERLANG"],11} </pre>
- </section>
-
- <section>
- <title>filter</title>
- <codeinclude file="funs1.erl" tag="%9" type="erl"></codeinclude>
- <p><c>filter</c> takes a predicate of one argument and a list and returns all element in the list which satisfy the predicate.</p>
- <pre>
-
-15><input>lists:filter(Big, [500,12,2,45,6,7]).</input>
-[500,12,45] </pre>
- <p>When we combine maps and filters we can write very succinct and obviously correct code. For example, suppose we want to define a set difference function. We want to define <c>diff(L1, L2)</c> to be the difference between the lists <c>L1</c> and <c>L2</c>.
- This is the list of all elements in L1 which are not contained in L2. This code can be written as follows:</p>
- <code type="none">
-
-diff(L1, L2) ->
- filter(fun(X) -> not member(X, L2) end, L1). </code>
- <p>The AND intersection of the list <c>L1</c> and <c>L2</c> is also easily defined:</p>
- <code type="none">
-
-intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2). </code>
- </section>
-
- <section>
- <title>takewhile</title>
- <codeinclude file="funs1.erl" tag="%5" type="erl"></codeinclude>
- <p><c>takewhile(P, L)</c> takes elements <c>X</c> from a list <c>L</c> as long as the predicate <c>P(X)</c> is true.</p>
- <pre>
-
-16><input>lists:takewhile(Big, [200,500,45,5,3,45,6]).</input>
-[200,500,45] </pre>
- </section>
-
- <section>
- <title>dropwhile</title>
- <codeinclude file="funs1.erl" tag="%6" type="erl"></codeinclude>
- <p><c>dropwhile</c> is the complement of <c>takewhile</c>.</p>
- <pre>
-
-17> <input>lists:dropwhile(Big, [200,500,45,5,3,45,6]).</input>
-[5,3,45,6] </pre>
- </section>
-
- <section>
- <title>splitlist</title>
- <codeinclude file="funs1.erl" tag="%7" type="erl"></codeinclude>
- <p><c>splitlist(P, L)</c> splits the list <c>L</c> into the two sub-lists <c>{L1, L2}</c>, where <c>L = takewhile(P, L)</c> and <c>L2 = dropwhile(P, L)</c>.</p>
- <pre>
-
-18><input>lists:splitlist(Big, [200,500,45,5,3,45,6]).</input>
-{[200,500,45],[5,3,45,6]} </pre>
- </section>
-
- <section>
- <title>first</title>
- <codeinclude file="funs1.erl" tag="%11" type="erl"></codeinclude>
- <p><c>first</c> returns <c>{true, R}</c>, where <c>R</c> is the first element in a list satisfying a predicate or <c>false</c>:</p>
- <pre>
-
-19><input>lists:first(Big, [1,2,45,6,123]).</input>
-{true,45}
-20><input>lists:first(Big, [1,2,4,5]). </input>
-false </pre>
- </section>
- </section>
-
- <section>
- <title>Funs which Return Funs</title>
- <p>So far, this section has only described functions which take Funs as arguments. It is also possible to write more powerful functions which themselves return Funs. The following examples illustrate these type of functions.</p>
-
- <section>
- <title>Simple Higher Order Functions</title>
- <p><c>Adder(X)</c> is a function which, given <c>X</c>, returns a new function <c>G</c> such that <c>G(K)</c> returns <c>K + X</c>.</p>
- <pre>
-
-21> <input>Adder = fun(X) -> fun(Y) -> X + Y end end.</input>
-#Fun&lt;erl_eval>
-22> <input>Add6 = Adder(6).</input>
-#Fun&lt;erl_eval>
-23><input>Add6(10).</input>
-16 </pre>
- </section>
-
- <section>
- <title>Infinite Lists</title>
- <p>The idea is to write something like:</p>
- <code type="none">
-
--module(lazy).
--export([ints_from/1]).
-ints_from(N) ->
- fun() ->
- [N|ints_from(N+1)]
- end. </code>
- <p>Then we can proceed as follows:</p>
- <code type="none"><![CDATA[
-
-24> XX = lazy:ints_from(1).
-#Fun<lazy>
-25> XX().
-[1|#Fun<lazy>]
-26> hd(XX()).
-1
-27> Y = tl(XX()).
-#Fun<lazy>
-28> hd(Y()).
-2 ]]></code>
- <p>etc. - this is an example of "lazy embedding"</p>
- </section>
-
- <section>
- <title>Parsing</title>
- <p>The following examples show parsers of the following type:</p>
- <pre>
-Parser(Toks) -> {ok, Tree, Toks1} | fail </pre>
- <p><c>Toks</c> is the list of tokens to be parsed. A successful parse returns <c>{ok, Tree, Toks1}</c>, where <c>Tree</c> is a parse tree and <c>Toks1</c> is a tail of <c>Tree</c> which contains symbols encountered after the structure which was correctly parsed. Otherwise <c>fail</c> is returned.</p>
- <p>The example which follows illustrates a simple, functional parser which parses the grammar:</p>
- <pre>
-(a | b) &amp; (c | d) </pre>
- <p>The following code defines a function <c>pconst(X)</c> in the module <c>funparse</c>, which returns a Fun which parses a list of tokens.</p>
- <codeinclude file="funparse.erl" tag="%14" type="erl"></codeinclude>
- <p>This function can be used as follows:</p>
- <pre>
-29><input>P1 = funparse:pconst(a).</input>
-#Fun&lt;hof>
-30> <input>P1([a,b,c]).</input>
-{ok,{const,a},[b,c]}
-31> <input>P1([x,y,z]).</input>
-fail </pre>
- <p>Next, we define the two higher order functions <c>pand</c> and <c>por</c> which combine primitive parsers to produce more complex parsers. Firstly <c>pand</c>:</p>
- <codeinclude file="funparse.erl" tag="%16" type="erl"></codeinclude>
- <p>Given a parser <c>P1</c> for grammar <c>G1</c>, and a parser <c>P2</c> for grammar <c>G2</c>, <c>pand(P1, P2)</c>
- returns a parser for the grammar which consists of sequences of tokens which satisfy <c>G1</c> followed by sequences of tokens which satisfy <c>G2</c>.</p>
- <p><c>por(P1, P2)</c> returns a parser for the language described by the grammar <c>G1</c> or <c>G2</c>.</p>
- <codeinclude file="funparse.erl" tag="%15" type="erl"></codeinclude>
- <p>The original problem was to parse the grammar <c><![CDATA[(a | b) & (c | d)]]></c>. The following code addresses this problem: </p>
- <codeinclude file="funparse.erl" tag="%13" type="erl"></codeinclude>
- <p>The following code adds a parser interface to the grammar:</p>
- <codeinclude file="funparse.erl" tag="%12" type="erl"></codeinclude>
- <p>We can test this parser as follows:</p>
- <pre>
-
-32> <input>funparse:parse([a,c]).</input>
-{ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}
-33> <input>funparse:parse([a,d]).</input>
-{ok,{'and',{'or',1,{const,a}},{'or',2,{const,d}}}}
-34> <input>funparse:parse([b,c]).</input>
-{ok,{'and',{'or',2,{const,b}},{'or',1,{const,c}}}}
-35> <input>funparse:parse([b,d]).</input>
-{ok,{'and',{'or',2,{const,b}},{'or',2,{const,d}}}}
-36> <input>funparse:parse([a,b]).</input>
-fail </pre>
- </section>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/funs1.erl b/system/doc/extensions/funs1.erl
deleted file mode 100644
index b1a3e21525..0000000000
--- a/system/doc/extensions/funs1.erl
+++ /dev/null
@@ -1,125 +0,0 @@
--module(funs1).
--compile(export_all).
--import(lists, [reverse/1]).
-
-%1
-map(F, [H|T]) -> [F(H)|map(F, T)];
-map(F, []) -> [].
-%1
-
-%2
-foreach(F, [H|T]) ->
- F(H),
- foreach(F, T);
-foreach(F, []) ->
- ok.
-%2
-%
-%3
-all(Pred, [H|T]) ->
- case Pred(H) of
- true -> all(Pred, T);
- false -> false
- end;
-all(Pred, []) ->
- true.
-%3
-%4
-any(Pred, [H|T]) ->
- case Pred(H) of
- true -> true;
- false -> any(Pred, T)
- end;
-any(Pred, []) ->
- false.
-%4
-%5
-takewhile(Pred, [H|T]) ->
- case Pred(H) of
- true -> [H|takewhile(Pred, T)];
- false -> []
- end;
-takewhile(Pred, []) ->
- [].
-%5
-%6
-dropwhile(Pred, [H|T]) ->
- case Pred(H) of
- true -> dropwhile(Pred, T);
- false -> [H|T]
- end;
-dropwhile(Pred, []) ->
- [].
-%6
-%7
-splitlist(Pred, L) ->
- splitlist(Pred, L, []).
-
-splitlist(Pred, [H|T], L) ->
- case Pred(H) of
- true -> splitlist(Pred, T, [H|L]);
- false -> {reverse(L), [H|T]}
- end;
-splitlist(Pred, [], L) ->
- {reverse(L), []}.
-%7
-
-flatmap(F, [Hd|Tail]) ->
- F(Hd) ++ flatmap(F, Tail);
-flatmap(F, []) -> [].
-
-%8
-foldl(F, Accu, [Hd|Tail]) ->
- foldl(F, F(Hd, Accu), Tail);
-foldl(F, Accu, []) -> Accu.
-%8
-%
-foldr(F, Accu, [Hd|Tail]) ->
- F(Hd, foldr(F, Accu, Tail));
-foldr(F, Accu, []) -> Accu.
-%9
-filter(F, [H|T]) ->
- case F(H) of
- true -> [H|filter(F, T)];
- false -> filter(F, T)
- end;
-filter(F, []) -> [].
-%9
-%10
-mapfoldl(F, Accu0, [Hd|Tail]) ->
- {R,Accu1} = F(Hd, Accu0),
- {Rs,Accu2} = mapfoldl(F, Accu1, Tail),
- {[R|Rs], Accu2};
-mapfoldl(F, Accu, []) -> {[], Accu}.
-%10
-mapfoldr(F, Accu0, [Hd|Tail]) ->
- {Rs,Accu1} = mapfoldr(F, Accu0, Tail),
- {R,Accu2} = F(Hd, Accu1),
- {[R|Rs],Accu2};
-mapfoldr(F, Accu, []) -> {[], Accu}.
-%11
-first(Pred, [H|T]) ->
- case Pred(H) of
- true ->
- {true, H};
- false ->
- first(Pred, T)
- end;
-first(Pred, []) ->
- false.
-%11
-%
-compose(F, G) ->
- fun(X) ->
- F(G(X))
- end.
-
-%20
-iterate(N, F) ->
- iterate(N, N+1, F).
-
-iterate(Stop, Stop, _) ->
- [];
-iterate(N, Stop, Fun) ->
- [Fun(N)|iterate(N+1, Stop, Fun)].
-%20
diff --git a/system/doc/extensions/include.xml b/system/doc/extensions/include.xml
deleted file mode 100644
index cd78644b95..0000000000
--- a/system/doc/extensions/include.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1999</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Includes</title>
- <prepared>Arndt Jonasson</prepared>
- <docno>1</docno>
- <date>99-01-25</date>
- <rev>PA1</rev>
- <file>include.sgml</file>
- </header>
- <p>There are two directives which can be used in Erlang source
- files to cause the compiler to temporarily read input from another
- source. They are typically used to provide macro definitions and
- record definitions from header files. It is recommended to use the
- file name extension <c>".hrl"</c> for files which are meant to be
- included (the 'h' can be read as "header").</p>
- <p>When locating header files a list of directory names, the
- compiler include path, is used. In short the list contains the current
- working directory of the file server, the base name of the compiled
- file, and the directories given by the include option, in that order.
- See <c>erlc(1)</c> and <c>compile(3)</c> for the details of the
- compiler include path.</p>
-
- <section>
- <title>The -include Directive</title>
- <p>The first action taken by the <c>-include</c> directive is to
- check if the format of the first path component of the specified
- filename is <c>$VAR</c>, for some string <c>VAR</c>. If that is the
- case, the value of the environment variable <c>VAR</c> as returned by
- <c>os:getenv(VAR)</c> is substituted for the first path component. If
- <c>os:getenv/1</c> returns <c>false</c>, the first path component is
- left as is. If the filename is absolute (possibly after variable
- substitution), the header file with that name is included. Otherwise,
- the specified header file is searched for in the directories in the
- compiler include path, starting with the first directory in the list.
- The first file found while traversing the list is included. Examples:</p>
- <code type="none">
- -include("my_records.hrl").
- -include("incdir/more_records.hrl").
- -include("/home/users/proj/recs.hrl").
- -include("$PROJ_ROOT/app1/defs.hrl"). </code>
- </section>
-
- <section>
- <title>The -include_lib Directive</title>
- <p>The <c>-include_lib</c> directive first tries to find the
- specified header file using the procedure employed for the
- <c>-include</c> directive. If no header file can be found by searching
- the compiler include path, the first path component of the specified
- filename (possibly after variable substitution) is regarded as the
- name of an application, and the directory of the current version of
- the application is searched. Example:</p>
- <code type="none">
- -include_lib("mnesia/include/mnemosyne.hrl"). </code>
- <p>The compiler is instructed to look for the directory where the
- current version of the <c>mnesia</c> application is installed, that is
- <c>code:lib_dir(mnesia)</c>, and then search the subdirectory
- <c>include</c> for the file <c>mnemosyne.hrl</c>.</p>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/list_comprehensions.erl b/system/doc/extensions/list_comprehensions.erl
deleted file mode 100644
index 21ac562aa5..0000000000
--- a/system/doc/extensions/list_comprehensions.erl
+++ /dev/null
@@ -1,118 +0,0 @@
--module(t).
--author('[email protected]').
-
-%%-export([test/2]).
--compile(export_all).
-
-%% Odd numbers.
-
-%%foo(L) -> [ X || X <- L, (X > X-1) == (X /= X-1) ].
-
-bar(L) -> [ X || X <- L, integer(X), gt(X, 3) ].
-
-bar(L, M) -> [ Y || X <- L, integer(X), gt(X, 3),
- Y <- M, float(Y), gt(X, Y)
- ].
-
-baz(L) -> [ X || X <- L, atom(X) ].
-
-buz(L, Min) -> [ X || Min > 3, X <- L, X >= Min ].
-
-gt(X, Y) when X > Y -> true;
-gt(X, Y) -> false.
-
-%% Turn a list into a set.
-make_set([]) -> [];
-make_set([H|T]) ->
- [H|[
- Y || Y <- make_set(T),
- Y =/= H
- ]].
-
-%% Return the Pythagorean triangles with sides
-%% of total length less than N
-pyth(N) ->
- [ {A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N),
- C <- lists:seq(1,N),
- A+B+C =< N,
- A*A+B*B == C*C
- ].
-
-%% Cut the search space a bit..
-pyth2(N) ->
- [ {A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N-A+1),
- C <- lists:seq(1,N-A-B+2),
- A+B+C =< N,
- A*A+B*B == C*C ].
-
-%% Return the Cartesian product
-cp() ->
- [ {X,Y} ||
- X <- a(),
- Y <- b()
- ].
-
-cp(A,B) when list(A),list(B) ->
- [ {X,Y} ||
- X <- A,
- Y <- B
- ].
-
-%a() -> 1/0.
-a() -> [a,b].
-b() -> [1,2,3].
-
-%% Return all permutations of a list
-perms([]) -> [[]];
-perms(L) -> [ [H|T] || H <- L, T <- perms(L--[H]) ].
-
-%% Quick sort
-sort([X|Xs]) ->
- sort([ Y || Y <- Xs, Y < X ]) ++
- [X] ++
- sort([ Y || Y <- Xs, Y >= X ]);
-sort([]) -> [].
-
-%% Vector addition
-vecAdd(Xs,Ys) ->
- [ X+Y || {X,Y} <- zip(Xs,Ys) ].
-
-zip([X|Xs],[Y|Ys]) -> [{X,Y}|zip(Xs,Ys)];
-zip([],[]) -> [].
-
-qsort([X|Xs]) ->
- qsort(lt(X,Xs))
- ++ [X] ++
- qsort(ge(X,Xs));
-qsort([]) -> [].
-
-lt(X,[H|T]) when X>H -> [H|lt(X,T)];
-lt(X,[_|T]) -> lt(X,T);
-lt(_,[]) -> [].
-
-ge(X,[H|T]) when X=<H -> [H|ge(X,T)];
-ge(X,[_|T]) -> ge(X,T);
-ge(_,[]) -> [].
-
-test(1,N) -> statistics(runtime),test1(N),statistics(runtime);
-test(2,N) -> statistics(runtime),test2(N),statistics(runtime);
-test(3,N) -> statistics(runtime),test3(N),statistics(runtime).
-
-test1(0) -> true;
-test1(N) ->
- sort([21,12,45,1,3,87,55,77,11,20,6,99,91,13,14,15,66,62,69,71,67,82,83,84,87,86,85]),
- test1(N-1).
-
-test2(0) -> true;
-test2(N) ->
- qsort([21,12,45,1,3,87,55,77,11,20,6,99,91,13,14,15,66,62,69,71,67,82,83,84,87,86,85]),
- test2(N-1).
-
-test3(0) -> true;
-test3(N) ->
- lists:sort([21,12,45,1,3,87,55,77,11,20,6,99,91,13,14,15,66,62,69,71,67,82,83,84,87,86,85]),
- test3(N-1).
diff --git a/system/doc/extensions/list_comprehensions.xml b/system/doc/extensions/list_comprehensions.xml
deleted file mode 100644
index 30e32da79c..0000000000
--- a/system/doc/extensions/list_comprehensions.xml
+++ /dev/null
@@ -1,205 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>List Comprehensions</title>
- <prepared>Joe Armstrong</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno>1</docno>
- <approved>Bjarne D&auml;Ker</approved>
- <checked></checked>
- <date>96-09-10</date>
- <rev>PA1</rev>
- <file>list_comprehensions.sgml</file>
- </header>
- <p>List comprehensions are a feature of many modern functional programming languages. Subject to certain rules, they provide a succinct notation for generating elements in a list.</p>
- <p>List comprehensions are analogous to set comprehensions
- in Zermelo-Frankel set theory and are called ZF expressions in
- Miranda. They are analogous to the <c>setof</c> and
- <c>findall</c> predicates in Prolog.</p>
- <p>List comprehensions are written with the following syntax:
- </p>
- <code type="none">
-
-[Expression || Qualifier1, Qualifier2, ...] </code>
- <p><c>Expression</c> is an arbitrary expression, and each <c>Qualifier</c> is either a generator or a filter.</p>
- <list type="bulleted">
- <item>A <em>generator</em> written as <c><![CDATA[Pattern <- ListExpr]]></c>. <c>ListExpr</c> must be an expression which evaluates to a list of terms.</item>
- <item>A <em>filter</em> is either a predicate or a boolean expression. A predicate is a function which returns <c>true</c> or <c>false</c>.</item>
- </list>
-
- <section>
- <title>Examples of List Comprehensions</title>
- <p>We start with a simple example:</p>
- <code type="none"><![CDATA[
-
-> [X || X <- [1,2,a,3,4,b,5,6], X > 3].
-[a,4,b,5,6] ]]></code>
- <p>This should be read as follows:</p>
- <quote>
- <p>The list of X such that X is taken from the list <c>[1,2,a,...]</c> and X is greater than 3.</p>
- </quote>
- <p>The notation <c><![CDATA[X <- [1,2,a,...]]]></c> is a generator and the expression <c>X > 3</c> is a filter.</p>
- <p>An additional filter can be added in order to restrict the result to integers:</p>
- <code type="none"><![CDATA[
-
-> [X || X <- [1,2,a,3,4,b,5,6], integer(X), X > 3].
-[4,5,6] ]]></code>
- <p>Generators can be combined. For example, the Cartesian product of two lists can be written as follows:</p>
- <code type="none"><![CDATA[
-
-> [{X, Y} || X <- [1,2,3], Y <- [a,b]].
-[{1,a},{1,b},{2,a},{2,b},{3,a},{3,b}] ]]></code>
-
- <section>
- <title>Quick Sort</title>
- <p>The well known quick sort routine can be written as follows:</p>
- <code type="none"><![CDATA[
-
-sort([Pivot|T]) ->
- sort([ X || X <- T, X < Pivot]) ++
- [Pivot] ++
- sort([ X || X <- T, X >= Pivot]);
-sort([]) -> []. ]]></code>
- <p>The expression <c><![CDATA[[X || X <- T, X < Pivot]]]></c> is the list of all elements in <c>T</c>, which are less than <c>Pivot</c>.</p>
- <p><c><![CDATA[[X || X <- T, X >= Pivot]]]></c> is the list of all elements in <c>T</c>, which are greater or equal to <c>Pivot</c>.</p>
- <p>To sort a list, we isolate the first element in the list and split the list into two sub-lists. The first sub-list contains all elements which are smaller than the first element in the list, the second contains all elements which are greater than or equal to the first element in the list. We then sort the sub-lists and combine the results.</p>
- </section>
-
- <section>
- <title>Permutations</title>
- <p>The following example generates all permutations of the elements in a list:</p>
- <code type="none"><![CDATA[
-
-perms([]) -> [[]];
-perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])]. ]]></code>
- <p>We take take <c>H</c> from <c>L</c> in all possible ways. The result is the set of all lists <c>[H|T]</c>, where <c>T</c> is the set of all possible permutations of <c>L</c> with <c>H</c> removed.</p>
- <code type="none">
-
-> perms([b,u,g]).
-[[b,u,g],[b,g,u],[u,b,g],[u,g,b],[g,b,u],[g,u,b]] </code>
- </section>
-
- <section>
- <title>Pythagorean Triplets</title>
- <p>Pythagorean triplets are sets of integers <c>{A,B,C}</c> such that <c>A**2 + B**2 = C**2</c>.</p>
- <p>The function <c>pyth(N)</c> generates a list of all integers <c>{A,B,C}</c> such that <c>A**2 + B**2 = C**2</c> and where the sum of the sides is less than <c>N</c>.</p>
- <code type="none"><![CDATA[
-
-pyth(N) ->
- [ {A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N),
- C <- lists:seq(1,N),
- A+B+C =< N,
- A*A+B*B == C*C
- ]. ]]></code>
- <pre>
-
-> <input>pyth(3).</input>
-[].
-> <input>pyth(11).</input>
-[].
-><input>pyth(12).</input>
-[{3,4,5},{4,3,5}]
-> <input>pyth(50).</input>
-[{3,4,5},
- {4,3,5},
- {5,12,13},
- {6,8,10},
- {8,6,10},
- {8,15,17},
- {9,12,15},
- {12,5,13},
- {12,9,15},
- {12,16,20},
- {15,8,17},
- {16,12,20}]</pre>
- <p>The following code reduces the search space and is more efficient:</p>
- <code type="none"><![CDATA[
-
-pyth1(N) ->
- [{A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N-A+1),
- C <- lists:seq(1,N-A-B+2),
- A+B+C =< N,
- A*A+B*B == C*C ]. ]]></code>
- </section>
-
- <section>
- <title>Simplifications with List Comprehensions</title>
- <p>As an example, list comprehensions can be used to simplify some of the functions in <c>lists.erl</c>:</p>
- <code type="none"><![CDATA[
-
-append(L) -> [X || L1 <- L, X <- L1].
-map(Fun, L) -> [Fun(X) || X <- L].
-filter(Pred, L) -> [X || X <- L, Pred(X)]. ]]></code>
- </section>
- </section>
-
- <section>
- <title>Variable Bindings in List Comprehensions</title>
- <p>The scope rules for variables which occur in list comprehensions are as follows:</p>
- <list type="bulleted">
- <item>all variables which occur in a generator pattern are assumed to be "fresh" variables</item>
- <item>any variables which are defined before the list comprehension and which are used in filters have the values they had before the list comprehension</item>
- <item>no variables may be exported from a list comprehension.</item>
- </list>
- <p>As an example of these rules, suppose we want to write the function <c>select</c>, which selects certain elements from a list of tuples. We might write <c><![CDATA[select(X, L) -> [Y || {X, Y} <- L].]]></c> with the intention of extracting all tuples from <c>L</c> where the first item is <c>X</c>.</p>
- <p>Compiling this yields the following diagnostic:</p>
- <code type="none">
-
-./FileName.erl:Line: Warning: variable 'X' shadowed in generate </code>
- <p>This diagnostic warns us that the variable <c>X</c> in the pattern is not the same variable as the variable <c>X</c> which occurs in the function head.</p>
- <p>Evaluating <c>select</c> yields the following result:</p>
- <pre>
-
-> <input>select(b,[{a,1},{b,2},{c,3},{b,7}]).</input>
-[1,2,3,7] </pre>
- <p>This result is not what we wanted. To achieve the desired effect we must write <c>select</c> as follows:</p>
- <code type="none"><![CDATA[
-
-select(X, L) -> [Y || {X1, Y} <- L, X == X1]. ]]></code>
- <p>The generator now contains unbound variables and the test has been moved into the filter. This now works as expected:</p>
- <pre>
-
-> <input>select(b,[{a,1},{b,2},{c,3},{b,7}]).</input>
-[2,7] </pre>
- <p>One consequence of the rules for importing variables into a list comprehensions is that certain pattern matching operations have to be moved into the filters and cannot be written directly in the generators. To illustrate this, do <em>not</em> write as follows:</p>
- <code type="none"><![CDATA[
-
-f(...) ->
- Y = ...
- [ Expression || PatternInvolving Y <- Expr, ...]
- ... ]]></code>
- <p>Instead, write as follows:</p>
- <code type="none"><![CDATA[
-
-f(...) ->
- Y = ...
- [ Expression || PatternInvolving Y1 <- Expr, Y == Y1, ...]
- ...
- ]]></code>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/list_comrehensions.erl b/system/doc/extensions/list_comrehensions.erl
deleted file mode 100644
index f6a23b5dca..0000000000
--- a/system/doc/extensions/list_comrehensions.erl
+++ /dev/null
@@ -1,75 +0,0 @@
--module(zf).
-
--compile(export_all).
-
-
-%% Odd numbers.
-
-%%foo(L) -> [ X || X <- L, (X > X-1) == (X /= X-1) ].
-
-boo() -> [X||X <- [1,2,a,3,4,b,5,6], X > 3].
-boo1() -> [X||X <- [1,2,a,3,4,b,5,6], integer(X),X > 3].
-boo2() -> [{X,Y} || X <- [1,2,3], Y <- [a,b]].
-
-bar(L) -> [ X || X <- L, integer(X), gt(X, 3) ].
-
-bar(L, M) -> [ Y || X <- L, integer(X), gt(X, 3),
- Y <- M, float(Y), gt(X, Y)
- ].
-
-baz(L) -> [ X || X <- L, atom(X) ].
-
-buz(L, Min) -> [ X || Min > 3, X <- L, X >= Min ].
-
-gt(X, Y) when X > Y -> true;
-gt(X, Y) -> false.
-
-
-%% Return the Pythagorean triangles with sides
-%% of total length less than N
-pyth(N) ->
- [ {A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N),
- C <- lists:seq(1,N),
- A+B+C =< N,
- A*A+B*B == C*C
- ].
-
-%% Cut the search space a bit..
-pyth2(N) ->
- [ {A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N-A+1),
- C <- lists:seq(1,N-A-B+2),
- A+B+C =< N,
- A*A+B*B == C*C ].
-
-%% Return the Cartesian product
-
-cp(A,B) ->
- [ {X,Y} ||
- X <- A,
- Y <- B
- ].
-
-%% Return all permutations of a list
-perms([]) -> [[]];
-perms(L) -> [ [H|T] || H <- L, T <- perms(L--[H]) ].
-
-%% Quick sort
-sort([X|Xs]) ->
- sort([ Y || Y <- Xs, Y < X ]) ++
- [X] ++
- sort([ Y || Y <- Xs, Y >= X ]);
-sort([]) -> [].
-
-%% append
-
-append(L) -> [X||L1<-L,X<-L1].
-
-map(Fun, L) -> [Fun(X)||X<-L].
-
-filter(Pred, L) -> [X||X<-L,Pred(X)].
-
-select(X, L) -> [Y || {X1,Y} <- L, X == X1].
diff --git a/system/doc/extensions/macros.xml b/system/doc/extensions/macros.xml
deleted file mode 100644
index feb3de6102..0000000000
--- a/system/doc/extensions/macros.xml
+++ /dev/null
@@ -1,177 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Macros</title>
- <prepared>Joe Armstrong</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno>1</docno>
- <approved>Bjarne D&auml;Ker</approved>
- <checked></checked>
- <date>96-09-10</date>
- <rev>PA1</rev>
- <file>macros.sgml</file>
- </header>
- <p>Macros in Erlang are written with the following syntax:</p>
- <code type="none">
-
--define(Const, Replacement).
--define(Fun(Var1, Var2,.., Var), Replacement). </code>
- <p>Macros are expanded when the syntax <c>?MacroName</c> is encountered.</p>
- <p>Consider the macro definition:</p>
- <code type="none">
-
--define(timeout, 200). </code>
- <p>The expression <c>?timeout</c>, which can occur anywhere in the code which follows the macro definition, will be replaced by <c>200</c>.</p>
- <p>Macros with arguments are written as follows:</p>
- <code type="none">
-
- -define(macro1(X, Y), {a, X, b, Y}). </code>
- <p>This type of macro can be used as follows:</p>
- <code type="none">
-
-bar(X) ->
- ?macro1(a, b),
- ?macro1(X, 123) </code>
- <p>This expands to:</p>
- <code type="none">
-
-bar(X) ->
- {a,a,b,b},
- {a,X,b,123}. </code>
-
- <section>
- <title>Macros and Tokens</title>
- <p>Macro expansion works at a token level. We might define a macro as follows:</p>
- <code type="none">
-
--define(macro2(X, Y), {a,X,b,Y). </code>
- <p>The replacement value of the macro is not a valid Erlang term because the closing right curly bracket is missing. <c>macro2</c> expands into a sequence of tokens <c>{</c>, <c>a</c>, <c>X</c> which are then pasted into the place where the macro is used.</p>
- <p>We might use this macro as follows:</p>
- <code type="none">
-
-bar() ->
- ?macro2(x,y)}. </code>
- <p>This will expand into the valid sequence of tokens <c>{a,x,y,b}</c> before being parsed and compiled.</p>
- <note>
- <p>It is good programming practise to ensure that the replacement text of a macro is a valid Erlang syntactic form.</p>
- </note>
- </section>
-
- <section>
- <title>Pre-Defined Macros</title>
- <p>The following macros are pre-defined:</p>
- <taglist>
- <tag><c>?MODULE</c>. </tag>
- <item>This macro returns the name of the current module.
- </item>
- <tag><c>?MODULE_STRING</c>. </tag>
- <item>This macro returns the name of the current module, as a string.</item>
- <tag><c>?FILE</c>.</tag>
- <item>This macro returns the current file name.</item>
- <tag><c>?LINE</c>.</tag>
- <item>This macro returns the current line number.</item>
- <tag><c>?MACHINE</c>.</tag>
- <item>This macro returns the current machine name,
- <c>'BEAM'</c>,</item>
- </taglist>
- </section>
-
- <section>
- <title>Stringifying Macro Arguments</title>
- <p>The construction <c>??Arg</c> for an argument to a macro expands to a
- string containing the tokens of the argument, similar to the
- <c>#arg</c> stringifying construction in C. This was added in Erlang
- 5.0 (OTP R7A).</p>
- <p>Example:</p>
- <code type="none">
--define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).
-
-?TESTCALL(myfunction(1,2)),
-?TESTCALL(you:function(2,1)).</code>
- <p>results in</p>
- <code type="none">
-io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",m:myfunction(1,2)]),
-io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).</code>
- </section>
-
- <section>
- <title>Flow Control in Macros</title>
- <p>The following macro directives are supplied:</p>
- <taglist>
- <tag>-undef(Macro).</tag>
- <item>Causes the macro to behave as if it had never been defined.</item>
- <tag>-ifdef(Macro).</tag>
- <item>Do the following lines if <c>Macro</c> is defined.</item>
- <tag>-ifndef(Macro).</tag>
- <item>Do the following lines if <c>Macro</c> is not defined.</item>
- <tag>-else.</tag>
- <item>"else" macro</item>
- <tag>-endif.</tag>
- <item>"endif" macro.</item>
- </taglist>
- <p>The conditional macros must be properly nested. They are usually grouped as follows:</p>
- <code type="none">
-
--ifdef(debug)
--define(....)
--else
--define(...)
--endif </code>
- <p>The following example illustrates this grouping:</p>
- <code type="none">
-
--define(debug, true).
--ifdef(debug).
--define(trace(Str, X), io:format("Mod:~w line:~w ~p ~p~n",
- [?MODULE,?LINE, Str, X])).
--else.
--define(trace(X, Y), true).
--endif. </code>
- <p>Given these definitions, the expression <c>?trace("X=", X).</c> in line 10 of the module <c>foo</c> expands to:</p>
- <code type="none">
-
-io:format("Mod:~w line:~w ~p ~p~n",[foo,100,"X=",[X]]), </code>
- <p>If we remove the <c>-define(debug, true).</c> line, then the same expression expands to <c>true</c>.</p>
- </section>
-
- <section>
- <title>A Macro Expansion Utility</title>
- <p>The following code can be used to expand a macro and display the result:</p>
- <code type="none">
-
--module(mexpand).
--export([file/1]).
--import(lists, [foreach/2]).
-file(File) ->
- case epp:parse_file(File ++ ".erl", [],[]) of
- {ok, L} ->
- {ok, Stream} = file:open(File ++ ".out", write),
- foreach(fun(X) ->
- io:format(Stream,"~s~n",[erl_pp:form(X)])
- end, L),
- file:close(Stream)
- end.</code>
- <p>Alternatively, we can compile the file with the <c>'P'</c> option. <c>compile:file(File, ['P'])</c> produces a list file <c>File.P</c>, in which the result of any macro expansions can be seen.</p>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/make.dep b/system/doc/extensions/make.dep
deleted file mode 100644
index fdac959667..0000000000
--- a/system/doc/extensions/make.dep
+++ /dev/null
@@ -1,21 +0,0 @@
-# ----------------------------------------------------
-# >>>> Do not edit this file <<<<
-# This file was automaticly generated by
-# /home/otp/bin/docdepend
-# ----------------------------------------------------
-
-
-# ----------------------------------------------------
-# TeX files that the DVI file depend on
-# ----------------------------------------------------
-
-book.dvi: bit_syntax.tex book.tex funs.tex include.tex \
- list_comprehensions.tex macros.tex misc.tex \
- part.tex records.tex
-
-# ----------------------------------------------------
-# Source inlined when transforming from source to LaTeX
-# ----------------------------------------------------
-
-funs.tex: fun_test.erl funparse.erl funs1.erl
-
diff --git a/system/doc/extensions/mexpand.erl b/system/doc/extensions/mexpand.erl
deleted file mode 100644
index 261f99da46..0000000000
--- a/system/doc/extensions/mexpand.erl
+++ /dev/null
@@ -1,16 +0,0 @@
--module(mexpand).
-
--export([file/1]).
-
--import(lists, [foreach/2]).
-
-file(File) ->
- case epp:parse_file(File ++ ".erl", [],[]) of
- {ok, L} ->
- {ok, Stream} = file:open(File ++ ".out", write),
- foreach(fun(X) ->
- io:format(Stream,"~s~n",
- [erl_pp:form(X)])
- end, L),
- file:close(Stream)
- end.
diff --git a/system/doc/extensions/misc.xml b/system/doc/extensions/misc.xml
deleted file mode 100644
index 576f705278..0000000000
--- a/system/doc/extensions/misc.xml
+++ /dev/null
@@ -1,310 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1999</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Miscellaneous</title>
- <prepared>Arndt Jonasson</prepared>
- <docno>1</docno>
- <date>99-01-25</date>
- <rev>PA1</rev>
- <file>misc.sgml</file>
- </header>
- <p>In this chapter, a number of miscellaneous features of Erlang
- are described.</p>
-
- <section>
- <title>Token Syntax</title>
- <p>In Erlang 4.8 (OTP R5A) the syntax of Erlang tokens have been
- extended to allow the use of the full ISO-8859-1 (Latin-1) character
- set. This is noticeable in the following ways:</p>
- <list type="bulleted">
- <item>All the Latin-1 printable characters can be used and are shown without
- the escape backslash convention.</item>
- <item>Atoms and variables can use all Latin-1 letters.</item>
- </list>
- <p>The new characters from Latin-1 have the following
- classifications in Erlang:</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Octal</em></cell>
- <cell align="left" valign="middle"><em>Decimal</em></cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle"><em>Class</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">200 - 237</cell>
- <cell align="left" valign="middle">128 - 159</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">Control characters</cell>
- </row>
- <row>
- <cell align="left" valign="middle">240 - 277</cell>
- <cell align="left" valign="middle">160 - 191</cell>
- <cell align="right" valign="middle">- &iquest;</cell>
- <cell align="left" valign="middle">Punctuation characters</cell>
- </row>
- <row>
- <cell align="left" valign="middle">300 - 326</cell>
- <cell align="left" valign="middle">192 - 214</cell>
- <cell align="center" valign="middle">&Agrave; - &Ouml;</cell>
- <cell align="left" valign="middle">Uppercase letters</cell>
- </row>
- <row>
- <cell align="center" valign="middle">327</cell>
- <cell align="center" valign="middle">215</cell>
- <cell align="center" valign="middle">&times;</cell>
- <cell align="left" valign="middle">Punctuation character</cell>
- </row>
- <row>
- <cell align="left" valign="middle">330 - 336</cell>
- <cell align="left" valign="middle">216 - 222</cell>
- <cell align="center" valign="middle">&Oslash; - &THORN;</cell>
- <cell align="left" valign="middle">Uppercase letters</cell>
- </row>
- <row>
- <cell align="left" valign="middle">337 - 366</cell>
- <cell align="left" valign="middle">223 - 246</cell>
- <cell align="center" valign="middle">&szlig; - &ouml;</cell>
- <cell align="left" valign="middle">Lowercase letters</cell>
- </row>
- <row>
- <cell align="center" valign="middle">367</cell>
- <cell align="center" valign="middle">247</cell>
- <cell align="center" valign="middle">&divide;</cell>
- <cell align="left" valign="middle">Punctuation character</cell>
- </row>
- <row>
- <cell align="left" valign="middle">370 - 377</cell>
- <cell align="left" valign="middle">248 - 255</cell>
- <cell align="center" valign="middle">&oslash; - &yuml;</cell>
- <cell align="left" valign="middle">Lowercase letters</cell>
- </row>
- <tcaption>Character classes</tcaption>
- </table>
- </section>
-
- <section>
- <title>String Concatenation</title>
- <p>Two adjacent string literals are concatenated into one. This is done already
- at compile-time, and doesn't incur any runtime overhead. Example:</p>
- <code type="none">
- "string" "42" </code>
- <p>is equivalent to</p>
- <code type="none">
- "string42" </code>
- <p>This feature is convenient in at least two situations:</p>
- <list type="bulleted">
- <item>when one of the
- strings is the result of a macro expansion;</item>
- <item>when a string is very
- long, and would otherwise either have to wrap, making the source code
- harder to read, or force the use of some runtime append operation.</item>
- </list>
- </section>
-
- <section>
- <title>The ++ list Concatenation Operator</title>
- <p>Since list concatenation is a very common operation, it is convenient
- to have a terse way of expressing it. The ++ operator appends its second
- argument to its first. Example:
- </p>
- <code type="none">
- X = [1,2,3],
- Y = [4,5],
- X ++ Y. </code>
- <p>results in <c>[1,2,3,4,5]</c>.</p>
- <p>The ++ operator has precedence between the binary '+' operator and
- the comparison operators.
- </p>
- </section>
-
- <section>
- <title>The - - list Subtraction Operator</title>
- <p>The - - operator produces a list which is a copy of the first
- argument, subjected to the following procedure: for each element in
- the second argument, its first occurrence in the first argument is
- removed.</p>
- <code type="none">
- X = [1,2,3,2,1,2],
- Y = [2,1,2],
- X -- Y. </code>
- <p>results in <c>[3,1,2]</c>.</p>
- <p>The - - operator has precedence between the binary '+' operator and
- the comparison operators.
- </p>
- </section>
-
- <section>
- <title>Bitwise Operator bnot</title>
- <p>Apart from the binary bitwise operators <c>band</c>, <c>bor</c>
- and <c>bxor</c>, there is a unary operator <c>bnot</c> with the same
- precedence as the other unary operators + and -, i.e., higher than
- the binary operators. Example:</p>
- <code type="none">
- bnot 7. </code>
- <p>returns -8.
- </p>
- </section>
-
- <section>
- <title>Logical Operators</title>
- <p>The atoms <c>true</c> and <c>false</c> are usually used for representing
- Boolean values. With the binary operators <c>and</c>, <c>or</c> and
- <c>xor</c>, and the unary operator <c>not</c>, Boolean values can be
- combined. Example:</p>
- <code type="none">
-
- M1 = lists:member(A, List1),
- M2 = lists:member(A, List2),
- M1 and M2.</code>
- <p>Note that the operators are strict, i.e., they always evaluate both
- their arguments.</p>
- <p><c>not</c> has the same priority as the other unary operators. The
- binary logical operators have precedence between the <c>=</c> operator
- and the comparison operators, the <c>and</c> operator having higher
- precedence than <c>or</c> and <c>xor</c>.
- </p>
- </section>
-
- <section>
- <title>Match Operator = In Patterns</title>
- <p>This extension was added in Erlang 4.8 (OTP R5A).</p>
- <p>The = operator is also called the `match' operator. The match operator
- can now be used in a pattern, so that <c>P1 = P2</c> is a valid pattern,
- where both <c>P1</c> and <c>P2</c> are patterns. This compound pattern
- when matched against a term causes the term to be matched against both
- <c>P1</c> and <c>P2</c>.</p>
- <p>One use for this construction is to avoid reconstructing a term which
- was part of an argument to a function. Example:</p>
- <code type="none">
- f({'+',X,Y}=T) -> {X+Y,T}.</code>
- <p>It also makes it possible to rewrite the construction</p>
- <code type="none">
- f(X) when X == #rec{x=1, y=a} -> ... </code>
- <p>as</p>
- <code type="none">
- f(#rec{x=1, y=a} = X) -> ... </code>
- <p>In the absence of optimization for the former case, the
- latter case is more efficient.
- </p>
- </section>
-
- <section>
- <title>Literal String Prefix in Patterns</title>
- <p>This extension was added in Erlang 4.8 (OTP R5A).</p>
- <p>A new construction is allowed in patterns, namely a literal
- string as the first operand of the ++ operator. Example:</p>
- <code type="none">
- f("prefix" ++ L) -> ... </code>
- <p>This is syntactic sugar for the equivalent, but harder to read</p>
- <code type="none">
- f([$p,$r,$e,$f,$i,$x | L]) -> ... </code>
- </section>
-
- <section>
- <title>Disjunctions in Guards</title>
- <p>This extension was added in Erlang 4.9 (OTP R6A).</p>
- <p>A new construction is allowed in guards, the disjunction operator
- ';'. The construction is syntactic sugar which removes the bother of
- writing the same body after several guards.</p>
- <code type="none">
- f(X) when xxx ; yyy ; zzz ->
- pop(X).</code>
- <p>This is syntactic sugar for the equivalent</p>
- <code type="none">
- f(X) when xxx ->
- pop(X);
- f(X) when yyy ->
- pop(X);
- f(X) when zzz ->
- pop(X). </code>
- <p>The abstract format has been changed accordingly to contain a list of
- (conjunctive) guards where there was previously only one guard.
- </p>
- </section>
-
- <section>
- <title>Expressions in Patterns</title>
- <p>This extension was added in Erlang 5.0 (OTP R7A).</p>
- <p>An arithmetic expression can be used within a pattern, if it uses
- only numeric or bitwise operators, and if its value can be evaluated
- to a constant at compile-time. This is especially useful when the
- expression is defined by a macro.
- </p>
- <p>Example:</p>
- <code type="none">
- case X of
- {1+2, T} -> T
- end.</code>
- </section>
-
- <section>
- <title>Boolean expresions in guards</title>
- <p>This extension was added in Erlang 5.1 (OTP R8).</p>
- <p>In guards, the use of <c>and</c>, <c>or</c> and <c>not</c> is
- now allowed. Guard expressions can combine these with
- parenthesis. This allows for more elaborate guards than what
- may be given with <c>,</c> and <c>;</c>.</p>
- <note>
- <p>The guard expressions written with these operators are boolean
- expressions, and the boolean functions <c>is_list</c>,
- <c>is_integer</c> etc. should be used, rather than
- <c>list</c>, <c>integer</c> etc.</p>
- </note>
- <p>Example 1:</p>
- <code type="none">
- f(X) when not (is_tuple(X) or is_list(X)) ->
- ... </code>
- <p>Example 2:</p>
- <code type="none"><![CDATA[
- g(A, B) when (A > 0) and (B > 0) and not (A*A < B*B) ->
- ... ]]></code>
- </section>
-
- <section>
- <title>Short-circuit boolean expressions</title>
- <p>This extension was added in Erlang 5.1 (OTP R8).</p>
- <p>In a boolean expression it is unnecessary to always evaluate all
- terms. If the first term gives a result that determines the
- result, the second term is not needed. In Erlang two new
- keywords handles boolean expressions without evaluating both
- terms, if it's unnecessary. (This is called short-curcuit
- boolean evaluation.)</p>
- <p>The keyword <c>andalso</c> is a short-curcuit version of
- <c>and</c>. The keyword <c>orelse</c> is a short-curcuit version
- of <c>or</c>. They can be used in boolean expressions (not
- guards) instead of <c>and</c> and <c>or</c>.</p>
- <p>Example 1:</p>
- <code type="none">
- case A >= -1.0 andalso math:sqrt(A+1) > B of </code>
- <p>This will work even if <c>A</c> is less than <c>-1.0</c>, since
- in that case, the second term (after <c>andalso</c>) is never
- evaluated. (Of course, the same effects could have been done
- using guards. In guards, evaluation is always short-circuited,
- since guard tests are known to be free of side-effects.)</p>
- <p>Example 2:</p>
- <code type="none">
- OnlyOne = is_atom(L) orelse
- (is_list(L) andalso length(L) == 1), </code>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/part.xml b/system/doc/extensions/part.xml
deleted file mode 100644
index 56fd2c09a6..0000000000
--- a/system/doc/extensions/part.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part>
- <header>
- <copyright>
- <year>1997</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Erlang Extensions Since 4.4</title>
- <prepared>OTP Team</prepared>
- <docno></docno>
- <date>1997-02-21</date>
- <rev>E</rev>
- <file>part.sgml</file>
- </header>
- <description>
- <p>This chapter describes extensions made to the Erlang language
- since version 4.4 (where nothing is said to the contrary, an extension
- was added in version 4.4).
- The chapter contains the following sections:
- </p>
- <list type="bulleted">
- <item>Records</item>
- <item>Functional Objects (Funs)</item>
- <item>List Comprehensions</item>
- <item>Macros</item>
- <item>File inclusion</item>
- <item>Bit syntax</item>
- <item>Miscellaneous</item>
- </list>
- </description>
- <include file="records"></include>
- <include file="funs"></include>
- <include file="list_comprehensions"></include>
- <include file="macros"></include>
- <include file="include"></include>
- <include file="bit_syntax"></include>
- <include file="misc"></include>
-</part>
-
diff --git a/system/doc/extensions/records.xml b/system/doc/extensions/records.xml
deleted file mode 100644
index 21ec73ab77..0000000000
--- a/system/doc/extensions/records.xml
+++ /dev/null
@@ -1,284 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Records</title>
- <prepared>Joe Armstrong</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno>1</docno>
- <approved>Bjarne D&auml;Ker</approved>
- <checked></checked>
- <date>96-09-10</date>
- <rev>PA1</rev>
- <file>records.sgml</file>
- </header>
- <p>A record is a data structure intended for storing a fixed number of related data items. It is
- similar to a <c>struct</c> in C, or a <c>record</c> in Pascal. </p>
- <p>The main advantage of using records instead of tuples is that fields in a record are accessed by name, whereas fields in a tuple are accessed by position. To illustrate these differences, suppose that we want to represent a person with the <em>tuple</em><c>{Name, Address, Phone}</c>.</p>
- <p>We must remember that the <c>Name</c> field is the first element of the tuple, the <c>Address</c> field is the second element, and so on, in order to write functions which manipulate this data. For example, to extract data from a variable <c>P</c> which contains such a tuple we might write the following code and then use pattern matching to extract the relevant fields.</p>
- <code type="none">
-
-Name = element(1, P),
-Address = element(2, P),
-... </code>
- <p>Code like this is difficult to read and understand and errors occur if we get the numbering of the elements in the tuple wrong. If we change the data representation by re-ordering the fields, or by adding or removing a field, then all references to the person tuple, wherever they occur, must be checked and possibly modified.</p>
- <p><em>Records</em> allow us to refer to the fields by name and not position. We use a record instead of a tuple to store the data . If we write a record definition of the type shown below, we can then refer to the fields of the record by name.</p>
- <code type="none">
-
--record(person, {name, phone, address}). </code>
- <p>For example, if <c>P</c> is now a variable whose value is a <c>person</c> record, we can code as follows in order to access the name and address fields of the records.</p>
- <code type="none">
-
-Name = P#person.name,
-Address = P#person.address,
-... </code>
- <p>In the following sections we describe the different operations which can be performed on records:</p>
-
- <section>
- <title>Defining a Record</title>
- <p>A record is defined with the following syntax:</p>
- <code type="none">
-
--record(RecordName, {Field1 [= DefaultValue1],
- Field2 [= DefaultValue2],
- ...,
- FieldN [= DefaultValueN]}). </code>
- <p>The record name and field names must be atoms. The optional default values, which are terms, are used if no value is supplied for a field when a new instance of the record is created. If the default value is not supplied, then the atom <c>undefined</c> is assumed.</p>
- <p>For example, in the following record definition, the address field is <c>undefined</c>.</p>
- <pre>
--record(person, {name = "", phone = [], address}). </pre>
- <p>This definition of a person will be used in many of the examples which follow.</p>
- </section>
-
- <section>
- <title>Including a Record Definition</title>
- <p>If the record is used in several modules, its definition should be placed in a <c>.hrl</c> header file. Each module which uses the record definition should have a <c>-include(FileName).</c> statement. For example:</p>
- <code type="none">
-
--include("my_data_structures.hrl"). </code>
- <note>
- <p>The definition of the record must come before it is used.</p>
- </note>
- </section>
-
- <section>
- <title>Creating a Record</title>
- <p>A new record is created with the following syntax:</p>
- <code type="none">
-
-#RecordName{Field1=Expr1,
- ...,
- FieldM=ExprM}. </code>
- <p>If any of the fields is omitted, then the default value supplied in the record definition is used. For example:</p>
- <pre>
-> #person{phone = [0,8,2,3,4,3,1,2], name = "Robert"}.
-{person, "Robert", [0,8,2,3,4,3,1,2], undefined}. </pre>
- <p>There is a new feature introduced in Erlang 5.1 (OTP release
- R8), with which you can set a value to all fields in a record,
- overriding the defaults in the record specification. The special
- field <c>_</c>, means "all fields not explicitly specified".</p>
- <pre>
-> #person{name = "Jakob", _ = '_'}
-{person, "Jakob", '_', '_'} </pre>
- <p>It is primarily intended to be used in <c>ets:match/2</c> and
- <c>mnesia:match_object/3</c>, to set record fields to the atom
- <c>'_'</c>. (This is a wildcard in <c>ets:match/2</c>.)</p>
- </section>
-
- <section>
- <title>Selectors</title>
- <p>The following syntax is used to select an individual field from a record:</p>
- <code type="none">
-
-Variable#RecordName.Field </code>
- <note>
- <p>The values contained in record names and fields must be constants, not variables.</p>
- </note>
- <note>
- <p>For the purposes of illustration, we will demonstrate the use of records using an imaginary dialogue with the Erlang shell. Currently the Erlang evaluator does not support records so you may not be able to reproduce this dialogue.</p>
- </note>
- <pre>
-
-> <input>P = #person{name = "Joe", phone = [0,8,2,3,4,3,1,2]}.</input>
-{person, "Joe", [0,8,2,3,4,3,1,2], undefined}
-> <input>P#person.name.</input>
-"Joe" </pre>
- <note>
- <p>Selectors for records are allowed in guards.</p>
- </note>
- </section>
-
- <section>
- <title>Updating a Record</title>
- <p>The following syntax is used to create a new copy of the record with some of the fields changed. Only the fields to be changed need to be referred to, all other fields retain their old values.</p>
- <code type="none">
-
-OldVariable#RecordName{Field1 = NewValue1,
- ...,
- FieldM = NewValueM} </code>
- <p>For example:</p>
- <pre>
-> P1 = #person{name="Joe", phone=[1,2,3], address="A street"}.
-{person, "Joe", [1,2,3], "A street"}
-> P2 = P1#person{name="Robert"}.
-{person, "Robert", [1,2,3], "A street"} </pre>
- </section>
-
- <section>
- <title>Type Testing</title>
- <p>The following guard test is used to test the type of a record:</p>
- <code type="none">
-
-record(Variable, RecordName) </code>
- <p>The following example shows that the guard succeeds if <c>P</c> is record of type <c>person</c>.</p>
- <pre>
-foo(P) when record(P, person) -> a_person;
-foo(_) -> not_a_person. </pre>
- <note>
- <p>This test checks that <c>P</c> is a tuple of arity <c>N + 1</c>, where <c>N</c> is the number
- of fields in the record, and the first element in the tuple is the atom <c>person</c>.</p>
- </note>
- </section>
-
- <section>
- <title>Pattern Matching</title>
- <p>Matching can be used in combination with records as shown in the following example:</p>
- <pre>
-> P = #person{name="Joe", phone=[0,0,7], address="A street"}.
-{person, "Joe", [0,0,7], "A street"}
-> #person{name = Name} = P, Name.
-"Joe" </pre>
- <p>The following function takes a list of <c>person</c> records and searches for the phone number of a person with a particular name:</p>
- <code type="none">
-
-find_phone([#person{name=Name, phone=Phone} | _], Name) ->
- {found, Phone};
-find_phone([_| T], Name) ->
- find_phone(T, Name);
-find_phone([], Name) ->
- not_found. </code>
- <note>
- <p>The fields referred to in the pattern can be given in any order.</p>
- </note>
- </section>
-
- <section>
- <title>Nested Records</title>
- <p>The value of a field in a record might be an instance of a record. Retrieval of nested data can be done stepwise, or in a single step, as shown in the following example:</p>
- <pre>
--record(name, {first = "Robert", last = "Ericsson"}).
--record(person, {name = #name{}, phone}).
-
-demo() ->
- P = #person{name= #name{first="Robert",last="Virding"}, phone=123},
- First = (P#person.name)#name.first. </pre>
- <note>
- <p>In this example, <c>demo()</c> evaluates to <c>"Robert"</c>.</p>
- </note>
- </section>
-
- <section>
- <title>Internal Representation of Records</title>
- <p>It is often desirable to write generic functions which will work on any record, not just a record of a particular type. For this reason, records are represented internally as tuples and the ordering of the fields in the tuple is strictly defined.</p>
- <p>For example, the record <c>-record(person, {name, phone, address}).</c> is represented internally by the tuple <c>{person, X, Y, Z}</c>.</p>
- <p>The arity of the tuple is one more than the number of fields in the tuple. The first element of the tuple is the name of the record, and the elements of the tuple are the fields in the record. The variables <c>X</c>, <c>Y</c> and <c>Z</c> will store the data contained in the record fields.</p>
- <p>The following two functions determine the indices in the tuple which refer to the named fields in the record:</p>
- <list type="bulleted">
- <item><c>record_info(fields, Rec) -> [Names]</c>. This function returns the names of the fields in the record <c>Rec</c>. For example, <c>record_info(fields, person)</c> evaluates to <c>[name, address, phone]</c>.</item>
- <item><c>record_info(size, Rec) -> Size</c>. This function returns the size of the record <c>Rec</c> when represented as a tuple, which is one more than the number of fields. For example, <c>record_info(size, person)</c> returns <c>4</c>.</item>
- </list>
- <p>In addition, <c>#Rec.Name</c> returns the index in the tuple representation of <c>Name</c> of the record <c>Rec</c>.</p>
- <note>
- <p><c>Name</c> must be an atom.</p>
- </note>
- <p>For example, the following test function <c>test()</c> might return the result shown:</p>
- <pre>
-test() ->
- {record_info(fields, person),
- record_info(size, person),
- #person.name}. </pre>
- <pre>
-> <input>Mod:test().</input>
-{[name,address,phone],4,2} </pre>
- <p>The order in which records map onto tuples is implementation dependent.</p>
- <note>
- <p><c>record_info</c> is a pseudo-function which cannot be exported from the module where it occurs.</p>
- </note>
- </section>
-
- <section>
- <title>Example</title>
- <pre>
-%% File: person.hrl
-
-%%-----------------------------------------------------------
-%% Data Type: person
-%% where:
-%% name: A string (default is undefined).
-%% age: An integer (default is undefined).
-%% phone: A list of integers (default is []).
-%% dict: A dictionary containing various information
-%% about the person.
-%% A {Key, Value} list (default is the empty list).
-%%------------------------------------------------------------
--record(person, {name, age, phone = [], dict = []}).
- </pre>
- <pre>
--module(person).
--include("person.hrl").
--compile(export_all). % For test purposes only.
-
-%% This creates an instance of a person.
-%% Note: The phone number is not supplied so the
-%% default value [] will be used.
-
-make_hacker_without_phone(Name, Age) ->
- #person{name = Name, age = Age,
- dict = [{computer_knowledge, excellent},
- {drinks, coke}]}.
-
-%% This demonstrates matching in arguments
-
-print(#person{name = Name, age = Age,
- phone = Phone, dict = Dict}) ->
- io:format("Name: ~s, Age: ~w, Phone: ~w ~n"
- "Dictionary: ~w.~n", [Name, Age, Phone, Dict]).
-
-%% Demonstrates type testing, selector, updating.
-
-birthday(P) when record(P, person) ->
- P#person{age = P#person.age + 1}.
-
-register_two_hackers() ->
- Hacker1 = make_hacker_without_phone("Joe", 29),
- OldHacker = birthday(Hacker1),
- % The central_register_server should have
- % an interface function for this.
- central_register_server ! {register_person, Hacker1},
- central_register_server ! {register_person,
- OldHacker#person{name = "Robert",
- phone = [0,8,3,2,4,5,3,1]}}. </pre>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/warning.gif b/system/doc/extensions/warning.gif
deleted file mode 100644
index 96af52360e..0000000000
--- a/system/doc/extensions/warning.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/Makefile b/system/doc/pics/Makefile
deleted file mode 100644
index fc5996259d..0000000000
--- a/system/doc/pics/Makefile
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# Copyright (C) 1996,1997 Ericsson Telecommunications
-# Author: Lars Thorsen
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/doc
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-#
-# Common macros
-#
-
-GIF_FILES= \
- min_head.gif \
- ps.gif
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-
-docs:
-
-pdf:
-
-ps:
-
-debug opt:
-
-
-
-clean:
- @echo "No action" >/dev/null
-
-#
-# Release Targets
-#
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-ifeq ($(DOCTYPE),pdf)
-release_docs_spec: pdf
-else
-ifeq ($(DOCTYPE),ps)
-release_docs_spec: ps
-else
-release_docs_spec: docs
- $(INSTALL_DIR) $(RELSYSDIR)/pics
- $(INSTALL_DATA) $(GIF_FILES) $(RELSYSDIR)/pics
-endif
-endif
-
-release_spec:
diff --git a/system/doc/pics/app.gif b/system/doc/pics/app.gif
deleted file mode 100644
index 345d5795b1..0000000000
--- a/system/doc/pics/app.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/ede.gif b/system/doc/pics/ede.gif
deleted file mode 100644
index 7a51766898..0000000000
--- a/system/doc/pics/ede.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/ede_logo.gif b/system/doc/pics/ede_logo.gif
deleted file mode 100644
index f7c902791b..0000000000
--- a/system/doc/pics/ede_logo.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/min_head.gif b/system/doc/pics/min_head.gif
deleted file mode 100644
index 67948a6378..0000000000
--- a/system/doc/pics/min_head.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/notes.gif b/system/doc/pics/notes.gif
deleted file mode 100644
index e000cca26a..0000000000
--- a/system/doc/pics/notes.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/otp.gif b/system/doc/pics/otp.gif
deleted file mode 100644
index 48c4ca9c02..0000000000
--- a/system/doc/pics/otp.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/otp_logo.gif b/system/doc/pics/otp_logo.gif
deleted file mode 100644
index d1a1f7f72d..0000000000
--- a/system/doc/pics/otp_logo.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/ps.gif b/system/doc/pics/ps.gif
deleted file mode 100644
index 186dfc7e24..0000000000
--- a/system/doc/pics/ps.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/ref_man.gif b/system/doc/pics/ref_man.gif
deleted file mode 100644
index b13c4efd53..0000000000
--- a/system/doc/pics/ref_man.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/user_guide.gif b/system/doc/pics/user_guide.gif
deleted file mode 100644
index e6275a803d..0000000000
--- a/system/doc/pics/user_guide.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/reference_manual/macros.xml b/system/doc/reference_manual/macros.xml
index a1ba182eff..9dd5fc79bd 100644
--- a/system/doc/reference_manual/macros.xml
+++ b/system/doc/reference_manual/macros.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>The Preprocessor</title>
@@ -140,6 +140,38 @@ bar(X) ->
</section>
<section>
+ <title>Macros Overloading</title>
+ <p>It is possible to overload macros, except for predefined
+ macros. An overloaded macro has more than one definition,
+ each with a different number of arguments.</p>
+ <p>The feature was added in Erlang 5.7.5/OTP R13B04.</p>
+ <p>A macro <c>?Func(Arg1,...,ArgN)</c> with a (possibly empty)
+ list of arguments results in an error message if there is at
+ least one definition of <c>Func</c> with arguments, but none
+ with N arguments.</p>
+ <p>Assuming these definitions:</p>
+ <code type="none">
+-define(F0(), c).
+-define(F1(A), A).
+-define(C, m:f).</code>
+ <p>the following will not work:</p>
+ <code type="none">
+f0() ->
+ ?F0. % No, an empty list of arguments expected.
+
+f1(A) ->
+ ?F1(A, A). % No, exactly one argument expected.</code>
+ <p>On the other hand,</p>
+ <code>
+f() ->
+ ?C().</code>
+ <p>will expand to</p>
+ <code>
+f() ->
+ m:f().</code>
+ </section>
+
+ <section>
<title>Flow Control in Macros</title>
<p>The following macro directives are supplied:</p>
<taglist>
diff --git a/system/doc/reference_manual/modules.xml b/system/doc/reference_manual/modules.xml
index f4885be480..0dbc0ab56b 100644
--- a/system/doc/reference_manual/modules.xml
+++ b/system/doc/reference_manual/modules.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Modules</title>
@@ -170,17 +170,21 @@ fact(0) -> % |
<section>
<title>Types and function specifications</title>
- <p>The current release implements types and function specifications
- as described in
+ <p>A similar syntax as for module attributes is used for
+ specifying types and function specifications.
+ </p>
+ <pre>
+-type my_type() :: atom() | integer().
+-spec my_function(integer()) -> integer().
+ </pre>
+ <p>Read more in <seealso marker="typespec">Types and Function specifications</seealso>.
+ </p>
+ <p>
+ The desciption is based on
<url href="http://www.erlang.org/eeps/eep-0008.html">EEP8 -
-Types and function specifications</url>.
-
- <note>
- <p>The implementation and EEP8 may not exactly correspond to
- each other. In a future release, type and function specifications
- will be described in this reference manual.</p>
- </note>
- </p>
+ Types and function specifications</url>
+ which will not be further updated.
+ </p>
</section>
</section>
diff --git a/system/doc/reference_manual/part.xml b/system/doc/reference_manual/part.xml
index aebeaf335a..8151f4c4e1 100644
--- a/system/doc/reference_manual/part.xml
+++ b/system/doc/reference_manual/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Erlang Reference Manual</title>
@@ -32,6 +32,7 @@
<xi:include href="patterns.xml"/>
<xi:include href="modules.xml"/>
<xi:include href="functions.xml"/>
+ <xi:include href="typespec.xml"/>
<xi:include href="expressions.xml"/>
<xi:include href="macros.xml"/>
<xi:include href="records.xml"/>
diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml
new file mode 100755
index 0000000000..a3660713e4
--- /dev/null
+++ b/system/doc/reference_manual/typespec.xml
@@ -0,0 +1,464 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2003</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Types and Function Specifications</title>
+ <prepared>Kostis Sagonas, Tobias Lindahl, Kenneth Lundin</prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>typespec.xml</file>
+ </header>
+
+ <section>
+ <title>Introduction of Types</title>
+ <p>
+ Although Erlang is a dynamically typed language this section describes
+ an extension to the Erlang language for declaring sets of Erlang terms
+ to form a particular type, effectively forming a specific sub-type of the
+ set of all Erlang terms.
+ </p>
+ <p>
+ Subsequently, these types can be used to specify types of record fields
+ and the argument and return types of functions.
+ </p>
+ <p>
+ Type information can be used to document function interfaces,
+ provide more information for bug detection tools such as <c>Dialyzer</c>,
+ and can be exploited by documentation tools such as <c>Edoc</c> for
+ generating program documentation of various forms.
+ It is expected that the type language described in this document will
+ supersede and replace the purely comment-based <c>@type</c> and
+ <c>@spec</c> declarations used by <c>Edoc</c>.
+ </p>
+ <warning>
+ The syntax and semantics described here is still preliminary and might be
+ slightly changed and extended before it becomes officially supported.
+ The plan is that this will happen in R14B.
+ </warning>
+ </section>
+ <section>
+ <marker id="syntax"></marker>
+ <title>Types and their Syntax</title>
+ <p>
+ Types describe sets of Erlang terms.
+ Types consist and are built from a set of predefined types (e.g. <c>integer()</c>,
+ <c>atom()</c>, <c>pid()</c>, ...) described below.
+ Predefined types represent a typically infinite set of Erlang terms which
+ belong to this type.
+ For example, the type <c>atom()</c> stands for the set of all Erlang atoms.
+ </p>
+ <p>
+ For integers and atoms, we allow for singleton types (e.g. the integers <c>-1</c>
+ and <c>42</c> or the atoms <c>'foo'</c> and <c>'bar'</c>).
+
+ All other types are built using unions of either predefined types or singleton
+ types. In a type union between a type and one of its sub-types the sub-type is
+ absorbed by the super-type and the union is subsequently treated as if the
+ sub-type was not a constituent of the union. For example, the type union:
+ </p>
+ <pre>
+ atom() | 'bar' | integer() | 42</pre>
+ <p>
+ describes the same set of terms as the type union:
+ </p>
+ <pre>
+atom() | integer()</pre>
+ <p>
+ Because of sub-type relations that exist between types, types form a lattice
+ where the topmost element, any(), denotes the set of all Erlang terms and
+ the bottom-most element, none(), denotes the empty set of terms.
+ </p>
+ <p>
+ The set of predefined types and the syntax for types is given below:
+ </p>
+ <pre><![CDATA[
+Type :: any() %% The top type, the set of all Erlang terms.
+ | none() %% The bottom type, contains no terms.
+ | pid()
+ | port()
+ | ref()
+ | [] %% nil
+ | Atom
+ | Binary
+ | float()
+ | Fun
+ | Integer
+ | List
+ | Tuple
+ | Union
+ | UserDefined %% described in Section 2
+
+Union :: Type1 | Type2
+
+Atom :: atom()
+ | Erlang_Atom %% 'foo', 'bar', ...
+
+Binary :: binary() %% <<_:_ * 8>>
+ | <<>>
+ | <<_:Erlang_Integer>> %% Base size
+ | <<_:_*Erlang_Integer>> %% Unit size
+ | <<_:Erlang_Integer, _:_*Erlang_Integer>>
+
+Fun :: fun() %% any function
+ | fun((...) -> Type) %% any arity, returning Type
+ | fun(() -> Type)
+ | fun((TList) -> Type)
+
+Integer :: integer()
+ | Erlang_Integer %% ..., -1, 0, 1, ... 42 ...
+ | Erlang_Integer..Erlang_Integer %% specifies an integer range
+
+List :: list(Type) %% Proper list ([]-terminated)
+ | improper_list(Type1, Type2) %% Type1=contents, Type2=termination
+ | maybe_improper_list(Type1, Type2) %% Type1 and Type2 as above
+
+Tuple :: tuple() %% stands for a tuple of any size
+ | {}
+ | {TList}
+
+TList :: Type
+ | Type, TList
+]]></pre>
+ <p>
+ Because lists are commonly used, they have shorthand type notations.
+ The type <c>list(T)</c> has the shorthand <c>[T]</c>. The shorthand <c>[T,...]</c> stands for
+ the set of non-empty proper lists whose elements are of type <c>T</c>.
+ The only difference between the two shorthands is that <c>[T]</c> may be an
+ empty list but <c>[T,...]</c> may not.
+ </p>
+ <p>
+ Notice that the shorthand for <c>list()</c>, i.e. the list of elements of unknown type,
+ is <c>[_]</c> (or <c>[any()]</c>), not <c>[]</c>.
+ The notation <c>[]</c> specifies the singleton type for the empty list.
+ </p>
+ <p>
+ For convenience, the following types are also built-in.
+ They can be thought as predefined aliases for the type unions also shown in
+ the table. (Some type unions below slightly abuse the syntax of types.)
+ </p>
+ <table>
+ <row>
+ <cell><b>Built-in type</b></cell><cell><b>Stands for</b></cell>
+ </row>
+ <row>
+ <cell><c>term()</c></cell><cell><c>any()</c></cell>
+ </row>
+ <row>
+ <cell><c>bool()</c></cell><cell><c>'false' | 'true'</c></cell>
+ </row>
+ <row>
+ <cell><c>byte()</c></cell><cell><c>0..255</c></cell>
+ </row>
+ <row>
+ <cell><c>char()</c></cell><cell><c>0..16#10ffff</c></cell>
+ </row>
+ <row>
+ <cell><c>non_neg_integer()</c></cell><cell><c>0..</c></cell>
+ </row>
+ <row>
+ <cell><c>pos_integer()</c></cell><cell><c>1..</c></cell>
+ </row>
+ <row>
+ <cell><c>neg_integer()</c></cell><cell><c>..-1</c></cell>
+ </row>
+ <row>
+ <cell><c>number()</c></cell><cell><c>integer() | float()</c></cell>
+ </row>
+ <row>
+ <cell><c>list()</c></cell><cell><c>[any()]</c></cell>
+ </row>
+ <row>
+ <cell><c>maybe_improper_list()</c></cell><cell><c>maybe_improper_list(any(), any())</c></cell>
+ </row>
+ <row>
+ <cell><c>maybe_improper_list(T)</c></cell><cell><c>maybe_improper_list(T, any())</c></cell>
+ </row>
+ <row>
+ <cell><c>string()</c></cell><cell><c>[char()]</c></cell>
+ </row>
+ <row>
+ <cell><c>nonempty_string()</c></cell><cell><c>[char(),...]</c></cell>
+ </row>
+ <row>
+ <cell><c>iolist()</c></cell><cell><c>maybe_improper_list(
+char() | binary() | iolist(), binary() | [])</c></cell>
+ </row>
+ <row>
+ <cell><c>module()</c></cell><cell><c>atom()</c></cell>
+ </row>
+ <row>
+ <cell><c>mfa()</c></cell><cell><c>{atom(),atom(),byte()}</c></cell>
+ </row>
+ <row>
+ <cell><c>node()</c></cell><cell><c>atom()</c></cell>
+ </row>
+ <row>
+ <cell><c>timeout()</c></cell><cell><c>'infinity' | non_neg_integer()</c></cell>
+ </row>
+ <row>
+ <cell><c>no_return()</c></cell><cell><c>none()</c></cell>
+ </row>
+ </table>
+
+ <p>
+ Users are not allowed to define types with the same names as the predefined or
+ built-in ones.
+ This is checked by the compiler and its violation results in a compilation
+ error.
+ (For bootstrapping purposes, it can also result to just a warning if this
+ involves a built-in type which has just been introduced.)
+ </p>
+ <note>
+ The following built-in list types also exist,
+ but they are expected to be rarely used. Hence, they have long names:
+ </note>
+ <pre>
+nonempty_maybe_improper_list(Type) :: nonempty_maybe_improper_list(Type, any())
+nonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any())
+ </pre>
+ <p>
+ where the following two types
+ define the set of Erlang terms one would expect:
+ </p>
+ <pre>
+nonempty_improper_list(Type1, Type2)
+nonempty_maybe_improper_list(Type1, Type2)
+ </pre>
+ <p>
+ Also for convenience, we allow for record notation to be used.
+ Records are just shorthands for the corresponding tuples.
+ </p>
+ <pre>
+Record :: #Erlang_Atom{}
+ | #Erlang_Atom{Fields}
+ </pre>
+ <p>
+ Records have been extended to possibly contain type information.
+ This is described in the sub-section <seealso marker="#typeinrecords">"Type information in record declarations"</seealso> below.
+ </p>
+ </section>
+
+ <section>
+ <title>Type declarations of user-defined types</title>
+ <p>
+ As seen, the basic syntax of a type is an atom followed by closed
+ parentheses. New types are declared using '-type' compiler attributes
+ as in the following:
+ </p>
+ <pre>
+-type my_type() :: Type.
+ </pre>
+ <p>
+ where the type name is an atom (<c>'my_type'</c> in the above) followed by
+ parenthesis. Type is a type as defined in the previous section.
+ A current restriction is that Type can contain only predefined types
+ or user-defined types which have been previously defined.
+ This restriction is enforced by the compiler and results in a
+ compilation error. (A similar restriction currently exists for records).
+ </p>
+ <p>
+ This means that currently general recursive types cannot be defined.
+ Lifting this restriction is future work.
+ </p>
+ <p>
+ Type declarations can also be parameterized by including type variables
+ between the parentheses. The syntax of type variables is the same as
+ Erlang variables (starts with an upper case letter).
+ Naturally, these variables can - and should - appear on the RHS of the
+ definition. A concrete example appears below:
+ </p>
+ <pre>
+-type orddict(Key, Val) :: [{Key, Val}].
+ </pre>
+
+ </section>
+
+ <marker id="typeinrecords"/>
+ <section>
+ <title>
+ Type information in record declarations
+ </title>
+ <p>
+ The types of record fields can be specified in the declaration of the
+ record. The syntax for this is:
+ </p>
+ <pre>
+-record(rec, {field1 :: Type1, field2, field3 :: Type3}).
+ </pre>
+ <p>
+ For fields without type annotations, their type defaults to any().
+ I.e., the above is a shorthand for:
+ </p>
+ <pre>
+-record(rec, {field1 :: Type1, field2 :: any(), field3 :: Type3}).
+ </pre>
+ <p>
+ In the presence of initial values for fields,
+ the type must be declared after the initialization as in the following:
+ </p>
+ <pre>
+-record(rec, {field1 = [] :: Type1, field2, field3 = 42 :: Type3}).
+ </pre>
+ <p>
+ Naturally, the initial values for fields should be compatible
+ with (i.e. a member of) the corresponding types.
+ This is checked by the compiler and results in a compilation error
+ if a violation is detected. For fields without initial values,
+ the singleton type <c>'undefined'</c> is added to all declared types.
+ In other words, the following two record declarations have identical
+ effects:
+ </p>
+ <pre>
+-record(rec, {f1 = 42 :: integer(),
+ f2 :: float(),
+ f3 :: 'a' | 'b').
+
+-record(rec, {f1 = 42 :: integer(),
+ f2 :: 'undefined' | float(),
+ f3 :: 'undefined' | 'a' | 'b').
+ </pre>
+ <p>
+ For this reason, it is recommended that records contain initializers,
+ whenever possible.
+ </p>
+ <p>
+ Any record, containing type information or not, once defined,
+ can be used as a type using the syntax:
+ </p>
+ <pre>
+#rec{}
+ </pre>
+ <p>
+ In addition, the record fields can be further specified when using
+ a record type by adding type information about the field in the following
+ manner:
+ </p>
+ <pre>
+#rec{some_field :: Type}
+ </pre>
+ <p>
+ Any unspecified fields are assumed to have the type in the original
+ record declaration.
+ </p>
+ </section>
+
+ <section>
+ <title>Specifications (contracts) for functions</title>
+ <p>
+ A contract (or specification) for a function is given using the new
+ compiler attribute <c>'-spec'</c>. The basic format is as follows:
+ </p>
+ <pre>
+-spec Module:Function(ArgType1, ..., ArgTypeN) -> ReturnType.
+ </pre>
+ <p>
+ The arity of the function has to match the number of arguments,
+ or else a compilation error occurs.
+ </p>
+ <p>
+ This form can also be used in header files (.hrl) to declare type
+ information for exported functions.
+ Then these header files can be included in files that (implicitly or
+ explicitly) import these functions.
+ </p>
+ <p>
+ For most uses within a given module, the following shorthand is allowed:
+ </p>
+ <pre>
+-spec Function(ArgType1, ..., ArgTypeN) -> ReturnType.
+ </pre>
+ <p>
+ Also, for documentation purposes, argument names can be given:
+ </p>
+ <pre>
+-spec Function(ArgName1 :: Type1, ..., ArgNameN :: TypeN) -> RT.
+ </pre>
+ <p>
+ A function specification can be overloaded.
+ That is, it can have several types, separated by a semicolon (<c>;</c>):
+ </p>
+ <pre>
+-spec foo(T1, T2) -> T3
+ ; (T4, T5) -> T6.
+ </pre>
+ <p>
+ A current restriction, which currently results in a warning
+ (OBS: not an error) by the compiler, is that the domains of the argument
+ types cannot be overlapping.
+ For example, the following specification results in a warning:
+ </p>
+ <pre>
+-spec foo(pos_integer()) -> pos_integer()
+ ; (integer()) -> integer().
+ </pre>
+ <p>
+ Type variables can be used in specifications to specify relations for
+ the input and output arguments of a function.
+ For example, the following specification defines the type of a
+ polymorphic identity function:
+ </p>
+ <pre>
+-spec id(X) -> X.
+ </pre>
+ <p>
+ However, note that the above specification does not restrict the input
+ and output type in any way.
+ We can constrain these types by guard-like subtype constraints:
+ </p>
+ <pre>
+-spec id(X) -> X when is_subtype(X, tuple()).
+ </pre>
+ <p>
+ and provide bounded quantification. Currently,
+ the <c>is_subtype/2</c> guard is the only guard which can
+ be used in a <c>'-spec'</c> attribute.
+ </p>
+ <p>
+ The scope of an <c>is_subtype/2</c> constraint is the
+ <c>(...) -> RetType</c>
+ specification after which it appears. To avoid confusion,
+ we suggest that different variables are used in different constituents of
+ an overloaded contract as in the example below:
+ </p>
+ <pre>
+-spec foo({X, integer()}) -> X when is_subtype(X, atom())
+ ; ([Y]) -> Y when is_subtype(Y, number()).
+ </pre>
+ <p>
+ Some functions in Erlang are not meant to return;
+ either because they define servers or because they are used to
+ throw exceptions as the function below:
+ </p>
+ <pre>
+my_error(Err) -> erlang:throw({error, Err}).
+ </pre>
+ <p>
+ For such functions we recommend the use of the special no_return()
+ type for their "return", via a contract of the form:
+ </p>
+ <pre>
+-spec my_error(term()) -> no_return().
+ </pre>
+ </section>
+</chapter>
+
diff --git a/system/doc/top/bin/otp_man_index b/system/doc/top/bin/otp_man_index
index bb913b25df..57a0f12d32 120000..100755
--- a/system/doc/top/bin/otp_man_index
+++ b/system/doc/top/bin/otp_man_index
@@ -1 +1,106 @@
-../../../../internal_tools/integration/scripts/otp_man_index \ No newline at end of file
+#!/opt/local/bin/perl
+
+use File::Find;
+use strict;
+
+#########################################
+# Usage:
+# $ cd $ERLANG_RELEASE
+# otp_man_index > doc/man_index.html
+#########################################
+
+my (@list,$info);
+
+find(\&wanted,'.');
+
+header();
+
+foreach $info (sort {lc($a->[0]) cmp lc($b->[0])} @list) {
+ my ($module,$application,$dir,$path) = @$info;
+
+ my $idx = -f "$dir/index.html" ? "$dir/index.html" : "$dir/../index.html";
+ # Remove .html extension from module name, if there is one
+ if ($module =~ /(\w+).html$/) {
+ $module = "$1";
+ }
+ print " <TR>\n";
+ print " <TD><A HREF=\"../$path\">$module</A></TD>\n";
+ print " <TD><A HREF=\"../$idx\">$application</A></TD>\n";
+ print " </TR>\n";
+}
+
+footer();
+
+###########################################################################
+
+sub wanted {
+ return unless /\.html$/ and -f $_;
+
+ open(FILE,$_) or die "ERROR: Can't open $File::Find::name: $!\n";
+ my $line;
+
+ while (defined ($line = <FILE>)) {
+ if ($line =~ /<!-- refpage -->/) {
+ close FILE;
+ my $path = $File::Find::name;
+ $path =~ s/\.\///; # Remove './' prefix
+ my $dir = $File::Find::dir;
+ $dir =~ s/\.\///; # Remove './' prefix
+ $dir =~ m&([^/]+)/doc/html$&;
+ my $application = $1;
+ push(@list, [$_,$application,$dir,$path]);
+ return;
+ }
+ }
+ close FILE;
+}
+
+
+sub header {
+ print <<EOS;
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- This file was generated by the otp_man_index script -->
+<HTML>
+<HEAD>
+ <link rel="stylesheet" href="otp_doc.css" type="text/css"/>
+ <TITLE>Erlang/OTP Manual Page Index</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF"
+ ALINK="#FF0000">
+<CENTER>
+<!-- A HREF="http://www.erlang.org/">
+<img alt="Erlang logo" src="erlang-logo.png"/ >
+</A><BR -->
+<SMALL>
+[<A HREF="index.html">Up</A> |
+<A HREF="http://www.erlang.org/">Erlang</A>]
+</SMALL><BR>
+<P><FONT SIZE="+4">Manual Page Index</FONT><BR>
+</CENTER>
+<CENTER>
+<P>
+<TABLE BORDER=1>
+<TR>
+ <TH>Manual Page</TH><TH>Application</TH>
+</TR>
+EOS
+}
+
+sub footer {
+ my $year = (localtime)[5] + 1900;
+ print <<EOS;
+</TABLE>
+</CENTER>
+<P>
+<CENTER>
+<HR>
+<SMALL>
+Copyright &copy; 1991-$year
+<a href="http://www.ericsson.com/technology/opensource/erlang/">
+Ericsson AB</a>
+</SMALL>
+</CENTER>
+</BODY>
+</HTML>
+EOS
+}
diff --git a/system/doc/top/src/erl_html_tools.erl b/system/doc/top/src/erl_html_tools.erl
index 35a199b08d..d93516768e 120000..100644
--- a/system/doc/top/src/erl_html_tools.erl
+++ b/system/doc/top/src/erl_html_tools.erl
@@ -1 +1,727 @@
-../../../../internal_tools/integration/scripts/make_index/erl_html_tools.erl \ No newline at end of file
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+-module(erl_html_tools).
+
+%% This file contains tools for updating HTML files in an installed system
+%% depending on the installed applications. Currently the only use is
+%% to update the top index file.
+
+
+%% ------ VERY IMPORTANT ------
+%%
+%% Original location for this file:
+%% /clearcase/otp/internal_tools/integration/scripts/make_index/
+%% When updating this file, copy the source to
+%% /home/otp/patch/share/program/
+%% and place .beam files (compiled with correct release) in all
+%% /home/otp/patch/share/program/<release>
+%% for releases >= R9C
+%%
+%% ----------------------------
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This program generate the top index files for the OTP documentation.
+% Part of the HTML code is in templates, like "index.html.src" and
+% part is written out from this module. So the program and the templates
+% has to match.
+%
+% The templates are searched from the current directory, a directory
+% "templates" relative to the current directory or at RootDir.
+%
+% RootDir is given as an argument or assumed to be code:root_dir(),
+% i.e. the root of the system running this program.
+%
+% The output is put into DestDir or RootDir if not given.
+%
+% The functions to call are
+%
+% top_index()
+% top_index([RootDir])
+% top_index([RootDir,DestDir,OtpRel])
+% top_index(RootDir)
+% top_index(RootDir, DestDir, OtpRel)
+%
+% where RootDir can be a string or an atom.
+%
+%
+% USING THIS SCRIPT FROM THE UNIX COMMAND LINE
+% --------------------------------------------
+% If the Erlang started is the same as the Erlang to create index.html
+% for the use
+%
+% % erl -noshell -s erl_html_tools top_index
+%
+% If you want to create an index for another Erlang installation or
+% documentation located separate from the object code, then use
+%
+% % erl -noshell -s erl_html_tools top_index /path/to/erlang/root
+%
+%
+% COLLECTING INFORMATION
+% ----------------------
+% This script assumes that all applications have an "info" file
+% in their top directory. This file should have some keywords with
+% values defined. The keys are 'group' and 'short' (for "short
+% description). See the OTP applications for examples.
+%
+% Some HTML code is generated by this program, others are taken from
+% the file "index.html.src" that may be located in the patch directory
+% or in the "$ERLANG_ROOT/doc/" directory.
+%
+% The code for creating the top index page assumes all applications
+% have a file "info" with some fields filled in
+%
+% short: Text Short text describing the application
+% group: tag [Heading] Group tag optionally followed by a description.
+% Only one app need to describe the group but
+% more than one can.
+%
+% FIXME: Check that there is documentation for the application, not just
+% an info file.
+% FIXME: Use records, it is now unreadable :-(
+% FIXME: Use a separate URL and URLIndexFile
+% FIXME: Pass the OTP release name as an argument instead of in
+% process dictionary (for elegance).
+
+-export([top_index/0,top_index/1,top_index/3,top_index_silent/3]).
+
+% This is the order groups are inserted into the file. Groups
+% not in this list is inserted in undefined order.
+
+group_order() ->
+ [
+ basic,
+ dat,
+ oam,
+ orb,
+ comm,
+ tools
+ ].
+
+top_index() ->
+ top_index(code:root_dir()).
+
+top_index([RootDir]) when atom(RootDir) ->
+ top_index(atom_to_list(RootDir));
+top_index([RootDir,DestDir,OtpRel])
+ when is_atom(RootDir), is_atom(DestDir), is_atom(OtpRel) ->
+ top_index(atom_to_list(RootDir), atom_to_list(DestDir), atom_to_list(OtpRel));
+top_index(RootDir) ->
+ {_,RelName} = init:script_id(),
+ top_index(RootDir, filename:join(RootDir, "doc"), RelName).
+
+top_index(RootDir, DestDir, OtpRel) ->
+ report("****\nRootDir: ~p", [RootDir]),
+ report("****\nDestDir: ~p", [DestDir]),
+ report("****\nOtpRel: ~p", [OtpRel]),
+
+ put(otp_release, OtpRel),
+
+ Templates = find_templates(["","templates",DestDir]),
+ report("****\nTemplates: ~p", [Templates]),
+ Bases = [{"../lib/", filename:join(RootDir,"lib")},
+ {"../", RootDir}],
+ Groups = find_information(Bases),
+ report("****\nGroups: ~p", [Groups]),
+ process_templates(Templates, DestDir, Groups).
+
+top_index_silent(RootDir, DestDir, OtpRel) ->
+ put(silent,true),
+ Result = top_index(RootDir, DestDir, OtpRel),
+ erase(silent),
+ Result.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Main loop - process templates
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+process_templates([], _DestDir, _Groups) ->
+ report("\n", []);
+process_templates([Template | Templates], DestDir, Groups) ->
+ report("****\nIN-FILE: ~s", [Template]),
+ BaseName = filename:basename(Template, ".src"),
+ case lists:reverse(filename:rootname(BaseName)) of
+ "_"++_ ->
+ %% One template expands to several output files.
+ process_multi_template(BaseName, Template, DestDir, Groups);
+ _ ->
+ %% Standard one-to-one template.
+ OutFile = filename:join(DestDir, BaseName),
+ subst_file("", OutFile, Template, Groups)
+ end,
+ process_templates(Templates, DestDir, Groups).
+
+
+process_multi_template(BaseName0, Template, DestDir, Info) ->
+ Ext = filename:extension(BaseName0),
+ BaseName1 = filename:basename(BaseName0, Ext),
+ [_|BaseName2] = lists:reverse(BaseName1),
+ BaseName = lists:reverse(BaseName2),
+ Groups0 = [{[$_|atom_to_list(G)],G} || G <- group_order()],
+ Groups = [{"",basic}|Groups0],
+ process_multi_template_1(Groups, BaseName, Ext, Template, DestDir, Info).
+
+process_multi_template_1([{Suffix,Group}|Gs], BaseName, Ext, Template, DestDir, Info) ->
+ OutFile = filename:join(DestDir, BaseName++Suffix++Ext),
+ subst_file(Group, OutFile, Template, Info),
+ process_multi_template_1(Gs, BaseName, Ext, Template, DestDir, Info);
+process_multi_template_1([], _, _, _, _, _) -> ok.
+
+subst_file(Group, OutFile, Template, Info) ->
+ report("\nOUTFILE: ~s", [OutFile]),
+ case subst_template(Group, Template, Info) of
+ {ok,Text,_NewInfo} ->
+ case file:open(OutFile, [write]) of
+ {ok, Stream} ->
+ file:write(Stream, Text),
+ file:close(Stream);
+ Error ->
+ error("Can't write to file ~s: ~w", [OutFile,Error])
+ end;
+ Error ->
+ error("Can't write to file ~s: ~w", [OutFile,Error])
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Find the templates
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+find_templates(SearchPaths) ->
+ find_templates(SearchPaths, SearchPaths).
+
+find_templates([SearchPath | SearchPaths], AllSearchPaths) ->
+ case filelib:wildcard(filename:join(SearchPath, "*.html.src")) of
+ [] ->
+ find_templates(SearchPaths, AllSearchPaths);
+ Result ->
+ Result
+ end;
+find_templates([], AllSearchPaths) ->
+ error("No templates found in ~p",[AllSearchPaths]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This function read all application names and if present all "info" files.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+find_information(Bases) ->
+ Paths = find_application_paths(Bases),
+% report("****\nPaths: ~p", [Paths]),
+ Apps = find_application_infos(Paths),
+% report("****\nApps: ~p", [Apps]),
+ form_groups(Apps).
+
+% The input is a list of tuples of the form
+%
+% IN: [{BaseURL,SearchDir}, ...]
+%
+% and the output is a list
+%
+% OUT: [{Appname,AppVersion,AppPath,IndexUTL}, ...]
+%
+% We know URL ends in a slash.
+
+find_application_paths([]) ->
+ [];
+find_application_paths([{URL,Dir} | Paths]) ->
+ Sub1 = "doc/html/index.html",
+%% Sub2 = "doc/index.html",
+ case file:list_dir(Dir) of
+ {ok, Dirs} ->
+ AppDirs =
+ lists:filter(
+ fun(E) ->
+ is_match(E, "^[A-Za-z0-9_]+-[0-9\\.]+")
+ end, Dirs),
+ AppPaths =
+ lists:map(
+ fun(AppDir) ->
+ {ok,[App,Ver]} = regexp:split(AppDir, "-"),
+ DirPath = filename:join(Dir,AppDir),
+ AppURL = URL ++ AppDir,
+ {App,Ver,DirPath,AppURL ++ "/" ++ Sub1}
+%% case file:read_file_info(
+%% filename:join(DirPath, Sub1)) of
+%% {ok, _} ->
+%% {App,Ver,DirPath,AppURL ++ "/" ++ Sub1};
+%% _ ->
+%% {App,Ver,DirPath,AppURL ++ "/" ++ Sub2}
+%% end
+ end, AppDirs),
+ AppPaths ++ find_application_paths(Paths)
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Find info for one application.
+% Read the "info" file for each application. Look at "group" and "short".
+% key words.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IN: [{Appname,AppVersion,AppPath,IndexUTL}, ...]
+% OUT: [{Group,Heading,[{AppName,[{AppVersion,Path,URL,Text} | ...]}
+% | ...]}, ...]
+
+find_application_infos([]) ->
+ [];
+find_application_infos([{App,Ver,AppPath,IndexURL} | Paths]) ->
+ case read_info(filename:join(AppPath,"info")) of
+ {error,_Reason} ->
+ warning("No info for app ~p", [AppPath]),
+ find_application_infos(Paths);
+ Db ->
+ {Group,Heading} =
+ case lists:keysearch("group", 1, Db) of
+ {value, {_, G0}} ->
+ % This value may be in two parts,
+ % tag and desciption
+ case string:str(G0," ") of
+ 0 ->
+ {list_to_atom(G0),""};
+ N ->
+ {list_to_atom(string:substr(G0,1,N-1)),
+ string:substr(G0,N+1)}
+ end;
+ false ->
+ error("No group given",[])
+ end,
+ Text =
+ case lists:keysearch("short", 1, Db) of
+ {value, {_, G1}} ->
+ G1;
+ false ->
+ ""
+ end,
+ [{Group,Heading,{App,{Ver,AppPath,IndexURL,Text}}}
+ | find_application_infos(Paths)]
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Group into one list element for each group name.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IN : {Group,Heading,{AppName,{AppVersion,Path,URL,Text}}}
+% OUT: {Group,Heading,[{AppName,[{AppVersion,Path,URL,Text} | ...]} | ...]}
+
+form_groups(Apps) ->
+ group_apps(lists:sort(Apps)).
+
+group_apps([{Group,Heading,AppInfo} | Info]) ->
+ group_apps(Info, Group, Heading, [AppInfo]);
+group_apps([]) ->
+ [].
+
+% First description
+group_apps([{Group,"",AppInfo} | Info], Group, Heading, AppInfos) ->
+ group_apps(Info, Group, Heading, [AppInfo | AppInfos]);
+group_apps([{Group,Heading,AppInfo} | Info], Group, "", AppInfos) ->
+ group_apps(Info, Group, Heading, [AppInfo | AppInfos]);
+% Exact match
+group_apps([{Group,Heading,AppInfo} | Info], Group, Heading, AppInfos) ->
+ group_apps(Info, Group, Heading, [AppInfo | AppInfos]);
+% Different descriptions
+group_apps([{Group,_OtherHeading,AppInfo} | Info], Group, Heading, AppInfos) ->
+ warning("Group ~w descriptions differ",[Group]),
+ group_apps(Info, Group, Heading, [AppInfo | AppInfos]);
+group_apps(Info, Group, Heading, AppInfos) ->
+ [{Group,Heading,combine_apps(AppInfos)} | group_apps(Info)].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Group into one list element for each application name.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IN : {AppName,{AppVersion,Path,URL,Text}}
+% OUT: {AppName,[{AppVersion,Path,URL,Text} | ...]}
+
+combine_apps(Apps) ->
+ combine_apps(Apps,[],[]).
+
+combine_apps([{AppName,{Vsn1,Path1,URL1,Text1}},
+ {AppName,{Vsn2,Path2,URL2,Text2}} | Apps], AppAcc, Acc) ->
+ combine_apps([{AppName,{Vsn2,Path2,URL2,Text2}} | Apps],
+ [{Vsn1,Path1,URL1,Text1} | AppAcc],
+ Acc);
+combine_apps([{AppName,{Vsn1,Path1,URL1,Text1}},
+ {NewAppName,{Vsn2,Path2,URL2,Text2}} | Apps], AppAcc, Acc) ->
+ App = lists:sort(fun vsncmp/2,[{Vsn1,Path1,URL1,Text1}|AppAcc]),
+ combine_apps([{NewAppName,{Vsn2,Path2,URL2,Text2}} | Apps],
+ [],
+ [{AppName,App}|Acc]);
+combine_apps([{AppName,{Vsn,Path,URL,Text}}], AppAcc, Acc) ->
+ App = lists:sort(fun vsncmp/2,[{Vsn,Path,URL,Text}|AppAcc]),
+ [{AppName,App}|Acc].
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Open a template and fill in the missing parts
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IN : {Group,Heading,[{AppName,[{AppVersion,Path,URL,Text} | ...]} | ...]}
+% OUT: String that is the HTML code
+
+subst_template(Group, File, Info) ->
+ case file:open(File, read) of
+ {ok,Stream} ->
+ Res = subst_template_1(Group, Stream, Info),
+ file:close(Stream),
+ Res;
+ {error,Reason} ->
+ {error, Reason}
+ end.
+
+subst_template_1(Group, Stream, Info) ->
+ case file:read(Stream, 100000) of
+ {ok, Template} ->
+ Fun = fun(Match, _) -> {subst(Match, Info, Group),Info} end,
+ gsub(Template, "#[A-Za-z0-9]+#", Fun, Info);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+get_version(Info) ->
+ case lists:keysearch('runtime', 1, Info) of
+ {value, {_,_,Apps}} ->
+ case lists:keysearch("erts", 1, Apps) of
+ {value, {_,[{Vers,_,_,_} | _]}} ->
+ Vers;
+ _ ->
+ ""
+ end;
+ _ ->
+ ""
+ end.
+
+subst("#release#", _Info, _Group) ->
+ get(otp_release);
+subst("#version#", Info, _Group) ->
+ get_version(Info);
+subst("#copyright#", _Info, _Group) ->
+ "copyright Copyright &copy; 1991-2004";
+subst("#groups#", Info, _Group) ->
+ [
+ "<table border=0 width=\"90%\" cellspacing=3 cellpadding=5>\n",
+ subst_groups(Info),
+ "</table>\n"
+ ];
+subst("#applinks#", Info, Group) ->
+ subst_applinks(Info, Group);
+subst(KeyWord, Info, _Group) ->
+ case search_appname(KeyWord -- "##", Info) of
+ {ok,URL} ->
+ URL;
+ _ ->
+ warning("Can't substitute keyword ~s~n",[KeyWord]),
+ ""
+ end.
+
+search_appname(App, [{_Group,_,Apps} | Groups]) ->
+ case lists:keysearch(App, 1, Apps) of
+ {value, {_,[{_Vers,_Path,URL,_Text} | _]}} ->
+ {ok,lists:sublist(URL, length(URL) - length("/index.html"))};
+ _ ->
+ search_appname(App, Groups)
+ end;
+search_appname(_App, []) ->
+ {error,noapp}.
+
+subst_applinks(Info, Group) ->
+ subst_applinks_1(group_order(), Info, Group).
+
+subst_applinks_1([G|Gs], Info0, Group) ->
+ case lists:keysearch(G, 1, Info0) of
+ {value,{G,Heading,Apps}} ->
+ Info = lists:keydelete(G, 1, Info0),
+ ["\n<li>",Heading,"\n<ul>\n",
+ html_applinks(Apps),"\n</ul></li>\n"|
+ subst_applinks_1(Gs, Info, Group)];
+ false ->
+ warning("No applications in group ~w\n", [G]),
+ subst_applinks_1(Gs, Info0, Group)
+ end;
+subst_applinks_1([], [], _) -> [];
+subst_applinks_1([], Info, _) ->
+ error("Info left:\n", [Info]),
+ [].
+
+html_applinks([{Name,[{_,_,URL,_}|_]}|AppNames]) ->
+ ["<li><a href=\"",URL,"\">",Name,
+ "</a></li>\n"|html_applinks(AppNames)];
+html_applinks([]) -> [].
+
+
+% Info: [{Group,Heading,[{AppName,[{AppVersion,Path,URL,Text} | ..]} | ..]} ..]
+
+subst_groups(Info0) ->
+ {Html1,Info1} = subst_known_groups(group_order(), Info0, ""),
+ {Html2,Info} = subst_unknown_groups(Info1, Html1, []),
+ Fun = fun({_Group,_GText,Applist}, Acc) -> Applist ++ Acc end,
+ case lists:foldl(Fun, [], Info) of
+ [] ->
+ Html2;
+ Apps ->
+ [Html2,group_table("Misc Applications",Apps)]
+ end.
+
+
+subst_known_groups([], Info, Text) ->
+ {Text,Info};
+subst_known_groups([Group | Groups], Info0, Text0) ->
+ case lists:keysearch(Group, 1, Info0) of
+ {value,{_,Heading,Apps}} ->
+ Text = group_table(Heading,Apps),
+ Info = lists:keydelete(Group, 1, Info0),
+ subst_known_groups(Groups, Info, Text0 ++ Text);
+ false ->
+ warning("No applications in group ~w~n",[Group]),
+ subst_known_groups(Groups, Info0, Text0)
+ end.
+
+
+subst_unknown_groups([], Text0, Left) ->
+ {Text0,Left};
+subst_unknown_groups([{Group,"",Apps} | Groups], Text0, Left) ->
+ warning("No text describes ~w",[Group]),
+ subst_unknown_groups(Groups, Text0, [{Group,"",Apps} | Left]);
+subst_unknown_groups([{_Group,Heading,Apps} | Groups], Text0, Left) ->
+ Text = group_table(Heading,Apps),
+ subst_unknown_groups(Groups, Text0 ++ Text, Left).
+
+
+group_table(Heading,Apps) ->
+ [
+ " <tr>\n",
+ " <td colspan=2 class=header>\n",
+ " <font size=\"+1\"><b>",Heading,"</b></font>\n",
+ " </td>\n",
+ " </tr>\n",
+ subst_apps(Apps),
+ " <tr>\n",
+ " <td colspan=2><font size=1>&nbsp;</font></td>\n",
+ " </tr>\n"
+ ].
+
+% Count and split the applications in half to get the right sort
+% order in the table.
+
+subst_apps([{App,VersionInfo} | Apps]) ->
+ [subst_app(App, VersionInfo) | subst_apps(Apps)];
+subst_apps([]) ->
+ [].
+
+
+subst_app(App, [{VSN,_Path,Link,Text}]) ->
+ [
+ " <tr class=app>\n",
+ " <td align=left valign=top>\n",
+ " <table border=0 width=\"100%\" cellspacing=0 cellpadding=0>\n",
+ " <tr class=app>\n",
+ " <td align=left valign=top>\n",
+ " <a href=\"",Link,"\" target=\"_top\">",uc(App),"</a>\n",
+ " <a href=\"",Link,"\" target=\"_top\">",VSN,"</a>\n",
+ " </td>\n",
+ " </tr>\n",
+ " </table>\n"
+ " </td>\n",
+ " <td align=left valign=top>\n",
+ Text,"\n",
+ " </td>\n",
+ " </tr>\n"
+ ];
+subst_app(App, [{VSN,_Path,Link,Text} | VerInfos]) ->
+ [
+ " <tr class=app>\n",
+ " <td align=left valign=top>\n",
+ " <table border=0 width=\"100%\" cellspacing=0 cellpadding=0>\n",
+ " <tr class=app>\n",
+ " <td align=left valign=top>\n",
+ " <a href=\"",Link,"\" target=\"_top\">",uc(App),
+ "</a>&nbsp;&nbsp;<br>\n",
+ " <a href=\"",Link,"\" target=\"_top\">",VSN,"</a>\n",
+ " </td>\n",
+ " <td align=right valign=top width=50>\n",
+ " <table border=0 width=40 cellspacing=0 cellpadding=0>\n",
+ " <tr class=app>\n",
+ " <td align=left valign=top class=appnums>\n",
+ subst_vsn(VerInfos),
+ " </td>\n",
+ " </tr>\n",
+ " </table>\n"
+ " </td>\n",
+ " </tr>\n",
+ " </table>\n"
+ " </td>\n",
+ " <td align=left valign=top>\n",
+ Text,"\n",
+ " </td>\n",
+ " </tr>\n"
+ ].
+
+
+subst_vsn([{VSN,_Path,Link,_Text} | VSNs]) ->
+ [
+ " <font size=\"2\"><a class=anum href=\"",Link,"\" target=\"_top\">",
+ VSN,
+ "</a></font><br>\n",
+ subst_vsn(VSNs)
+ ];
+subst_vsn([]) ->
+ "".
+
+
+% Yes, this is very inefficient an is done for every comarision
+% in the sort but it doesn't matter in this case.
+
+vsncmp({Vsn1,_,_,_}, {Vsn2,_,_,_}) ->
+ L1 = [list_to_integer(N1) || N1 <- string:tokens(Vsn1, ".")],
+ L2 = [list_to_integer(N2) || N2 <- string:tokens(Vsn2, ".")],
+ L1 > L2.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GENERIC FUNCTIONS, NOT SPECIFIC FOR GENERATING INDEX.HTML
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Read the "info" file into a list of Key/Value pairs
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+read_info(File) ->
+ case file:open(File, read) of
+ {ok,Stream} ->
+ Res =
+ case file:read(Stream,10000) of
+ {ok, Text} ->
+ Lines = string:tokens(Text, "\n\r"),
+ KeyValues0 = lines_to_key_value(Lines),
+ combine_key_value(KeyValues0);
+ {error, Reason} ->
+ {error, Reason}
+ end,
+ file:close(Stream),
+ Res;
+ {error,Reason} ->
+ {error,Reason}
+ end.
+
+combine_key_value([{Key,Value1},{Key,Value2} | KeyValues]) ->
+ combine_key_value([{Key,Value1 ++ "\n" ++ Value2} | KeyValues]);
+combine_key_value([KeyValue | KeyValues]) ->
+ [KeyValue | combine_key_value(KeyValues)];
+combine_key_value([]) ->
+ [].
+
+lines_to_key_value([]) ->
+ [];
+lines_to_key_value([Line | Lines]) ->
+ case regexp:first_match(Line, "^[a-zA-Z_\\-]+:") of
+ nomatch ->
+ case regexp:first_match(Line, "[\041-\377]") of
+ nomatch ->
+ lines_to_key_value(Lines);
+ _ ->
+ warning("skipping line \"~s\"",[Line]),
+ lines_to_key_value(Lines)
+ end;
+ {match, _, Length} ->
+ Value0 = lists:sublist(Line, Length+1, length(Line) - Length),
+ {ok, Value1, _} = regexp:sub(Value0, "^[ \t]*", ""),
+ {ok, Value, _} = regexp:sub(Value1, "[ \t]*$", ""),
+ Key = lists:sublist(Line, Length-1),
+ [{Key,Value} | lines_to_key_value(Lines)]
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Extensions to the 'regexp' module.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+is_match(Ex, Re) ->
+ case regexp:first_match(Ex, Re) of
+ {match, _, _} ->
+ true;
+ nomatch ->
+ false
+ end.
+
+%% -type gsub(String, RegExp, Fun, Acc) -> subres().
+%% Substitute every match of the regular expression RegExp with the
+%% string returned from the function Fun(Match, Acc). Accept pre-parsed
+%% regular expressions. Acc is an argument to the Fun. The Fun should return
+%% a tuple {Replacement, NewAcc}.
+
+gsub(String, RegExp, Fun, Acc) when list(RegExp) ->
+ case regexp:parse(RegExp) of
+ {ok,RE} -> gsub(String, RE, Fun, Acc);
+ {error,E} -> {error,E}
+ end;
+gsub(String, RE, Fun, Acc) ->
+ {match,Ss} = regexp:matches(String, RE),
+ {NewString, NewAcc} = sub_repl(Ss, Fun, Acc, String, 1),
+ {ok,NewString,NewAcc}.
+
+
+% New code that uses fun for finding the replacement. Also uses accumulator
+% to pass argument between the calls to the fun.
+sub_repl([{St,L}|Ss], Fun, Acc0, S, Pos) ->
+ Match = string:substr(S, St, L),
+ {Rep, Acc} = Fun(Match, Acc0),
+ {Rs, NewAcc} = sub_repl(Ss, Fun, Acc, S, St+L),
+ {string:substr(S, Pos, St-Pos) ++ Rep ++ Rs, NewAcc};
+sub_repl([], _Fun, Acc, S, Pos) -> {string:substr(S, Pos), Acc}.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Error and warnings
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+error(Format, Args) ->
+ io:format("ERROR: " ++ Format ++ "\n", Args),
+ exit(1).
+
+warning(Format, Args) ->
+ case get(silent) of
+ true -> ok;
+ _ -> io:format("WARNING: " ++ Format ++ "\n", Args)
+ end.
+
+report(Format, Args) ->
+ case get(silent) of
+ true -> ok;
+ _ -> io:format(Format ++ "\n", Args)
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Extensions to the 'string' module.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+uc(String) ->
+ lists:reverse(uc(String, [])).
+
+uc([], Acc) ->
+ Acc;
+uc([H | T], Acc) when is_integer(H), [97] =< H, H =< $z ->
+ uc(T, [H - 32 | Acc]);
+uc([H | T], Acc) ->
+ uc(T, [H | Acc]).
diff --git a/system/doc/top/src/erlresolvelinks.erl b/system/doc/top/src/erlresolvelinks.erl
index 8d277ad17a..a891b67421 120000..100644
--- a/system/doc/top/src/erlresolvelinks.erl
+++ b/system/doc/top/src/erlresolvelinks.erl
@@ -1 +1,144 @@
-../../../../internal_tools/integration/scripts/resolve_links/erlresolvelinks.erl \ No newline at end of file
+-module(erlresolvelinks).
+
+%% ------ VERY IMPORTANT ------
+%%
+%% Original location for this file:
+%% /clearcase/otp/internal_tools/integration/scripts/resolve_links/
+%% When updating this file, copy the source to
+%% /usr/local/otp/patch/share/program/
+%% and place .beam files (compiled with correct release) in all
+%% /usr/local/otp/patch/share/program/<release>
+%% for releases >= R10B
+%%
+%% ----------------------------
+
+-export([make/1, do_make/1, do_make/2, do_make/3]).
+-include_lib("kernel/include/file.hrl").
+
+-define(JAVASCRIPT_NAME, "erlresolvelinks.js").
+
+make([RootDir]) ->
+ do_make(RootDir);
+make([RootDir, DestDir]) ->
+ do_make(RootDir, DestDir);
+make([RootDir, DestDir, Name]) ->
+ do_make(RootDir, DestDir, Name).
+
+do_make(RootDir) ->
+ DestDir = filename:join(RootDir, "doc"),
+ do_make(RootDir, DestDir).
+
+do_make(RootDir, DestDir) ->
+ do_make(RootDir, DestDir, ?JAVASCRIPT_NAME).
+
+do_make(RootDir, DestDir, Name) ->
+ %% doc/Dir
+ %% erts-Vsn
+ %% lib/App-Vsn
+ DocDirs0 = get_dirs(filename:join([RootDir, "doc"])),
+ DocDirs = lists:map(fun(Dir) ->
+ D = filename:join(["doc", Dir]),
+ {D, D} end, DocDirs0),
+
+ ErtsDirs = latest_app_dirs(RootDir, ""),
+ AppDirs = latest_app_dirs(RootDir, "lib"),
+
+ AllAppDirs =
+ lists:map(
+ fun({App, AppVsn}) -> {App, filename:join([AppVsn, "doc", "html"])}
+ end, ErtsDirs ++ AppDirs),
+
+ AllDirs = DocDirs ++ AllAppDirs,
+ {ok, Fd} = file:open(filename:join([DestDir, Name]), [write]),
+ UTC = calendar:universal_time(),
+ io:fwrite(Fd, "/* Generated by ~s at ~w UTC */\n",
+ [atom_to_list(?MODULE), UTC]),
+ io:fwrite(Fd, "function erlhref(ups, app, rest) {\n", []),
+ io:fwrite(Fd, " switch(app) {\n", []),
+ lists:foreach(
+ fun({Tag, Dir}) ->
+ io:fwrite(Fd, " case ~p:\n", [Tag]),
+ io:fwrite(Fd, " location.href=ups + \"~s/\" + rest;\n",
+ [Dir]),
+ io:fwrite(Fd, " break;\n", [])
+ end, AllDirs),
+ io:fwrite(Fd, " default:\n", []),
+ io:fwrite(Fd, " location.href=ups + \"Unresolved\";\n", []),
+ io:fwrite(Fd, " }\n", []),
+ io:fwrite(Fd, "}\n", []),
+ file:close(Fd),
+ ok.
+
+get_dirs(Dir) ->
+ {ok, Files} = file:list_dir(Dir),
+ AFiles =
+ lists:map(fun(File) -> {File, filename:join([Dir, File])} end, Files),
+ lists:zf(fun is_dir/1, AFiles).
+
+is_dir({File, AFile}) ->
+ {ok, FileInfo} = file:read_file_info(AFile),
+ case FileInfo#file_info.type of
+ directory ->
+ {true, File};
+ _ ->
+ false
+ end.
+
+latest_app_dirs(RootDir, Dir) ->
+ ADir = filename:join(RootDir, Dir),
+ RDirs0 = get_dirs(ADir),
+ RDirs1 = lists:filter(fun is_app_dir/1, RDirs0),
+ %% Build a list of {{App, VsnNumList}, AppVsn}
+ SDirs0 =
+ lists:map(fun(AppVsn) ->
+ [App, VsnStr] = string:tokens(AppVsn, "-"),
+ VsnNumList = vsnstr_to_numlist(VsnStr),
+ {{App, VsnNumList}, AppVsn} end,
+ RDirs1),
+ SDirs1 = lists:keysort(1, SDirs0),
+ App2Dirs = lists:foldr(fun({{App, _VsnNumList}, AppVsn}, Acc) ->
+ case lists:keymember(App, 1, Acc) of
+ true ->
+ Acc;
+ false ->
+ [{App, AppVsn}| Acc]
+ end
+ end, [], SDirs1),
+ lists:map(fun({App, AppVsn}) -> {App, filename:join([Dir, AppVsn])} end,
+ App2Dirs).
+
+is_app_dir(Dir) ->
+ case string:tokens(Dir, "-") of
+ [_Name, Rest] ->
+ is_vsnstr(Rest);
+ _ ->
+ false
+ end.
+
+is_vsnstr(Str) ->
+ case string:tokens(Str, ".") of
+ [_] ->
+ false;
+ Toks ->
+ lists:all(fun is_numstr/1, Toks)
+ end.
+
+is_numstr(Cs) ->
+ lists:all(fun(C) when $0 =< C, C =< $9 ->
+ true;
+ (_) ->
+ false
+ end, Cs).
+
+%% We know:
+
+vsnstr_to_numlist(VsnStr) ->
+ lists:map(fun(NumStr) -> list_to_integer(NumStr) end,
+ string:tokens(VsnStr, ".")).
+
+
+
+
+
+
+
diff --git a/system/doc/top/src/permuted_index.erl b/system/doc/top/src/permuted_index.erl
deleted file mode 120000
index e65338a517..0000000000
--- a/system/doc/top/src/permuted_index.erl
+++ /dev/null
@@ -1 +0,0 @@
-../../../../internal_tools/integration/scripts/make_index/permuted_index.erl \ No newline at end of file
diff --git a/system/doc/top/templates/erlang.gif b/system/doc/top/templates/erlang.gif
deleted file mode 100644
index 91fd4b9647..0000000000
--- a/system/doc/top/templates/erlang.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/top/templates/first.html.src b/system/doc/top/templates/first.html.src
deleted file mode 100644
index edef1c0e5c..0000000000
--- a/system/doc/top/templates/first.html.src
+++ /dev/null
@@ -1,104 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
- <title>Erlang/OTP #release# Documentation</title>
- <style type="text/css">
-<!--
- BODY { background: white }
-
- BODY { font-family: Verdana, Arial, Helvetica, sans-serif }
- TH { font-family: Verdana, Arial, Helvetica, sans-serif }
- TD { font-family: Verdana, Arial, Helvetica, sans-serif }
- P { font-family: Verdana, Arial, Helvetica, sans-serif }
-
- .header { background: #222; color: #fff }
- .app { background: #ccc }
--->
- </style>
-</head>
-<body bgcolor=white text="#000000" link="#0000ff" vlink="#ff00ff"
- alink="#ff0000">
-<center>
-<p>
-<font size="+1">Welcome to Erlang/OTP, a complete<br>
-development environment<br>
-for concurrent programming.</font>
-</p>
-</center>
-<br>
-<br>
-<br>
-<p><b>
-<font size"+1">
-Some hints that may get you started faster
-</font>
-</b></p>
-
-<ul>
-
-<li>In addition the the documentation here Erlang is described in the book
-<a href="http://www.pragprog.com/titles/jaerlang" target="_top">"Programming Erlang"</a>, ISBN 978-1-934356-00-5 which we really recommend as a start.<br/ >
-The complete language is also described in the <a href="reference_manual/part_frame.html" target="_top">Erlang Reference Manual</a>. An Erlang tutorial can be found in <a href="getting_started/part_frame.html" target="_top">Getting Started With Erlang</a>.
-</li>
-<li>Erlang/OTP is divided into a number of OTP <a
-href="applications.html">applications</a>. An application normally contains
-Erlang <a href="man_index.html">modules</a>. Some OTP applications,
-such as the C interface <em>Erl_Interface</em>, are written in other languages and have no Erlang
-modules.
-
-<p>
-Note that functions that are not imported or prefixed with a module
-name belong to the module
-<a href="#kernel#/erlang.html" target="_top">erlang</a>
-(in the <em>Kernel</em> application).
-</p>
-<p>
-<li>On a Unix system you can view the manual pages from the command
-line using
-<pre>
- % erl -man &lt;module&gt;
-</pre>
-<p>
-
-<li> You can of course use any editor you like to write Erlang
-programs, but if you use Emacs there exists editing support such as
-indentation, syntax highlighting, electric commands, module name
-verification, comment support including paragraph filling, skeletons,
-tags support and more. See the <a href="#tools#/index.html"
-target="_top">Tools</a> application for details.
-<p>
-There is also an
-<a href="http://erlide.sourceforge.net" target="_top">
-Erlang plugin (ErlIde) for Eclipse</a> if you prefer a more graphical
-environment. ErlIde is under development and should at the time
-of writing this be quite stable and useful.
-<li>When developing with Erlang/OTP you usually test your programs
-from the interactive shell (see <a href="getting_started/part_frame.html"
-target="_top">Getting Started With Erlang</a>) where you can call individual
-functions. There is also a number of tools available, such as the graphical <a
-href="#debugger#/index.html" target="_top">Debugger</a>, the process
-manager <a href="#pman#/index.html" target="_top">Pman</a> and table
-viewer <a href="#tv#/index.html" target="_top">TV</a>.
-<p> Also note that there are some shell features like history list
-(control-p and control-n), inline editing (emacs key bindings) and
-module and function name completion (tab) if the module is loaded.
-<p>
-
-<li>OpenSource users can ask questions
-and share experiences on the <a href="http://www.erlang.org/faq.html"
-target="_top">Erlang questions mailing list</a>. <p>
-
-<li>Before asking a question you can browse the <a
-href="http://www.erlang.org/pipermail/erlang-questions/"
-target="_top">mailing list archive</a> and read the <a
-href="http://www.erlang.org/faq/faq.html" target="_top">Frequently
-Asked Questions</a>. <p>
-
-<li>Additional information and links of interest for Erlang programmers can be found on the Erlang Open Source site
-<a href="http://www.erlang.org/" target="_top">http://www.erlang.org</a>.
-<p>
-
-</ul>
-
-</body>
-</html>
diff --git a/system/doc/top/templates/flip_closed.gif b/system/doc/top/templates/flip_closed.gif
deleted file mode 100755
index 9a27c7c25d..0000000000
--- a/system/doc/top/templates/flip_closed.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/top/templates/flip_google.gif b/system/doc/top/templates/flip_google.gif
deleted file mode 100755
index 3f0543c2bb..0000000000
--- a/system/doc/top/templates/flip_google.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/top/templates/flip_open.gif b/system/doc/top/templates/flip_open.gif
deleted file mode 100755
index 9dda60e73a..0000000000
--- a/system/doc/top/templates/flip_open.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/top/templates/flip_static.gif b/system/doc/top/templates/flip_static.gif
deleted file mode 100755
index 2b3ddb5382..0000000000
--- a/system/doc/top/templates/flip_static.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/top/templates/flipmenu.js b/system/doc/top/templates/flipmenu.js
deleted file mode 100755
index 92a5a58a06..0000000000
--- a/system/doc/top/templates/flipmenu.js
+++ /dev/null
@@ -1,342 +0,0 @@
-// ######################################################################
-
-// ## flipMenu 5.0.0 (c) J. Reijers
-// ## Last modifications: 23 March 2007
-
-// ######################################################################
-
-// ## Degree of indentation from the left.
- flipIndentation = "5px";
-
-// ## Padding inbetween menu items.
- flipVerticalPadding = "4px";
-
-// ## Margin between the left of the browser and the menu.
- flipLeftMargin = "16px";
-
-// ## Margin between the top of the browser and the menu.
- flipTopMargin = "10px";
-
-// ## Allow multiple menus to fold out without closing all the other open ones.
- flipOpenMultipleMenus = false;
-
-// ## Preserve the current state of the menu (requires cookies).
- flipSaveMenuState = true;
-
-// ## Use custom images for bullets
- flipImages = true;
-
-// ## Images to use (specify full path)
- flipImg_open = "flip_open.gif";
- flipImg_closed = "flip_closed.gif";
- flipImg_static = "flip_static.gif";
-
-// ## Initialise all flipMenus onload
- flipInitOnLoad = true;
-
-// ## Message to display in status bar while loading
- flipLoadingMessage = "Loading...";
-
-// ######################################################################
-
-function alterSize(someSize, alterAmount) {
- someSize = String(someSize);
- var tmpNr = parseFloat(someSize.replace(/\D/g, ""));
- var tmpChar = someSize.replace(/\d/g, "");
- return isNaN(tmpNr) ? someSize : ((tmpNr + alterAmount) + tmpChar);
-}
-
-isIE = (String(navigator.appVersion).indexOf("MSIE") > -1);
-if (!isIE) flipIndentation = alterSize(flipIndentation, -16);
-if (!isIE) flipLeftMargin = alterSize(flipLeftMargin, -16);
-
-document.write(
- "<style type=\"text/css\">" +
-
- "ul.flipMenu { margin-top: " + flipTopMargin + "; margin-left: " + flipLeftMargin + "; " + (flipImages ? "" : "list-style-type: none;") + " }" +
- "ul.flipMenu ul, ul.flipMenu li { padding-top: " + flipVerticalPadding + "; margin-left: " + flipIndentation + "; margin-right: 0px; " + (flipImages ? "" : "list-style-type: none;") + " }" +
-
- "li.flipFolderOpen { cursor: pointer; " + (flipImages ? "list-style-image: url(" + flipImg_open + ");" : "") + " }" +
- "li.flipFolderClosed { cursor: pointer; " + (flipImages ? "list-style-image: url(" + flipImg_closed + ");" : "") + " }" +
-
- "</style>"
-);
-
-if (flipImages) {
- aFlipPreloads = [];
- aFlipPreloads[0] = new Image;
- aFlipPreloads[0].src = flipImg_open;
- aFlipPreloads[1] = new Image;
- aFlipPreloads[1].src = flipImg_closed;
- aFlipPreloads[2] = new Image;
- aFlipPreloads[2].src = flipImg_static;
-}
-
-function addEvent(someObj, someEvent, someFunction) {
- if (someObj.addEventListener) { someObj.addEventListener(someEvent, someFunction, true); return true; } else if (someObj.attachEvent) return someObj.attachEvent("on" + someEvent, someFunction); else return false;
-}
-
-function openCloseFlip(theItem, newSetting, openParents) {
- if (theItem.flipID) {
- if (openParents) {
- var tmpItem = theItem;
- while (tmpItem.parentElement || tmpItem.parentNode) {
- tmpItem = (tmpItem.parentElement) ? tmpItem.parentElement : tmpItem.parentNode;
- openCloseFlip(tmpItem, newSetting);
- }
- }
- if ((theItem.className == "flipFolderOpen" && newSetting == "closed") || (theItem.className == "flipFolderClosed" && newSetting == "open")) {
- if (!theItem.childrenInitialised) {
- for (var j = 0; j < theItem.childNodes.length; j++) if (theItem.childNodes[j].nodeName == "UL" && !theItem.childNodes[j].initialised) initFlip(theItem.childNodes[j]);
- theItem.childrenInitialised = true;
- }
- theItem.getElementsByTagName("UL")[0].style.display = (newSetting == "open") ? "" : "none";
- theItem.className = newSetting == "open" ? "flipFolderOpen" : "flipFolderClosed";
- }
- }
-}
-
-function openFlip(theItem, openParents) {
- openCloseFlip(theItem, "open", openParents);
-}
-
-function closeFlip(theItem, closeParents) {
- openCloseFlip(theItem, "closed", closeParents);
-}
-
-function toggleFlip(theElement) {
- if (theElement.flipID) {
- var theItem = theElement;
- var isContained = true;
- } else {
- if (theElement && theElement.button > 0) return false;
- var theItem = (isIE) ? event.srcElement : theElement.target;
-
- var isContained = false;
- if (theItem.className == "flipFolderOpen" || theItem.className == "flipFolderClosed") isContained = true; else while (theItem.parentElement || theItem.parentNode) {
- if (theItem.className == "flipStatic" || theItem.className == "flipFolderOpen" || theItem.className == "flipFolderClosed") {
- isContained = (theItem.className == "flipFolderOpen" || theItem.className == "flipFolderClosed");
- break;
- }
- theItem = (theItem.parentElement) ? theItem.parentElement : theItem.parentNode;
- }
- }
-
- var toOpenFlip = (isContained && theItem.className == "flipFolderClosed");
-
- if (!flipOpenMultipleMenus && (toOpenFlip || theItem.className == "flipStatic")) {
- if (theItem.parentElement || theItem.parentNode) {
- var parentUL = (theItem.parentElement) ? theItem.parentElement : theItem.parentNode;
- for (var i = 0; i < parentUL.childNodes.length; i++) closeFlip(parentUL.childNodes[i]);
- }
- }
-
- if (isContained) {
- if (toOpenFlip) openFlip(theItem); else closeFlip(theItem);
- }
-}
-
-function setAllFlips(startElement, newSetting) {
- if (typeof startElement == "undefined") var startElement = document;
- if (typeof newSetting == "undefined") var newSetting = "closed";
-
- var aUL = startElement.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var parentFlip = aUL[i].parentElement ? aUL[i].parentElement : aUL[i].parentNode;
- openCloseFlip(parentFlip, newSetting);
- }
-}
-
-function openAllFlips(startElement) {
- setAllFlips(startElement, "open");
-}
-
-function closeAllFlips(startElement) {
- setAllFlips(startElement, "closed");
-}
-
-function initFlip(startElement) {
- if (!document.createElement) return false;
-
- if (!startElement || !startElement.nodeName) {
- var aUL = document.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- if (flipLoadingMessage != "") window.status = flipLoadingMessage + " " + parseInt((i / (aUL.length - 1)) * 100, 10) + "%";
- var curUL = aUL[i];
- if (curUL.className == "flipMenu") {
- initFlip(curUL);
-
- // ## Fix text selecting problem in Mozilla
- curUL.onselectstart = new Function("return false");
- curUL.onmousedown = new Function("return false");
- curUL.onclick = new Function("return true");
- }
- }
-
- if (flipSaveMenuState) loadMenuState();
-
- if (flipLoadingMessage != "") window.status = "";
- return true;
- }
-
- if (startElement.className == "flipMenu") startElement.style.display = "";
-
- if (!startElement.childNodes || startElement.childNodes.length == 0) return false;
-
- if (typeof flipIDCur == "undefined") flipIDCur = 0;
- if (!startElement.initialised) {
- var aUL = startElement.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) aUL[i].style.display = "none";
- }
-
- for (var i = 0; i < startElement.childNodes.length; i++) {
- var curNode = startElement.childNodes[i];
- if (curNode.nodeName == "LI") {
- flipIDCur++;
- curNode.flipID = flipIDCur;
-
- var nodeHasChildren = curNode.getElementsByTagName("UL").length > 0;
- if (nodeHasChildren) {
- if (flipImages && curNode.flipClosed) curNode.style.listStyleImage = "url(" + curNode.flipClosed + ")";
-
- if (curNode.className == null || curNode.className == "") curNode.className = "flipFolderClosed";
- } else {
- curNode.className = "flipStatic";
- if (flipImages && !curNode.style.listStyleImage) {
- if (!curNode.flipStatic) curNode.flipStatic = flipImg_static;
- curNode.style.listStyleImage = "url(" + curNode.flipStatic + ")";
- }
- }
-
- if (!curNode.flipOpen) curNode.flipOpen = flipImg_open;
- if (!curNode.flipClosed) curNode.flipClosed = flipImg_closed;
-
- if (curNode.flipIsOpen) openFlip(curNode);
- }
- }
-
- startElement.initialised = true;
-}
-
-function rootOfFlip(flipID, startElement) {
-
- function containsFlip(startElement, flipID) {
- var flipFound = false;
- var i = 0;
- while (i < startElement.childNodes.length && !flipFound) {
- var curNode = startElement.childNodes[i];
- flipFound = (curNode.flipID == flipID) ? true : containsFlip(curNode, flipID);
- i++;
- }
- return flipFound;
- }
-
- var rootFlip = null;
-
- if (!startElement || !startElement.nodeName) {
- var aUL = document.getElementsByTagName("UL");
- var i = 0;
- while (rootFlip == null && i < aUL.length) {
- var curUL = aUL[i];
- if (curUL.nodeName == "UL" && curUL.className == "flipMenu") rootFlip = rootOfFlip(flipID, curUL);
- i++;
- }
- return rootFlip;
- }
-
- if (startElement.childNodes) for (var i = 0; i < startElement.childNodes.length; i++) {
- var curNode = startElement.childNodes[i];
- if (curNode.flipID == flipID || containsFlip(curNode, flipID)) rootFlip = curNode;
- }
-
- return rootFlip;
-}
-
-function getCookie(cookieName) {
- var allCookies = document.cookie;
- var indexStr = allCookies.indexOf(cookieName + "=");
- if (indexStr == -1) return "";
- indexStr = allCookies.indexOf("=", indexStr) + 1;
- var endStr = allCookies.indexOf(";", indexStr);
- if (endStr == -1) endStr = allCookies.length;
- return unescape(allCookies.substring(indexStr, endStr));
-}
-
-function inArray(someID, someArray) {
- for (var i = 0; i < someArray.length; i++) if (someArray[i] == someID) return true;
- return false;
-}
-
-function getMenuState(startElement) {
- if (!startElement.childNodes || startElement.childNodes.length == 0) return "";
-
- var openItems = "";
- var aUL = startElement.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var curNode = aUL[i];
- var parentFlip = (curNode.parentElement) ? curNode.parentElement : curNode.parentNode;
- if (curNode.style.display == "" && parentFlip.flipID) openItems += " " + parentFlip.flipID;
- }
- return openItems;
-}
-
-function putMenuState(startElement) {
- if (!startElement.childNodes || startElement.childNodes.length == 0) return false;
-
- var aUL = startElement.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var curNode = aUL[i];
- var parentFlip = (curNode.parentElement) ? curNode.parentElement : curNode.parentNode;
- if (inArray(parentFlip.flipID, aOpenItems)) {
- openFlip(parentFlip);
- if (typeof prevFlipRoot == "undefined") {
- var testRoot = rootOfFlip(parentFlip.flipID);
- if (testRoot.flipID == parentFlip.flipID) prevFlipRoot = testRoot;
- }
- }
- }
-}
-
-function saveMenuState() {
- if (flipSaveMenuState) {
- var aUL = document.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var curUL = aUL[i];
- var curID = curUL.id ? curUL.id : i;
- if (curUL.className == "flipMenu") document.cookie = cookiePrefix + curID + "=" + getMenuState(curUL) + ";";
- }
- }
-}
-
-function loadMenuState() {
- var aUL = document.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var curUL = aUL[i];
- var curID = curUL.id ? curUL.id : i;
- if (curUL.className == "flipMenu") {
- var savedState = String(getCookie(cookiePrefix + curID));
- if (savedState != "") {
- aOpenItems = savedState.split(" ");
- putMenuState(curUL);
- }
- }
- }
-
- addEvent(window, "unload", saveMenuState);
-}
-
-function clearMenuState(flipMenuID) {
- if (typeof flipMenuID == "undefined") {
- var aUL = document.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var curUL = aUL[i];
- var curID = curUL.id ? curUL.id : i;
- if (curUL.className == "flipMenu") document.cookie = cookiePrefix + curID + "=;";
- }
- } else document.cookie = cookiePrefix + flipMenuID + "=;";
-}
-
-cookiePrefix = document.location.pathname + "_";
-
-addEvent(document, "click", toggleFlip);
-if (flipInitOnLoad) addEvent(window, "load", initFlip);
diff --git a/system/doc/top/templates/index.html.src b/system/doc/top/templates/index.html.src
index 935bb11c80..257a656316 100644
--- a/system/doc/top/templates/index.html.src
+++ b/system/doc/top/templates/index.html.src
@@ -2,7 +2,7 @@
<!--
%CopyrightBegin%
-Copyright Ericsson AB 2001-2009. All Rights Reserved.
+Copyright Ericsson AB 2009-2010. All Rights Reserved.
The contents of this file are subject to the Erlang Public License,
Version 1.1, (the "License"); you may not use this file except in
@@ -169,7 +169,7 @@ Asked Questions</a>. <p>
<center>
<small>
-Copyright &copy; 1999-2009
+Copyright &copy; 1999-2010
<a href="http://www.ericsson.com">Ericsson AB</a>
</small>
</center>
diff --git a/system/doc/top/templates/otp_top.css b/system/doc/top/templates/otp_top.css
deleted file mode 100644
index 1c6d27bd8d..0000000000
--- a/system/doc/top/templates/otp_top.css
+++ /dev/null
@@ -1,53 +0,0 @@
- BODY { background: white }
-
- BODY { font-family: Verdana, Arial, Helvetica, sans-serif }
- TH { font-family: Verdana, Arial, Helvetica, sans-serif }
- TD { font-family: Verdana, Arial, Helvetica, sans-serif }
- P { font-family: Verdana, Arial, Helvetica, sans-serif }
-
- .header { background: #222; color: #fff }
- .top { background: #efe }
- .otp { background: #efe }
- .erlang { background: #ffe }
- .otp2 { background: #efe }
- .app { background: #ffe }
-
- a:link { color: blue; text-decoration: none }
- a:active { color: blue; text-decoration: none }
- a:visited { color: blue; text-decoration: none }
- body {
- margin: 0;
- padding: 0;
- border: 0;
- overflow: scroll;
- height: 100%;
- max-height: 100%
- }
- #container {
- width: 100%;
- margin: 10px auto;
- background-color: #fff;
- }
- #leftnav {
- float: left;
- width: 200px;
- margin: 0;
- padding: 1em;
- }
- #content {
- margin-left: 220px; /* set left value to WidthOfFrameDiv */
- border-left: 1px solid red;
- }
-
- .innertube {
- margin: 15px; /* Magins for inner DIV inside each DIV (to provide padding) */
- }
-
- * html body{ /* IE6 hack */
- padding: 0 0 0 200px; /* Set value to (0 0 0 WidthOfFrameDiv)*/
- }
- * html #maincontent{ /* IE6 hack*/
- height: 100%;
- width: 100%;
- }
-
diff --git a/system/doc/top/templates/system.html.src b/system/doc/top/templates/system.html.src
deleted file mode 100644
index 761bc96ed0..0000000000
--- a/system/doc/top/templates/system.html.src
+++ /dev/null
@@ -1,281 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
- <title>Erlang/OTP #release#</title>
- <style type="text/css">
-<!--
- BODY { background: white }
-
- BODY { font-family: Verdana, Arial, Helvetica, sans-serif }
- TH { font-family: Verdana, Arial, Helvetica, sans-serif }
- TD { font-family: Verdana, Arial, Helvetica, sans-serif }
- P { font-family: Verdana, Arial, Helvetica, sans-serif }
-
- .header { background: #222; color: #fff }
- .app { background: #ccc }
-
- a.anum:link { color: green; text-decoration: none }
- a.anum:active { color: green; text-decoration: none }
- a.anum:visited { color: green; text-decoration: none }
-
- a:link { text-decoration: none }
- a:active { text-decoration: none }
- a:visited { text-decoration: none }
--->
- </style>
-</head>
-
-<body bgcolor=white text="#000000" link="#0000ff" vlink="#ff00ff"
- alink="#ff0000">
-<center>
-<table border=0 width="90%" cellspacing=3 cellpadding=5>
-
- <tr>
- <td colspan=2 class=header>
- <font size="+1"><b>General</b></font>
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="system_architecture_intro/part_frame.html" target="_top"
- name=system_architecture_intro>
- Introduction
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-About Erlang, OTP, Erlang/OTP and this documentation
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="installation_guide/part_frame.html" target="_top"
- name=installation_guide>
- Installation Guide
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-The Erlang/OTP Installation Guide
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="system_principles/part_frame.html" target="_top"
- name=system_principles>
- System Principles
- </a>
- </td>
- <td align=right valign=top width=20>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Starting, stopping and configuring the Erlang runtime system
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="embedded/part_frame.html" target="_top" name=embedded>
- Embedded System
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Erlang in an Embedded System
- </td>
- </tr>
-
- <tr>
- <td colspan=2><font size=1>&nbsp;</font></td>
- </tr>
-
-<!-- ====================================================================== -->
-
- <tr>
- <td colspan=2 class=header>
- <font size="+1"><b>Programming in Erlang</b></font>
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="reference_manual/part_frame.html" target="_top" name=reference_manual>
- Erlang Reference Manual
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Description of data types, language constructs and more
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="getting_started/part_frame.html" target="_top" name=getting_started>
- Getting Started
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Getting started with Erlang
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="programming_examples/part_frame.html" target="_top" name=programming_examples>
- Programming Examples
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Examples of using records, funs, list comprehensions and the bit syntax
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="efficiency_guide/part_frame.html" target="_top" name=efficiency_guide>Efficiency Guide</a>
- </td>
- <td align=right valign=top width=20>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Learn how to write efficient programs in Erlang
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="tutorial/part_frame.html" target="_top" name=tutorial>Interoperability Tutorial</a>
- </td>
- <td align=right valign=top width=20>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-About interoperating with programs written in other programming languages
- </td>
- </tr>
-
- <tr>
- <td colspan=2><font size=1>&nbsp;</font></td>
- </tr>
-
-<!-- ====================================================================== -->
-
- <tr>
- <td colspan=2 class=header>
- <font size="+1"><b>Working with OTP</b></font>
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="design_principles/part_frame.html" target="_top"
- name=design_principles>
- Design Principles
- </a>
- </td>
- <td align=right valign=top width=20>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Structure your programs with applications, supervisors and generic behaviors (gen_server, gen_event and gen_fsm).
-Also use the built in error logger.
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="oam/part_frame.html" target="_top" name=oam>OAM Principles</a>
- </td>
- <td align=right valign=top width=20>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-OTP Operation and Management Principles
- </td>
- </tr>
-
- <tr>
- <td colspan=2><font size=1>&nbsp;</font></td>
- </tr>
-
-</table>
-
-</center>
-</body>
-</html>
-
-
diff --git a/system/doc/top/templates/toc_.html.src b/system/doc/top/templates/toc_.html.src
deleted file mode 100644
index 5e79bc0ac8..0000000000
--- a/system/doc/top/templates/toc_.html.src
+++ /dev/null
@@ -1,105 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
- <title>Erlang/OTP #release#</title>
- <style type="text/css">
-<!--
- BODY { background: white }
-
- BODY { font-family: Verdana, Arial, Helvetica, sans-serif }
- TH { font-family: Verdana, Arial, Helvetica, sans-serif }
- TD { font-family: Verdana, Arial, Helvetica, sans-serif }
- P { font-family: Verdana, Arial, Helvetica, sans-serif }
-
- .header { background: #222; color: #fff }
- .top { background: #efe }
- .otp { background: #efe }
- .erlang { background: #ffe }
- .otp2 { background: #efe }
- .app { background: #ffe }
-
- a:link { color: blue; text-decoration: none }
- a:active { color: blue; text-decoration: none }
- a:visited { color: blue; text-decoration: none }
--->
- </style>
-</head>
-
-<body bgcolor=white text="#000000" link="#0000ff" vlink="#ff00ff"
- alink="#ff0000">
-<center>
-<font size="+1"><b>Erlang/OTP #release#</b></font><br>
-</center>
-
-<div class=top>
-<small><a href="glossary.html" target=body>Glossary</a> |
-<a href="man_index.html" target=body>Modules</a> |
-<a href="permuted_index/pidxa.html" target=body>Index</a></small>
-<p>
-<small><a href="highlights.html" target=body>Release highlights</a><br>
-<a href="incompatible.html" target=body>Potential incompatibilities</a>
-</small>
-</div>
-
-<p>
-<div class=otp>
-Erlang/OTP
-<br>
-&middot;<small><a href="installation_guide/part_frame.html" target="_top"
- name=installation_guide>Installation Guide</a></small>
-
-<br>
-&middot;<small><a href="system_principles/part_frame.html" target="_top"
- name=system_principles>System Principles</a></small>
-
-<br>
-&middot;<small><a href="embedded/part_frame.html" target="_top" name=embedded>Embedded System</a></small>
-
-</div>
-
-<p>
-<div class=erlang>
-Erlang Programming
-<br>
-&middot;<small><a href="getting_started/part_frame.html" target="_top" name=getting_started>Getting
-Started</a></small>
-
-<br>
-&middot;<small><a href="reference_manual/part_frame.html" target="_top" name=reference_manual>Erlang
-Reference Manual</a></small>
-
-<br>
-&middot;<small><a href="programming_examples/part_frame.html" target="_top" name=programming_examples>Programming
-Examples</a></small>
-
-<br>
-&middot;<small><a href="efficiency_guide/part_frame.html" target="_top" name=efficiency_guide>Efficiency Guide</a></small>
-
-<br>
-&middot;<small><a href="tutorial/part_frame.html" target="_top" name=tutorial>Interoperability Tutorial</a></small>
-</div>
-
-<p>
-<div class=otp2>
-Working with OTP
-<br>
-&middot;<small><a href="design_principles/part_frame.html" target="_top"
- name=design_principles>Design Principles</a>
-</small>
-
-<br>
-&middot;<small><a href="oam/part_frame.html" target="_top" name=oam>OAM Principles</a></small>
-
-</div>
-
-<p>
-<div class=app>
-Applications
-<small>#applinks#</small>
-</div>
-
-<p>
-<a href="http://www.erlang.se/" target=body>http://www.erlang.se</a>
-
-</body>
-</html>